2014-09-14 10 views
6

Dans mon application, j'ai ajouté plusieurs vues à une disposition linéaire horizontale à partir du code. Mon problème est quand le nombre de vues augmente leur non visible dans une rangée et va plus loin à l'écran. Y at-il une mise en page que je peux ajouter des vues dynamiquement et si la vue suivante ne rentre pas dans la première rangée, elle est placée dans la deuxième rangée. Au début je ne connais pas le nombre de vues mais je veux que tout soit dynamique. quelque chose comme ceci: enter image description hereandroid LinearLayout avec plusieurs lignes

+0

Je ne pense pas que quelque chose comme ça existe, que je sache. Ne pouvez-vous pas simplement ajouter les largeurs des enfants et si elle est supérieure à la largeur du parent, créez un nouveau LinearLayout horizontal et ajoutez-les à cela à la place? –

+0

@billynomates Je veux savoir s'il existe une bibliothèque écrite à cet effet ou une façon plus simple de le faire. Vous savez obtenir la largeur des vues avant de les ajouter à un parent est difficile. –

+1

@MohamadGhafourian: plz jeter un oeil à ici espère que cela aide: https://stackoverflow.com/questions/549451/line-breaking-widget-layout-for-android/560958#560958 –

Répondre

2

utilisez cet

package com.shashi.app.utils; 

    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; 

    import com.shashi.app.R; 

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

utilisation xml

<com.shashi.app.utils.FlowLayout 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingLeft="15dp" 
      android:paddingRight="15dp" 
      app:horizontalSpacing="10dp" 
      app:verticalSpacing="10dp" > 
your views here 
</com.shashi.app.utils.FlowLayout>