অ্যান্ড্রয়েড - মোড়ানো বাচ্চাদের সাথে লিনিয়ারলআউট অনুভূমিক


89

অ্যান্ড্রয়েডের লিনিয়ারলআউটের জন্য এমন কোনও সম্পত্তি সেট করা আছে যা এটি শিশু নিয়ন্ত্রণগুলি সঠিকভাবে মোড়ানো করতে সক্ষম করবে?

অর্থ - আমার পরিবর্তনযোগ্য সংখ্যক বাচ্চা রয়েছে এবং তাদের অনুভূমিকভাবে এগুলি ছড়িয়ে দিতে চাই:

উদাহরণ: নিয়ন্ত্রণ 1, নিয়ন্ত্রণ 2, নিয়ন্ত্রণ 3, ...

আমি সেট করে তা করি:

ll.setOrientation (লিনিয়ারলআউট.হরিজেন্টাল);
ভবিষ্যদ্বাণী (শিশুদের মধ্যে শিশু সি)
  ll.addView (সি);

তবে, আমার যদি প্রচুর পরিমাণে বাচ্চা থাকে, তবে পরের লাইনে না গিয়ে শেষেরটি কেটে যায়।

কোন ধারণা কীভাবে এটি স্থির করা যায়?



এই রেপো পরীক্ষা করে দেখুন। <br/> github.com/ranvijaySingh-Webonise/AdjustableLayout <br/> <br/> আপনি ভালো কিছু করতে চান। <br/> <br/> ! [নিয়মিত লেআউট উদাহরণ ] ( i.stack.imgur.com /68dHW.png )
রানা

উত্তর:


58

২০১ 2016 সালের মে পর্যন্ত গুগল FlexBoxLayoutএকটি নিজস্ব তৈরি করেছে যা আপনার সমস্যার সমাধান করা উচিত।

আপনি এখানে গিটহাব রেপোটি পেতে পারেন: https://github.com/google/flexbox-layout


7
@ ফ্র্যাক্টাল রাঞ্চ আপনি কীভাবে একটি উত্তরে জাভা গ্রন্থাগারের "প্রয়োজনীয় অংশগুলি" অন্তর্ভুক্ত করতে পারেন?
TWiStErRob

4
এটি সম্ভবত আজকাল প্রস্তাবিত পদ্ধতি এবং স্বীকৃত উত্তর হওয়া উচিত।
ম্যাগনাস ডব্লু

56

আপনি যা চান এটি হওয়া উচিত:

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 *
 * @author RAW
 */
public class FlowLayout extends ViewGroup {

    private int line_height;

    public static class LayoutParams extends ViewGroup.LayoutParams {

        public final int horizontal_spacing;
        public final int vertical_spacing;

        /**
         * @param horizontal_spacing Pixels between items, horizontally
         * @param vertical_spacing Pixels between items, vertically
         */
        public LayoutParams(int horizontal_spacing, int vertical_spacing) {
            super(0, 0);
            this.horizontal_spacing = horizontal_spacing;
            this.vertical_spacing = vertical_spacing;
        }
    }

    public FlowLayout(Context context) {
        super(context);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);

        final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
        int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
        final int count = getChildCount();
        int line_height = 0;

        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        int childHeightMeasureSpec;
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
        } else {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }


        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec);
                final int childw = child.getMeasuredWidth();
                line_height = Math.max(line_height, child.getMeasuredHeight() + lp.vertical_spacing);

                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }

                xpos += childw + lp.horizontal_spacing;
            }
        }
        this.line_height = line_height;

        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
            height = ypos + line_height;

        } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            if (ypos + line_height < height) {
                height = ypos + line_height;
            }
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(1, 1); // default of 1px spacing
    }

    @Override
    protected android.view.ViewGroup.LayoutParams generateLayoutParams(
        android.view.ViewGroup.LayoutParams p) {
        return new LayoutParams(1, 1, p);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        if (p instanceof LayoutParams) {
            return true;
        }
        return false;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        final int width = r - l;
        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final int childw = child.getMeasuredWidth();
                final int childh = child.getMeasuredHeight();
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }
                child.layout(xpos, ypos, xpos + childw, ypos + childh);
                xpos += childw + lp.horizontal_spacing;
            }
        }
    }
}

এবং এক্সএমএল ফাইল

/* you must write your package name and class name */
<org.android.FlowLayout
                android:id="@+id/flow_layout"
                android:layout_marginLeft="5dip"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"/>

4
গৃহীত কেপে 123 উত্তরের চেয়ে আরও ভাল এবং আরও মার্জিত কাজ করে।
মার্টিন কনেকনি

ভাল সমাধান কিন্তু খারাপ উত্তর। কেবল ব্যাখ্যা ছাড়াই লিঙ্কিংয়ের পরিবর্তে উত্তর অন্তর্ভুক্ত করুন।
আয়েয়ুন

4
দেখে মনে হচ্ছে, আপোভোটের কেউই এই কোডটি ব্যবহার করেনি। কারণ আপনি যদি এটি করেন, এটি একটি সঙ্গে বিরতি ClassCastException। এই ব্যতিক্রম হওয়ার কারণটি অন্য একটি স্ট্যাকওভারফ্লো প্রশ্ন, অসম্পূর্ণ অনুলিপি stackoverflow.com/q/549451/1741542 । আপনি যদি generateLayoutParams(ViewGroup.LayoutParams p)পদ্ধতি যুক্ত করেন তবে এটি প্রত্যাশার মতো কাজ করে।
ওলাফ ডিয়েটশে

9
কোনও নির্মাণকারীই new LayoutParams(1, 1, p)জানেন না, লোকেরা কেন কোড ব্যবহার না করেই
ফয়সাল নাসির

উত্তরের জন্য আপনাকে ধন্যবাদ, তবে আমি কীভাবে এটি ব্যবহার করতে পারি যদি আমি বাচ্চাদের ডান থেকে বামে মুড়ে রাখতে চাই?
TheTallWitch

42

যার জন্য এই ধরণের আচরণের প্রয়োজন:

private void populateLinks(LinearLayout ll, ArrayList<Sample> collection, String header) {

    Display display = getWindowManager().getDefaultDisplay();
    int maxWidth = display.getWidth() - 10;

    if (collection.size() > 0) {
        LinearLayout llAlso = new LinearLayout(this);
        llAlso.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT));
        llAlso.setOrientation(LinearLayout.HORIZONTAL);

        TextView txtSample = new TextView(this);
        txtSample.setText(header);

        llAlso.addView(txtSample);
        txtSample.measure(0, 0);

        int widthSoFar = txtSample.getMeasuredWidth();
        for (Sample samItem : collection) {
            TextView txtSamItem = new TextView(this, null,
                    android.R.attr.textColorLink);
            txtSamItem.setText(samItem.Sample);
            txtSamItem.setPadding(10, 0, 0, 0);
            txtSamItem.setTag(samItem);
            txtSamItem.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    TextView self = (TextView) v;
                    Sample ds = (Sample) self.getTag();

                    Intent myIntent = new Intent();
                    myIntent.putExtra("link_info", ds.Sample);
                    setResult("link_clicked", myIntent);
                    finish();
                }
            });

            txtSamItem.measure(0, 0);
            widthSoFar += txtSamItem.getMeasuredWidth();

            if (widthSoFar >= maxWidth) {
                ll.addView(llAlso);

                llAlso = new LinearLayout(this);
                llAlso.setLayoutParams(new LayoutParams(
                        LayoutParams.FILL_PARENT,
                        LayoutParams.WRAP_CONTENT));
                llAlso.setOrientation(LinearLayout.HORIZONTAL);

                llAlso.addView(txtSamItem);
                widthSoFar = txtSamItem.getMeasuredWidth();
            } else {
                llAlso.addView(txtSamItem);
            }
        }

        ll.addView(llAlso);
    }
}

বিন্যাস ফাইলগুলিতে এটি করার কোনও উপায়?
গুড্ডর

4
আরে আপনি বলতে পারেন এই "নমুনা samItem" কি
ShreeshaDas


1

অনুরূপ তবে সহজ সমস্যাটির সমাধানের সন্ধান করছেন, তা হ'ল অনুভূমিক বিন্যাসে শিশু পাঠ্য সামগ্রী মোড়ানো। kape123 এর সমাধান ভাল কাজ করে। ক্লিকযোগ্য স্প্যান ব্যবহার করে এই সমস্যার জন্য আরও সহজ একটি সন্ধান করুন। এটি কিছু সাধারণ ক্ষেত্রে কার্যকর হতে পারে। স্নিপেট:

        String[] stringSource = new String[sourceList.size()];
        for (int i = 0; c < sourceList.size(); i++) {
            String text = sourceList.get(i);
            stringSource[i] = text;
        }

        SpannableString totalContent = new SpannableString(TextUtils.join(",", stringSource));
        int start = 0;
        for (int j = 0; j < stringSource.length(); j++) {
            final String text = stringSource[j];
            ClickableSpan span = new ClickableSpan() {

        @Override
                public void updateDrawState(TextPaint ds) {
                    ds.setUnderlineText(true);
                    ds.setColor(getResources().getColor(R.color.green));
                }
                @Override
                public void onClick(View widget) {
                    // the text clicked
                }
            };
    int end = (start += text.length());
            totalContent.setSpan(span, start, end, 0);
            star = end + 1;
        }

        TextView wrapperView = (TextView) findViewById(horizontal_container_id);
        wrapperView.setMovementMethod(LinkMovementMethod.getInstance());

        wrapperView.setText(totalContent, BufferType.SPANNABLE);
    }

দুঃখিত তবে মনে হচ্ছে ওপিকে পাঠ্য নয়, ভিউ মোড়ানো দরকার।
সাইতো মিয়ার

1

র‌্যান্ডি সুগিয়ানো 'ইউকের উত্তর এবং শেষ পর্যন্ত আমি যা দিয়েছিলাম তা থেকে কোডের একটি পরিবর্তিত সংস্করণ :

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.View.MeasureSpec.*
import android.view.ViewGroup
import androidx.core.content.withStyledAttributes
import androidx.core.view.children
import *.*.*.R


class FlowLayout(context: Context, attributeSet: AttributeSet) : ViewGroup(context, attributeSet) {

    private var lineHeight: Int = 0

    private var horizontalSpacing = 0F
    private var verticalSpacing = 0F

    init {
        context.withStyledAttributes(attributeSet, R.styleable.FlowLayout) {
            horizontalSpacing = getDimension(R.styleable.FlowLayout_horizontalSpacing, 0F)
            verticalSpacing = getDimension(R.styleable.FlowLayout_verticalSpacing, 0F)
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        val width = getSize(widthMeasureSpec) - paddingLeft - paddingRight
        var height = getSize(heightMeasureSpec) - paddingTop - paddingBottom

        var xPosition = paddingLeft
        var yPosition = paddingTop

        val childHeightMeasureSpec = makeMeasureSpec(
            height, if (getMode(heightMeasureSpec) == AT_MOST) AT_MOST else UNSPECIFIED
        )

        children.forEach { child ->
            if (child.visibility != GONE) {
                val layoutParams = child.layoutParams as LayoutParamsWithSpacing
                child.measure(makeMeasureSpec(width, AT_MOST), childHeightMeasureSpec)
                val childWidth = child.measuredWidth
                lineHeight =
                        Math.max(lineHeight, child.measuredHeight + layoutParams.verticalSpacing)

                if (xPosition + childWidth > width) {
                    xPosition = paddingLeft
                    yPosition += lineHeight
                }

                xPosition += childWidth + layoutParams.horizontalSpacing
            }
        }

        if (getMode(heightMeasureSpec) == UNSPECIFIED ||
            getMode(heightMeasureSpec) == AT_MOST && yPosition + lineHeight < height
        ) {
            height = yPosition + lineHeight
        }

        setMeasuredDimension(width, height)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        val width = right - left
        var xPosition = paddingLeft
        var yPosition = paddingTop

        children.forEach { child ->
            if (child.visibility != View.GONE) {
                val layoutParams = child.layoutParams as LayoutParamsWithSpacing
                val childWidth = child.measuredWidth
                if (xPosition + childWidth > width) {
                    xPosition = paddingLeft
                    yPosition += lineHeight
                }
                child.layout(
                    xPosition, yPosition, xPosition + childWidth,
                    yPosition + child.measuredHeight
                )
                xPosition += layoutParams.horizontalSpacing
                xPosition += childWidth
            }
        }
    }

    override fun generateDefaultLayoutParams(): ViewGroup.LayoutParams =
        LayoutParamsWithSpacing(1, 1)

    override fun generateLayoutParams(layoutParams: LayoutParams) =
        LayoutParamsWithSpacing(horizontalSpacing.toInt(), verticalSpacing.toInt())

    override fun checkLayoutParams(layoutParams: LayoutParams) =
        layoutParams is LayoutParamsWithSpacing

    class LayoutParamsWithSpacing(val horizontalSpacing: Int, val verticalSpacing: Int) :
        ViewGroup.LayoutParams(0, 0)
}

স্টাইল / attrs.xML ফাইলটিতে:

<resources>
    <declare-styleable name="FlowLayout">
        <attr name="horizontalSpacing" format="dimension" />
        <attr name="verticalSpacing" format="dimension" />
    </declare-styleable>
</resources>

ব্যবহার:

<*.*.*.*.FlowLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:horizontalSpacing="8dp"
    app:verticalSpacing="8dp">

    <!-- ... -->

</*.*.*.*.FlowLayout>

0
//this method will add image view to liner grid and warp it if no space in new child LinearLayout grid 
private void addImageToLinyerLayout(LinearLayout ll , ImageView v)
{
    //set the padding and margin and weight 
    v.setPadding(5, 5, 5, 5);

    Display display = getWindowManager().getDefaultDisplay();
    int maxWidth = display.getWidth() - 10;
    int maxChildeNum = (int) ( maxWidth / (110)) ; 
    Toast.makeText(getBaseContext(), "c" + v.getWidth() ,
            Toast.LENGTH_LONG).show();
    //loop through all child of the LinearLayout
    for (int i = 0; i < ll.getChildCount(); i++) {
        View chidv = ll.getChildAt(i);
        Class c = chidv.getClass();
        if (c == LinearLayout.class) {
            //here we are in the child lay out check to add the imageView if there is space 
            //Available else we will add it to new linear layout 
            LinearLayout chidvL = (LinearLayout)chidv; 
            if(chidvL.getChildCount() < maxChildeNum)
            {
                chidvL.addView(v);
                return;
            }
        } else{
           continue;
        } 
    }

    //if you reached here this means there was no roam for adding view so we will 
    //add new linear layout 
    LinearLayout childLinyer = new LinearLayout(this);
    childLinyer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));

    childLinyer.setOrientation(LinearLayout.HORIZONTAL);
    ll.addView(childLinyer);
    childLinyer.addView(v);

}

উপরের পদ্ধতিটি এগ্রিডের মতো এবং আপনার বিন্যাসে ইমিগভিউ পাশাপাশি যুক্ত করবে

  <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" 
    android:id="@+id/imageslayout"
    ></LinearLayout>

আমি এই সমাধানটি পোস্ট করতে পারি এটি কারওর পক্ষে সহায়তা করতে পারে এবং কিছু সময় সাশ্রয় করতে পারে এবং আমি এটি আমার অ্যাপ্লিকেশনটিতে ব্যবহার করি


0

আমি ট্যাগভিউ ব্যবহার করে শেষ করেছি :

<com.cunoraz.tagview.TagView
        android:id="@+id/tag_group"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp" />




  TagView tagGroup = (TagView)findviewById(R.id.tag_view);
 //You can add one tag
 tagGroup.addTag(Tag tag);
 //You can add multiple tag via ArrayList
 tagGroup.addTags(ArrayList<Tag> tags);
 //Via string array
 addTags(String[] tags);


   //set click listener
      tagGroup.setOnTagClickListener(new OnTagClickListener() {
            @Override
            public void onTagClick(Tag tag, int position) {
            }
        });

   //set delete listener
            tagGroup.setOnTagDeleteListener(new OnTagDeleteListener() {
            @Override
            public void onTagDeleted(final TagView view, final Tag tag, final int position) {
            }
        });

এখানে চিত্র বর্ণনা লিখুন


এই এক রেফারেন্স জন্য ধন্যবাদ। এই প্রথম আমি একটি গিট লাইব্রেরি ডাউনলোড এবং ব্যবহার করেছি। এটির জন্য কিছুটা গবেষণা প্রয়োজন, তবে আমি কাজটি করেছি এবং এই ট্যাগভিউ দুর্দান্ত। ঠিক আমি খুঁজছেন ছিল কি!
জন ওয়ার্ড

বিটিডাব্লু, আপনি এলোমেলো রঙ অ্যাসাইনমেন্ট তৈরি করতে কোন বিধি ব্যবহার করেছেন। প্যাটার্নটি দেখতে এটি শক্ত।
জন ওয়ার্ড

আমি নমুনা অ্যাপ্লিকেশন থেকে একটি স্ক্রিনশট নিয়েছি। আপনি এই নির্দিষ্ট লাইনটি দেখতে পারবেন github.com/Cutta/TagView/blob/master/app/src/main/java/cuneyt/… যেখানে নতুন ট্যাগক্লাস তৈরি করা হয়েছে। ট্যাগগ্লাস কনস্ট্রাক্টরে একটি এলোমেলো রঙ পরে github.com/Cutta/TagView/blob/master/app/src/main/java/cuneyt/… নির্ধারিত হয় ।
আলবার্তো এম

নিজেই আউটপুটটি দেখতে দারুণ, তবে এটি কি বাচ্চাদের লাইনের মধ্যবর্তী স্থানে দাঁড় করানো সমর্থন করে?
কমলাকান্নান জে

আপনার বিকাশকারীকে জিজ্ঞাসা করা উচিত এবং / অথবা গিথুব এ একটি সমস্যা খোলা উচিত! আমি এটি নিজেই বিকাশ করি না
আলবার্তো এম

0

গুগল নিজস্ব সমাধান অফার করে: ক্লাস ফ্লোএলআউট

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.google.android.material.internal;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.core.view.MarginLayoutParamsCompat;
import androidx.core.view.ViewCompat;
import com.google.android.material.R.styleable;

@RestrictTo({Scope.LIBRARY_GROUP})
public class FlowLayout extends ViewGroup {
  private int lineSpacing;
  private int itemSpacing;
  private boolean singleLine;

  public FlowLayout(Context context) {
    this(context, (AttributeSet)null);
  }

  public FlowLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.singleLine = false;
    this.loadFromAttributes(context, attrs);
  }

  @TargetApi(21)
  public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    this.singleLine = false;
    this.loadFromAttributes(context, attrs);
  }

  private void loadFromAttributes(Context context, AttributeSet attrs) {
    TypedArray array = context.getTheme().obtainStyledAttributes(attrs, styleable.FlowLayout, 0, 0);
    this.lineSpacing = array.getDimensionPixelSize(styleable.FlowLayout_lineSpacing, 0);
    this.itemSpacing = array.getDimensionPixelSize(styleable.FlowLayout_itemSpacing, 0);
    array.recycle();
  }

  protected int getLineSpacing() {
    return this.lineSpacing;
  }

  protected void setLineSpacing(int lineSpacing) {
    this.lineSpacing = lineSpacing;
  }

  protected int getItemSpacing() {
    return this.itemSpacing;
  }

  protected void setItemSpacing(int itemSpacing) {
    this.itemSpacing = itemSpacing;
  }

  protected boolean isSingleLine() {
    return this.singleLine;
  }

  public void setSingleLine(boolean singleLine) {
    this.singleLine = singleLine;
  }

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int maxWidth = widthMode != -2147483648 && widthMode != 1073741824 ? 2147483647 : width;
    int childLeft = this.getPaddingLeft();
    int childTop = this.getPaddingTop();
    int childBottom = childTop;
    int maxChildRight = 0;
    int maxRight = maxWidth - this.getPaddingRight();

    int finalWidth;
    for(finalWidth = 0; finalWidth < this.getChildCount(); ++finalWidth) {
      View child = this.getChildAt(finalWidth);
      if (child.getVisibility() != 8) {
        this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
        LayoutParams lp = child.getLayoutParams();
        int leftMargin = 0;
        int rightMargin = 0;
        if (lp instanceof MarginLayoutParams) {
          MarginLayoutParams marginLp = (MarginLayoutParams)lp;
          leftMargin += marginLp.leftMargin;
          rightMargin += marginLp.rightMargin;
        }

        int childRight = childLeft + leftMargin + child.getMeasuredWidth();
        if (childRight > maxRight && !this.isSingleLine()) {
          childLeft = this.getPaddingLeft();
          childTop = childBottom + this.lineSpacing;
        }

        childRight = childLeft + leftMargin + child.getMeasuredWidth();
        childBottom = childTop + child.getMeasuredHeight();
        if (childRight > maxChildRight) {
          maxChildRight = childRight;
        }

        childLeft += leftMargin + rightMargin + child.getMeasuredWidth() + this.itemSpacing;
      }
    }

    finalWidth = getMeasuredDimension(width, widthMode, maxChildRight);
    int finalHeight = getMeasuredDimension(height, heightMode, childBottom);
    this.setMeasuredDimension(finalWidth, finalHeight);
  }

  private static int getMeasuredDimension(int size, int mode, int childrenEdge) {
    switch(mode) {
    case -2147483648:
      return Math.min(childrenEdge, size);
    case 1073741824:
      return size;
    default:
      return childrenEdge;
    }
  }

  protected void onLayout(boolean sizeChanged, int left, int top, int right, int bottom) {
    if (this.getChildCount() != 0) {
      boolean isRtl = ViewCompat.getLayoutDirection(this) == 1;
      int paddingStart = isRtl ? this.getPaddingRight() : this.getPaddingLeft();
      int paddingEnd = isRtl ? this.getPaddingLeft() : this.getPaddingRight();
      int childStart = paddingStart;
      int childTop = this.getPaddingTop();
      int childBottom = childTop;
      int maxChildEnd = right - left - paddingEnd;

      for(int i = 0; i < this.getChildCount(); ++i) {
        View child = this.getChildAt(i);
        if (child.getVisibility() != 8) {
          LayoutParams lp = child.getLayoutParams();
          int startMargin = 0;
          int endMargin = 0;
          if (lp instanceof MarginLayoutParams) {
            MarginLayoutParams marginLp = (MarginLayoutParams)lp;
            startMargin = MarginLayoutParamsCompat.getMarginStart(marginLp);
            endMargin = MarginLayoutParamsCompat.getMarginEnd(marginLp);
          }

          int childEnd = childStart + startMargin + child.getMeasuredWidth();
          if (!this.singleLine && childEnd > maxChildEnd) {
            childStart = paddingStart;
            childTop = childBottom + this.lineSpacing;
          }

          childEnd = childStart + startMargin + child.getMeasuredWidth();
          childBottom = childTop + child.getMeasuredHeight();
          if (isRtl) {
            child.layout(maxChildEnd - childEnd, childTop, maxChildEnd - childStart - startMargin, childBottom);
          } else {
            child.layout(childStart + startMargin, childTop, childEnd, childBottom);
          }

          childStart += startMargin + endMargin + child.getMeasuredWidth() + this.itemSpacing;
        }
      }

    }
  }
}

এই শ্রেণিটি উপরে বর্ণিত ক্লাস ফ্লোলআউটের সাথে ঠিক একইভাবে কাজ করে তবে আপনার প্রকল্পে আপনার কোনও নতুন ক্লাস যুক্ত করা উচিত নয় এবং ডিজাইনার কাস্টমের চেয়ে এই শ্রেণীর সাথে আরও ভাল কাজ করে


0

আমি একটি খুব সহজ সমাধান চেয়েছিলাম যা নমনীয় (যে কারণে আমি লিনিয়ারলআউটগুলি ব্যবহার করি)। এটিই আমি নিয়ে এসেছি।

https://github.com/ShalakoSnell/ মোড়ানো_লাইনার_ লেআউট

দ্রষ্টব্য: আমি পাঠ্যদর্শনগুলি ব্যবহার করে একটি উদাহরণ পদ্ধতি অন্তর্ভুক্ত করেছি (দেখুন টেক্সটভিউআরলিস্টেরফেক্সেক্সেল ()) এক্সএমএল কেবল আইডি এবং উল্লম্ব অভিযোজন সহ একটি প্যারেন্ট ভিউ লিনিয়ারলআউট, অন্য কিছুই প্রয়োজন নেই। ব্যবহারের জন্য: প্যারেন্ট ভিউ এবং প্রসঙ্গের সাথে লিনিয়ারলআউটগুলিতে মোড়ানো এমন দর্শনগুলির একটি অ্যারে পাস করুন। (ভিউএডাপ্টারআরলিস্ট দেখুন (অ্যারেলিস্ট টেক্সটভিউগুলি))

লিনিয়ারলাউটগুলির একটি অ্যারেতে প্রবেশ করাই যা এই পদ্ধতিকে এত নমনীয় করে তোলে, কারণ এটি আপনাকে বিভিন্ন দর্শন প্রকারের যোগ করতে দেয়। সুতরাং প্রথম লিনিয়ারলয়েটে আপনার পাঠ্য থাকতে পারে এবং দ্বিতীয়টিতে আপনার একটি চিত্র থাকতে পারে তৃতীয়টিতে একটি বোতাম এবং আরও কিছু ...

প্রতিকৃতি উদাহরণ ল্যান্ডস্কেপ উদাহরণ 50dp মার্জিনগুলি উল্লম্বরেখায় লাইনারলয়েআউট (দুঃখিত, আমি ছবিগুলি এখনও যোগ করতে পারি না ... লিঙ্কগুলি দেখুন।

মেইনএ্যাকটিভিটি.জভা

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new WrappingLinearLayout(
                viewAdapterArrayList(textViewArrayListForExample()), // <-- replace this with you own array of LinearLayouts
                (LinearLayout) findViewById(R.id.verticalLinearLayout),
                this);
    }

কার্যকলাপ_মাইন.এক্সএমএল

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/verticalLinearLayout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</LinearLayout>

র‌্যাপিংলাইনারলআউট.জভা

package com.example.wrapping_linear_layout;

import android.content.Context;
import android.widget.LinearLayout;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

public class WrappingLinearLayout {

    public WrappingLinearLayout(@NotNull final ArrayList<LinearLayout> views, @NotNull final LinearLayout verticalLinearLayout, @NotNull final Context context) {
        verticalLinearLayout.post(new Runnable() {
            @Override
            public void run() {
                execute(views, verticalLinearLayout, context);
            }
        });

    }

    private void execute(@NotNull ArrayList<LinearLayout> views, @NotNull final LinearLayout verticalLinearLayout, @NotNull final Context context) {

        ArrayList<LinearLayout> horizontalLinearLayouts = new ArrayList<>();
        LinearLayout horizontalLinearLayout = new LinearLayout(context);
        horizontalLinearLayouts.add(horizontalLinearLayout);
        int verticalLinearLayoutWidth = verticalLinearLayout.getMeasuredWidth()
                - (verticalLinearLayout.getPaddingLeft()
                        + verticalLinearLayout.getPaddingRight());

        int totalWidthOfViews = 0;

        for (LinearLayout view : views) {

            view.measure(0, 0);
            int currentViewWidth = view.getMeasuredWidth();
            if (totalWidthOfViews + view.getMeasuredWidth() > verticalLinearLayoutWidth) {
                horizontalLinearLayout = new LinearLayout(context);
                horizontalLinearLayouts.add(horizontalLinearLayout);
                totalWidthOfViews = 0;
            }

            totalWidthOfViews += currentViewWidth;

            horizontalLinearLayout.addView(view);
        }

        for (LinearLayout linearLayout : horizontalLinearLayouts) {
            verticalLinearLayout.addView(linearLayout);
        }
    }

}

উদাহরণস্বরূপ ব্যবহারের ক্ষেত্রে অতিরিক্ত কোড:

    private ArrayList<LinearLayout> viewAdapterArrayList(ArrayList<TextView> textViews) {
        ArrayList<LinearLayout> views = new ArrayList<>();
        for (TextView textView : textViews) {
            LinearLayout linearLayout = new LinearLayout(this);
            linearLayout.addView(textView);
            views.add(linearLayout);
        }
        return views;
    }

    private ArrayList<TextView> textViewArrayListForExample() {
        ArrayList<TextView> textViews = new ArrayList<>();
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
        for (int i = 0; i < 40; i++) {
            TextView textView = new TextView(this);
            textView.setText("View " + i + " |");
            if (i < 20) {
                if (i % 5 == 0) {
                    textView.setText("View longer view " + i + " |");
                } else if (i % 7 == 0) {
                    textView.setText("View different length view " + i + " |");
                } else if (i % 9 == 0) {
                    textView.setText("View very long view that is so long it's really long " + i + " |");
                }
            }
            textView.setMaxLines(1);
            textView.setBackground(new ColorDrawable(Color.BLUE));
            textView.setTextColor(Color.WHITE);
            textView.setLayoutParams(layoutParams);
            textView.setPadding(20, 2, 20, 2);
            layoutParams.setMargins(10, 2, 10, 2);
            textViews.add(textView);
        }
        return textViews;
    }
}

0

অতীতে অনেক কাস্টম সমাধান এবং লাইব্রেরি চেষ্টা করেছিল এবং প্রকৃতপক্ষে এই সমস্যার সমাধান করেছিল।

শুরু করে Constraint Layout 2.0এখন আমরা ব্যবহার করতে পারিFlow

ফ্লো হ'ল চেইনগুলি তৈরির জন্য একটি নতুন ভার্চুয়াল লেআউট যা পরের লাইনে বা এমনকি স্ক্রিনের অন্য কোনও বিভাগে মোড়াতে পারে যখন সেগুলি ঘরছাড়া হয়ে যায়। আপনি যখন একটি শৃঙ্খলে একাধিক আইটেম রাখছেন তখন এটি কার্যকর তবে আপনি রানটাইম কন্টেইনারটি কত বড় হবে তা নিশ্চিত নন। আপনার অ্যাপ্লিকেশনটিতে গতিবেগের স্ক্রিন প্রস্থের মতো গতিশীল আকারের উপর ভিত্তি করে আপনার বিন্যাসটি তৈরি করতে আপনি এটি ব্যবহার করতে পারেন।

এক্সএমএল দেখতে কেমন হবে তা এখানে:

<androidx.constraintlayout.helper.widget.Flow
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintTop_toTopOf="parent"
   app:flow_wrapMode="chain"
   app:constraint_referenced_ids="card1, card2, card3"
   />

নোটিশ app:constraint_referenced_idsএবং app:flow_wrapModeসম্পত্তি।

আমরা প্রথমটি ব্যবহার করে মতামতগুলি পাস করি এবং দ্বিতীয়টি কীভাবে তাদের মোড়ানো যায় তা আমরা বেছে নিই।

app:flow_wrapMode 3 টি ভিন্ন বিকল্প গ্রহণ করে:

কোনটি নয় :create a single chain, overflowing if the content doesn’t fit

চেইন :on overflow, create add another chain for the overflow elements

সারিবদ্ধ :similar to chain, but align rows into columns

আরও তথ্যের জন্য অ্যান্ড্রয়েড বিকাশকারীদের পোস্ট পরীক্ষা করুন

এবং অফিসিয়াল ডক্স

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.