2010-12-17 10 views

Respuesta

83

Si ve la charla que di en el día de la Universidad Devoxx (disponible en parleys.com), aprenderá cómo hacerlo usted mismo. Durante la charla escribí una implementación de FlowLayout en vivo en el escenario para mostrar lo simple que es escribir diseños personalizados.

La implementación está alojada en here.

+0

Creo que esto puede ayudar a http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/ – Adham

+14

gracias chico romaní, eso realmente ayuda. ¿Qué hay de solo dar la solución? o un enlace? ... No entiendo cómo se respondió tu respuesta. –

+4

@JohannHilbold: Acabo de agregar los enlaces – Macarse

-3

No, no hay forma de que los widgets se envuelvan así hasta donde yo sé.

22

No tengo suficiente reputación para publicar un comentario a la respuesta de Romain Guy, pero ahí es donde debería estar (creo una cuenta solo para compartir mi edición).

De todos modos, veo que otras personas han descubierto que su solución CoolLayout, muy guay, tiene algunos problemas. Pude encontrar uno yo mismo y vi, como otros, que algunos niños fueron cortados. Mirando en detalle el algoritmo, parece ser un error muy simple en el cálculo de la altura. Cuando el último niño es el que se coloca en una nueva línea, entonces la altura no se calculó correctamente. Limpié un poco el cálculo (hubo un uso extraño de "altura" frente a la altura actual).

El siguiente cambio soluciona el problema del "último hijo si se recorta en una nueva línea":

@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

Esto es genial.Gracias por arreglar un problema obvio. –

+0

Gracias @Kevin. Me ayudaste mucho :) – Gaurav

0

Niza sencillo código FlowLayout auto-contenida aquí (sólo unos pocos archivos gist.github concisos) :

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

sin embargo, la actividad no fuera de la caja no funcionaba para mí para cargar el diseño personalizado.

yo encontramos este trabajo en torno [utilizando el parámetro 2-.inflate() llamar 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

Como una de las respuestas anteriores, que se inició con la solución aquí: http://hzqtc.github.io/2013/12/android-custom-layout-flowlayout.html

Lo extendí para tener en cuenta las diferentes alturas de los niños, como se muestra a continuación.

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; 
      } 
     } 
    } 
} 

Utilicé esto como una solución para envolver TextEdits multilínea. ¡Espero eso ayude!

+0

Muy útil en ciertos casos. [Aquí hay una revisión] (https://stackoverflow.com/a/45123806/4515489) que admite MarginLayoutParams. – jk7

+0

¡Buena solución! el margen solo funciona después de configurarlo dentro del método init pero no desde el diseño. –

2

Aquí está la clase personalizada en la que puede lograr el diseño como sigue con la adición dinámica de vista (también llamado 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; 
      } 
     } 
    } 
} 

Ejemplo:

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

Clase agradable, pero necesitaría algo de trabajo para soportar la dirección del diseño de derecha a izquierda. –

+0

Cómo hacer artículos en el centro. –

28

Debe utilizar FlexboxLayout con flexWrap="wrap" atributo.

<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> 

Por instrucciones de construcción, ver the github repo.

visual representation of FlexboxLayout Más información este - https://android-developers.googleblog.com/2017/02/build-flexible-layouts-with.html

+4

Es la última y hasta ahora la mejor solución. – Touhid

+3

¡Esto debe marcarse como la solución! La mejor respuesta para este problema hasta ahora – x10sion

2

Una revisión de @MattNotEquals() FlowLayout que soporta MarginLayoutParams.

Esto es solo una implementación minimalista de MarginLayoutParms para admitir los márgenes izquierdo, derecho, superior e inferior.

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

¡Estaba rascándome la cabeza de las últimas 2 horas y solo este código me funcionaba! ¿Puede proporcionar el diseño de flujo para RadioGroup? –

+0

Además, quiero saber cómo puedo usar el margen? margen = 10dp viene correctamente del diseño. –

+1

@Pratik, si tiene un RadioGroup pequeño y desea mostrar otras vistas junto a él si hay espacio y flujo a la siguiente línea si no hay espacio, FlowLayout debería funcionar bien. Un gran grupo de radio horizontal que hace que sus elementos de RadioButton fluyan a la siguiente línea cuando la primera línea está fuera de la sala requeriría escribir una clase de tipo RadioGroup personalizada dado que RadioGroup amplía LinearLayout. Podría escribir una clase RadioGroup personalizada utilizando las ideas de esta clase FlowLayout. Hasta ahora no he tenido necesidad de usar botones de radio. Usualmente usamos Spinners u otros controles. – jk7

Cuestiones relacionadas