2010-12-17 119 views

回答

83

如果你看着我在Devoxx大學日的演講(可在parleys.com上找到),你將學會如何自己做。在演講期間,我在舞臺上寫了一個實現FlowLayout的實現,以展示編寫自定義佈局的簡單程度。

執行託管here

+0

我認爲這可能有助於http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/ – Adham 2010-12-17 21:51:33

+14

感謝羅曼傢伙,這真的有幫助。如果只是提供解決方案?或鏈接?...我沒有得到你如何回答被接受。 – 2012-08-02 14:52:03

+4

@JohannHilbold:我剛剛添加了鏈接 – Macarse 2012-10-31 14:54:07

-3

不,根據我所知,沒有辦法讓小部件這樣包裝。

22

我沒有足夠的知名度向羅曼蓋伊的回答發表評論,但這就是答案應該是的地方(我創建了一個帳戶只是爲了分享我的編輯)。

無論如何,我看到其他人已經發現他非常酷的FlowLayout解決方案有一些問題。 我可以自己找到一個,我和其他人一樣,看到有些孩子被剪斷。 查看算法的詳細信息,它似乎是計算高度時非常簡單的錯誤。當最後一個孩子被放在一條新線上時,身高並沒有被正確計算。 我清理了一下計算(有一個奇怪的使用「高度」與currentHeight)。

以下更改解決的,「如果一個新行最後一個孩子被剪裁」的問題:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    int widthLimit = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight(); 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 

    boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED; 

    int width = 0; 

    int currentWidth = getPaddingLeft(); 
    int currentHeight = getPaddingTop(); 

    int maxChildHeight = 0; 

    boolean breakLine = false; 
    boolean newLine = false; 
    int spacing = 0; 

    final int count = getChildCount(); 
    for (int i = 0; i < count; i++) 
    { 
     View child = getChildAt(i); 
     measureChild(child, widthMeasureSpec, heightMeasureSpec); 

     LayoutParams lp = (LayoutParams) child.getLayoutParams(); 
     spacing = mHorizontalSpacing; 

     if (lp.horizontalSpacing >= 0) 
     { 
      spacing = lp.horizontalSpacing; 
     } 

     if (growHeight && (breakLine || ((currentWidth + child.getMeasuredWidth()) > widthLimit))) 
     {    
      newLine = true; 
      currentHeight += maxChildHeight + mVerticalSpacing; 

      width = Math.max(width, currentWidth - spacing); 

      currentWidth = getPaddingLeft(); 
      maxChildHeight = 0; 
     } 
     else 
     { 
      newLine = false; 
     } 

     maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); 

     lp.x = currentWidth; 
     lp.y = currentHeight; 

     currentWidth += child.getMeasuredWidth() + spacing; 

     breakLine = lp.breakLine; 
    } 

    if (newLine == false) 
    { 
     width = Math.max(width, currentWidth - spacing); 
    } 

    width += getPaddingRight(); 
    int height = currentHeight + maxChildHeight + getPaddingBottom(); 

    setMeasuredDimension(resolveSize(width, widthMeasureSpec), 
      resolveSize(height, heightMeasureSpec)); 
} 
+1

這太好了。感謝您解決一個明顯的問題。 – 2014-04-30 03:12:33

+0

謝謝@凱文。你幫了我很多:) – Gaurav 2016-12-05 03:26:21

0

尼斯簡單自足的FlowLayout代碼在這裏(只是通過簡單的幾gist.github文件)

http://hzqtc.github.io/2013/12/android-custom-layout-flowlayout.html

然而,開箱即用的活性沒有工作對我來說,加載自定義佈局。

我發現[)使用2 PARAM .inflate(稱之爲from this example]此變通

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    // .. 

    setContentView(R.layout.main_res_layout_activity_main); 

    ViewGroup flowContainer = getFlowLayoutView(); 

    // .. 
} 

ViewGroup getFlowLayoutView() 
{ 
    LayoutInflater inflater = getLayoutInflater(); 

    ViewGroup flowLayout = 
     (ViewGroup) 
      inflater.inflate(
        R.layout.main_res_layout_activity_main, 
        (FlowLayout) findViewById(R.id.flow_container) 
      ); 

    return flowLayout; 
} 
4

像以前的答案之一,我開始與這裏的解決方案:http://hzqtc.github.io/2013/12/android-custom-layout-flowlayout.html

我將它擴展到了如下所示的兒童身高。

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

// Custom layout that wraps child views to a new line 
public class FlowLayout extends ViewGroup { 

    private int marginHorizontal; 
    private int marginVertical; 

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

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

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

    private void init() { // Specify the margins for the children 
     marginHorizontal = getResources().getDimensionPixelSize(R.dimen.activity_half_horizontal_margin); 
     marginVertical = getResources().getDimensionPixelSize(R.dimen.activity_half_vertical_margin); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int childLeft = getPaddingLeft(); 
     int childTop = getPaddingTop(); 
     int lowestBottom = 0; 
     int lineHeight = 0; 
     int myWidth = resolveSize(100, widthMeasureSpec); 
     int wantedHeight = 0; 

     for (int i = 0; i < getChildCount(); i++) { 
      final View child = getChildAt(i); 
      if (child.getVisibility() == View.GONE) { 
       continue; 
      } 

      child.measure(getChildMeasureSpec(widthMeasureSpec, 0, child.getLayoutParams().width), 
        getChildMeasureSpec(heightMeasureSpec, 0, child.getLayoutParams().height)); 
      int childWidth = child.getMeasuredWidth(); 
      int childHeight = child.getMeasuredHeight(); 
      lineHeight = Math.max(childHeight, lineHeight); 

      if (childWidth + childLeft + getPaddingRight() > myWidth) { // Wrap this line 
       childLeft = getPaddingLeft(); 
       childTop = marginVertical + lowestBottom; // Spaced below the previous lowest point 
       lineHeight = childHeight; 
      } 
      childLeft += childWidth + marginHorizontal; 

      if (childHeight + childTop > lowestBottom) { // New lowest point 
       lowestBottom = childHeight + childTop; 
      } 
     } 

     wantedHeight += childTop + lineHeight + getPaddingBottom(); 
     setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec)); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     int childLeft = getPaddingLeft(); 
     int childTop = getPaddingTop(); 
     int lowestBottom = 0; 
     int myWidth = right - left; 
     for (int i = 0; i < getChildCount(); i++) { 
      final View child = getChildAt(i); 
      if (child.getVisibility() == View.GONE) { 
       continue; 
      } 
      int childWidth = child.getMeasuredWidth(); 
      int childHeight = child.getMeasuredHeight(); 

      if (childWidth + childLeft + getPaddingRight() > myWidth) { // Wrap this line 
       childLeft = getPaddingLeft(); 
       childTop = marginVertical + lowestBottom; // Spaced below the previous lowest point 
      } 
      child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); 
      childLeft += childWidth + marginHorizontal; 

      if (childHeight + childTop > lowestBottom) { // New lowest point 
       lowestBottom = childHeight + childTop; 
      } 
     } 
    } 
} 

我用這個作爲包裝多行TextEdits的解決方案。希望能幫助到你!

+0

在某些情況下非常有用。 [這是修訂](https://stackoverflow.com/a/45123806/4515489),支持MarginLayoutParams。 – jk7 2017-07-16 00:07:05

+0

很好的解決方案!只有在初始化方法中設置margin後,margin才能工作,但不能從layout中設置。 – 2017-12-03 13:03:54

2

這裏是自定義類,您可以通過添加動態視圖(也稱爲FlowLayout)來實現如下佈局。

enter image description here

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

/* 
Created By Dhavalkumar Solanki 
* */ 
public class FlowLayout extends ViewGroup { 

    private int line_height_space; 

    public static class LayoutParams extends ViewGroup.LayoutParams { 

     public int horizontal_spacing; 
     public 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_space = 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_space = Math.max(line_height_space, child.getMeasuredHeight() + lp.vertical_spacing); 

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

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

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

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

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

    @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_space; 
       } 
       child.layout(xpos, ypos, xpos + childw, ypos + childh); 
       xpos += childw + lp.horizontal_spacing; 
      } 
     } 
    } 
} 

實施例:

text_view。XML

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tool="http://schemas.android.com/tools" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:padding="5dp"> 

    <TextView 
     android:id="@+id/tvText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textSize="19sp" 
     android:background="@drawable/unselected_tag" 
     android:textColor="@color/colorPrimary" 
     tool:text="Temp" /> 
</RelativeLayout> 

activity_flow_layou_demo.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 

    > 
    <ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 

       <TextView 
        android:id="@+id/tvTitleBusiness" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="Business Interest " 
        android:textColor="@color/colorPrimary" 
        android:textSize="25sp" /> 

       <com.example.tristateandroid2.radardemo.FlowLayout 
        android:id="@+id/flowBusiness" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"> 

       </com.example.tristateandroid2.radardemo.FlowLayout> 
      </LinearLayout> 

      <LinearLayout 
       android:layout_marginTop="@dimen/activity_horizontal_margin" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 

       <TextView 
        android:id="@+id/tvTitlePrivate" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="Private Interest " 
        android:textColor="@color/colorPrimary" 
        android:textSize="25sp" /> 

       <com.example.tristateandroid2.radardemo.FlowLayout 
        android:id="@+id/flowPrivate" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"> 

       </com.example.tristateandroid2.radardemo.FlowLayout> 
      </LinearLayout> 
     </LinearLayout> 
    </ScrollView> 
</RelativeLayout> 

FlowLayouDemo.java

import android.graphics.Color; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

import java.util.ArrayList; 

public class FlowLayouDemo extends AppCompatActivity { 
    private TextView tvTitleBusiness; 
    private FlowLayout flowBusiness; 
    private TextView tvTitlePrivate; 
    private FlowLayout flowPrivate; 
    private ArrayList<TagModel> arrayList; 

    private void findViews() { 
     tvTitleBusiness = (TextView) findViewById(R.id.tvTitleBusiness); 
     flowBusiness = (FlowLayout) findViewById(R.id.flowBusiness); 
     tvTitlePrivate = (TextView) findViewById(R.id.tvTitlePrivate); 
     flowPrivate = (FlowLayout) findViewById(R.id.flowPrivate); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_flow_layou_demo); 
     findViews(); 
     addLayouts(); 
    } 

    private void addLayouts() { 
     if (arrayList == null) { 
      arrayList = new ArrayList<>(); 
     } 
     flowBusiness.removeAllViews(); 
     flowPrivate.removeAllViews(); 
     for (int i = 0; i < 75; i++) { 

      final boolean[] selected = {false}; 
      View view = this.getLayoutInflater().inflate(R.layout.text_view, null); 
      final TextView textView = (TextView) view.findViewById(R.id.tvText); 
      if (i % 5 == 0) { 
       arrayList.add(new TagModel(i, false, "Business VIEW : " + i)); 
       textView.setText("Busi VIEW To IS : " + i); 
      } else { 
       arrayList.add(new TagModel(i, false, "TEXT IS : " + i)); 
       textView.setText("Busi IS : " + i); 
      } 
      textView.setBackgroundResource(R.drawable.unselected_tag); 
      textView.setTextColor(Color.parseColor("#3F51B5")); 
      textView.setTag(i); 
      if(i<=50){ 
       flowBusiness.addView(view); 
      }else { 
       textView.setText("Priv View : "+i); 
       flowPrivate.addView(view); 
      } 

      textView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        if (selected[0]) { 
         selected[0] = false; 
         textView.setBackgroundResource(R.drawable.unselected_tag); 
         textView.setTextColor(Color.parseColor("#3F51B5")); 
        } else { 
         selected[0] = true; 
         textView.setBackgroundResource(R.drawable.selected_tag); 
         textView.setTextColor(Color.parseColor("#FFFFFF")); 
        } 
       } 
      }); 

     } 
    } 
} 
+0

不錯的課程,但它需要一些工作來支持從右到左的佈局方向。 – 2016-12-07 12:07:46

+0

如何在中心製作物品。 – 2018-02-10 14:36:03

28

你應該使用FlexboxLayoutflexWrap="wrap"屬性。

<com.google.android.flexbox.FlexboxLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    app:flexWrap="wrap"> 

<!-- contents go here --> 

</com.google.android.flexbox.FlexboxLayout> 

對於構建說明,請參閱the github repo.

visual representation of FlexboxLayout 更多關於這 - https://android-developers.googleblog.com/2017/02/build-flexible-layouts-with.html

+4

這是最新的和迄今爲止最好的解決方案。 – Touhid 2017-05-03 13:59:26

+3

這應該被標記爲解決方案!目前爲止,這個問題的最佳答案 – x10sion 2017-08-02 06:56:56

2

的修訂,以@MattNotEquals()FlowLayout支持MarginLayoutParams。

這只是MarginLayoutParms的最低限度實現,用於支持左側,右側,頂部和底部邊距。

import android.content.Context; 
import android.support.annotation.NonNull; 
import android.support.annotation.Nullable; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 

/** 
* Original version courtesy of MattNotEquals() at http://stackoverflow.com/a/34169798/4515489 - 4/13/17. 
* 7/15/17 Revised to support MarginLayoutParams. 
*/ 
public class FlowLayout extends ViewGroup { 
    // Custom layout that wraps child views to a new line. 

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

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

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

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int childLeft = getPaddingLeft(); 
     int childTop = getPaddingTop(); 
     int lowestBottom = 0; 
     int lineHeight = 0; 
     int myWidth = resolveSize(100, widthMeasureSpec); 
     int wantedHeight = 0; 
     for (int i = 0; i < getChildCount(); i++) { 
      final View child = getChildAt(i); 
      if (child.getVisibility() == View.GONE) { 
       continue; 
      } 
      child.measure(getChildMeasureSpec(widthMeasureSpec, 0, child.getLayoutParams().width), 
          getChildMeasureSpec(heightMeasureSpec, 0, child.getLayoutParams().height)); 
      int childWidth = child.getMeasuredWidth(); 
      int childHeight = child.getMeasuredHeight(); 
      lineHeight = Math.max(childHeight, lineHeight); 

      final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 
      childLeft += lp.leftMargin; 
      childTop += lp.topMargin; 
      if (childLeft + childWidth + lp.rightMargin + getPaddingRight() > myWidth) { // Wrap this line 
       childLeft = getPaddingLeft() + lp.leftMargin; 
       childTop = lowestBottom + lp.topMargin; // Spaced below the previous lowest point 
       lineHeight = childHeight; 
      } 
      childLeft += childWidth + lp.rightMargin; 

      if (childTop + childHeight + lp.bottomMargin > lowestBottom) { // New lowest point 
       lowestBottom = childTop + childHeight + lp.bottomMargin; 
      } 
     } 
     wantedHeight += lowestBottom + getPaddingBottom(); // childTop + lineHeight + getPaddingBottom(); 
     setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec)); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     int childLeft = getPaddingLeft(); 
     int childTop = getPaddingTop(); 
     int lowestBottom = 0; 
     int myWidth = right - left; 
     for (int i = 0; i < getChildCount(); i++) { 
      final View child = getChildAt(i); 
      if (child.getVisibility() == View.GONE) { 
       continue; 
      } 
      int childWidth = child.getMeasuredWidth(); 
      int childHeight = child.getMeasuredHeight(); 

      final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 
      childLeft += lp.leftMargin; 
      childTop += lp.topMargin; 
      if (childLeft + childWidth + lp.rightMargin + getPaddingRight() > myWidth) { // Wrap this line 
       childLeft = getPaddingLeft() + lp.leftMargin; 
       childTop = lowestBottom + lp.topMargin; // Spaced below the previous lowest point 
      } 
      child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); 
      childLeft += childWidth + lp.rightMargin; 

      if (childTop + childHeight + lp.bottomMargin > lowestBottom) { // New lowest point 
       lowestBottom = childTop + childHeight + lp.bottomMargin; 
      } 
     } 
    } 

    @Override 
    public boolean shouldDelayChildPressedState() { 
     return false; 
    } 

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

    @Override 
    protected LayoutParams generateDefaultLayoutParams() { 
     return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
    } 

    @Override 
    public LayoutParams generateLayoutParams(AttributeSet attrs) { 
     return new FlowLayout.LayoutParams(getContext(), attrs); 
    } 

    @Override 
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { 
     if (lp instanceof LayoutParams) { 
      return new LayoutParams((LayoutParams) lp); 
     } 
     else if (lp instanceof MarginLayoutParams) { 
      return new LayoutParams((MarginLayoutParams) lp); 
     } 
     else 
      return super.generateLayoutParams(lp); 
    } 

    /** 
    * Per-child layout information for layouts that support margins. 
    */ 
    public static class LayoutParams extends MarginLayoutParams { 
     public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) { 
      super(c, attrs); 
     } 
     public LayoutParams(int width, int height) { 
      super(width, height); 
     } 
     public LayoutParams(@NonNull ViewGroup.LayoutParams source) { 
      super(source); 
     } 
     public LayoutParams(@NonNull ViewGroup.MarginLayoutParams source) { 
      super(source); 
     } 
     public LayoutParams(@NonNull LayoutParams source) { 
      super(source); 
     } 
    } 
} 
+0

我從最近2個小時就開始搔癢,只有這段代碼對我有用!你能爲RadioGroup提供流程佈局嗎? – 2017-12-03 12:35:40

+0

另外,我想知道如何使用保證金?保證金= 10dp從版面正確地進入。 – 2017-12-03 12:57:45

+1

@Pratik,如果你有一個小的RadioGroup,並且如果有空間並且如果沒有空間時流到下一行,你想要在旁邊顯示其他視圖,FlowLayout應該可以正常工作。當第一行超出房間時,導致RadioButton項目流向下一行的大型水平RadioGroup需要自定義RadioGroup類型的類,因爲RadioGroup擴展了LinearLayout。您可以使用此FlowLayout類的想法編寫自定義RadioGroup類。到目前爲止,我還沒有必要使用單選按鈕。我們通常使用Spinners或其他控件。 – jk7 2017-12-05 03:38:57