Android 强制查看组';s的子项如果超过设备宽度,则移动到下一行

Android 强制查看组';s的子项如果超过设备宽度,则移动到下一行,android,viewgroup,device-width,Android,Viewgroup,Device Width,我想有一个视图组,它可能有一些视图,这些视图水平放置在一起。我的代码的问题是,一切都很好,但当子项计数越来越大时,所有子项水平放置在一起并超过设备宽度。如果它们超过设备宽度,我需要强制它们移动到下一行 这是我的代码: <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="92dp" android:layo

我想有一个视图组,它可能有一些视图,这些视图水平放置在一起。我的代码的问题是,一切都很好,但当子项计数越来越大时,所有子项水平放置在一起并超过设备宽度。如果它们超过设备宽度,我需要强制它们移动到下一行

这是我的代码:

<LinearLayout
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="92dp"
    android:layout_marginTop="?attr/actionBarSize"
    android:background="@color/divider"
    android:padding="6dp">

    <LinearLayout
        android:id="@+id/linear_layout_container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal"></LinearLayout>

    <ImageButton
        android:id="@+id/image_button_add_item"
        android:layout_width="78dp"
        android:layout_height="match_parent"
        android:background="@color/secondary_text"
        android:contentDescription="@string/content_description_add_new_file"
        android:src="@drawable/ic_plus"/>

</LinearLayout>


注意:线性布局容器
视图组包含所有视图,所有视图都是
线性布局视图组的子视图。

为了将它们移动到下一行,您必须进行一些测量,但如果您想要一个简单的解决方案:

  • 您只需将它们
    匹配即可
  • 或者给它们一个固定的宽度大小,并使用权重(您确实需要使用为
    MATCH\u PARRENT
    和水平布局设置的线性布局来包装它们)
  • 或者你可以玩2015年8月推出的新款

    • 默认情况下,线性布局就是这样工作的。出于您的目的,您需要一个FlowLayout

      罗曼盖伊的流动布局

      import android.content.Context;
      import android.content.res.TypedArray;
      import android.graphics.Canvas;
      import android.graphics.Paint;
      import android.util.AttributeSet;
      import android.view.View;
      import android.view.ViewGroup;
      
      public class FlowLayout extends ViewGroup {
              private int mHorizontalSpacing;
              private int mVerticalSpacing;
              private Paint mPaint;
      
              public FlowLayout(Context context, AttributeSet attrs) {
                      super(context, attrs);
      
                      TypedArray a = context.obtainStyledAttributes(attrs,
                                      R.styleable.FlowLayout);
                      try {
                              mHorizontalSpacing = a.getDimensionPixelSize(
                                              R.styleable.FlowLayout_horizontalSpacing, 0);
                              mVerticalSpacing = a.getDimensionPixelSize(
                                              R.styleable.FlowLayout_verticalSpacing, 0);
                      } finally {
                              a.recycle();
                      }
      
                      mPaint = new Paint();
                      mPaint.setAntiAlias(true);
                      mPaint.setColor(0xffff0000);
                      mPaint.setStrokeWidth(2.0f);
              }
      
              @Override
              protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                      int widthSize = MeasureSpec.getSize(widthMeasureSpec)
                                      - getPaddingRight();
                      int widthMode = MeasureSpec.getMode(widthMeasureSpec);
      
                      boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;
      
                      int width = 0;
                      int height = getPaddingTop();
      
                      int currentWidth = getPaddingLeft();
                      int currentHeight = 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() > widthSize)) {
                                      height += currentHeight + mVerticalSpacing;
                                      currentHeight = 0;
                                      width = Math.max(width, currentWidth - spacing);
                                      currentWidth = getPaddingLeft();
                                      newLine = true;
                              } else {
                                      newLine = false;
                              }
      
                              lp.x = currentWidth;
                              lp.y = height;
      
                              currentWidth += child.getMeasuredWidth() + spacing;
                              currentHeight = Math.max(currentHeight, child.getMeasuredHeight());
      
                              breakLine = lp.breakLine;
                      }
      
                      if (!newLine) {
                              height += currentHeight;
                              width = Math.max(width, currentWidth - spacing);
                      }
      
                      width += getPaddingRight();
                      height += getPaddingBottom();
      
                      setMeasuredDimension(resolveSize(width, widthMeasureSpec),
                                      resolveSize(height, heightMeasureSpec));
              }
      
              @Override
              protected void onLayout(boolean changed, int l, int t, int r, int b) {
                      final int count = getChildCount();
                      for (int i = 0; i < count; i++) {
                              View child = getChildAt(i);
                              LayoutParams lp = (LayoutParams) child.getLayoutParams();
                              child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y
                                              + child.getMeasuredHeight());
                      }
              }
      
              @Override
              protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
                      boolean more = super.drawChild(canvas, child, drawingTime);
                      LayoutParams lp = (LayoutParams) child.getLayoutParams();
                      if (lp.horizontalSpacing > 0) {
                              float x = child.getRight();
                              float y = child.getTop() + child.getHeight() / 2.0f;
                              canvas.drawLine(x, y - 4.0f, x, y + 4.0f, mPaint);
                              canvas.drawLine(x, y, x + lp.horizontalSpacing, y, mPaint);
                              canvas.drawLine(x + lp.horizontalSpacing, y - 4.0f, x
                                              + lp.horizontalSpacing, y + 4.0f, mPaint);
                      }
                      if (lp.breakLine) {
                              float x = child.getRight();
                              float y = child.getTop() + child.getHeight() / 2.0f;
                              canvas.drawLine(x, y, x, y + 6.0f, mPaint);
                              canvas.drawLine(x, y + 6.0f, x + 6.0f, y + 6.0f, mPaint);
                      }
                      return more;
              }
      
              @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 LayoutParams(getContext(), attrs);
              }
      
              @Override
              protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
                      return new LayoutParams(p.width, p.height);
              }
      
              public static class LayoutParams extends ViewGroup.LayoutParams {
                      int x;
                      int y;
      
                      public int horizontalSpacing;
                      public boolean breakLine;
      
                      public LayoutParams(Context context, AttributeSet attrs) {
                              super(context, attrs);
                              TypedArray a = context.obtainStyledAttributes(attrs,
                                              R.styleable.FlowLayout_LayoutParams);
                              try {
                                      horizontalSpacing = a
                                                      .getDimensionPixelSize(
                                                                      R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing,
                                                                      -1);
                                      breakLine = a.getBoolean(
                                                      R.styleable.FlowLayout_LayoutParams_layout_breakLine,
                                                      false);
                              } finally {
                                      a.recycle();
                              }
                      }
      
                      public LayoutParams(int w, int h) {
                              super(w, h);
                      }
              }
      
      }
      
      导入android.content.Context;
      导入android.content.res.TypedArray;
      导入android.graphics.Canvas;
      导入android.graphics.Paint;
      导入android.util.AttributeSet;
      导入android.view.view;
      导入android.view.ViewGroup;
      公共类FlowLayout扩展了ViewGroup{
      私人国际水平间距;
      私有整数垂直间距;
      私人油漆;
      公共流布局(上下文、属性集属性){
      超级(上下文,attrs);
      TypedArray a=上下文。获取样式属性(属性,
      R.styleable.FlowLayout);
      试一试{
      mHorizontalSpacing=a.getDimensionPixelSize(
      R.styleable.FlowLayout_水平间距,0);
      mVerticalSpacing=a.getDimensionPixelSize(
      R.styleable.FlowLayout_垂直间距,0);
      }最后{
      a、 回收();
      }
      mPaint=新油漆();
      mPaint.setAntiAlias(true);
      mPaint.setColor(0xffff0000);
      mPaint.设定行程宽度(2.0f);
      }
      @凌驾
      测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
      int widthSize=MeasureSpec.getSize(widthMeasureSpec)
      -getPaddingRight();
      int widthMode=MeasureSpec.getMode(widthmasurespec);
      布尔增长高度=宽度模式!=MeasureSpec.UNSPECIFIED;
      整数宽度=0;
      int height=getPaddingTop();
      int currentWidth=getPaddingLeft();
      int currentHeight=0;
      布尔特征线=假;
      布尔换行=假;
      整数间距=0;
      最终整数计数=getChildCount();
      for(int i=0;i=0){
      间距=lp.水平间距;
      }
      如果(生长高度)
      &&(特征线| | currentWidth+child.getMeasuredWidth()>widthSize)){
      高度+=当前高度+垂直间距;
      当前高度=0;
      宽度=数学最大值(宽度,当前宽度-间距);
      currentWidth=getPaddingLeft();
      换行符=真;
      }否则{
      换行符=假;
      }
      lp.x=电流宽度;
      lp.y=高度;
      currentWidth+=child.getMeasuredWidth()+间距;
      currentHeight=Math.max(currentHeight,child.getMeasuredHeight());
      特征线=lp.特征线;
      }
      如果(!换行){
      高度+=当前高度;
      宽度=数学最大值(宽度,当前宽度-间距);
      }
      宽度+=getPaddingRight();
      高度+=getPaddingBottom();
      设置测量尺寸(resolveSize(宽度、宽度测量等级),
      分辨率尺寸(高度、高度测量值);
      }
      @凌驾
      仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
      最终整数计数=getChildCount();
      for(int i=0;i0){
      float x=child.getRight();
      float y=child.getTop()+child.getHeight()/2.0f;
      帆布抽绳(x,y-4.0f,x,y+4.0f,mPaint);
      帆布.抽绳(x,y,x+lp.horizontalSpacin