android - Is it possible to implement a FlowLayout with RelativeLayout properties? -


i create custom relativelayout has 2 views in 1 row: 1 on left side of screen (android:layout_alignparentstart="true") , 1 on right (android:layout_alignparentend="true"). view on right grow toward left view until takes space between 2 views. move new line under view on left.

i have implemented modified version of romain guy's flowlayout extends relativelayout. however, class seems ignore relativelayout's align properties , sticks views right next each other. there way implement such layout anchor views left , right?

flowlayout class:

public class flowlayout extends relativelayout {  private int mhorizontalspacing; private int mverticalspacing;  public flowlayout(context context) {     super(context); }  public flowlayout(context context, attributeset attrs) {     super(context, attrs);      typedarray attributes = context.obtainstyledattributes(attrs, r.styleable.flowlayout);     mhorizontalspacing = attributes.getdimensionpixelsize(r.styleable             .flowlayout_horizontalspacing, 0);     mverticalspacing = attributes.getdimensionpixelsize(r.styleable             .flowlayout_verticalspacing, 0);     attributes.recycle(); }  @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {     int widthsize = measurespec.getsize(widthmeasurespec);      int width = 0;     int height = getpaddingtop();      int currentwidth = getpaddingstart();     int currentheight = 0;      final int count = getchildcount();     (int = 0; < count; i++) {         view child = getchildat(i);         layoutparams lp = (layoutparams) child.getlayoutparams();         measurechild(child, widthmeasurespec, heightmeasurespec);          if (currentwidth + child.getmeasuredwidth() > widthsize) {             height += currentheight + mverticalspacing;             currentheight = 0;             width = math.max(width, currentwidth);             currentwidth = getpaddingend();         }          int spacing = mhorizontalspacing;         if (lp.spacing > -1) {             spacing = lp.spacing;         }          lp.x = currentwidth + spacing;         lp.y = currentheight;          currentwidth += child.getmeasuredwidth();         currentheight = math.max(currentheight, child.getmeasuredheight());     }      width += getpaddingend();     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();     (int = 0; < 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 checklayoutparams(viewgroup.layoutparams p) {     return p instanceof layoutparams; }  @override protected viewgroup.layoutparams generatedefaultlayoutparams() {     return new layoutparams(relativelayout.layoutparams.wrap_content, relativelayout             .layoutparams.wrap_content); }  @override protected viewgroup.layoutparams generatelayoutparams(viewgroup.layoutparams p) {     return new layoutparams(p.width, p.height); }  @override public relativelayout.layoutparams generatelayoutparams(attributeset attrs) {     return new layoutparams(getcontext(), attrs); }  public static class layoutparams extends relativelayout.layoutparams {      public int spacing;      public int x;     public int y;      public layoutparams(context context, attributeset attrs) {         super(context, attrs);          typedarray attributes = context.obtainstyledattributes(attrs, r.styleable                 .flowlayout_layoutparams);         spacing = attributes.getdimensionpixelsize(r.styleable                 .flowlayout_layoutparams_layoutspacing, -1);         attributes.recycle();     }      public layoutparams(int width, int height) {         super(width, height);     } }  } 

it turns out rather calculating right view's new position yourself, can change layoutparams , have os handle positioning you. created custom layout extends relativelayout , overrides onmeasure() method. adjust layoutparams accordingly.

more specifically: call super method find widths of 2 views , parent in onmeasure(). use these figure out if right view overlap left view. if so, change right view's layout_alignparentend="true" property layout_alignparentstart="true" , give layout_below="@id/left_view" property. opposite when there no overlap. call super method again have os remeasure views you.

the layout class:

public class wrappinglayout extends relativelayout {      private textview leftview;     private edittext rightview;     //use prevent unnecessarily adjusting layoutparams     //when right view in correct position     private boolean ismultiline = false;      public wrappinglayout(context context) {         super(context);         layoutinflater inflater = layoutinflater.from(context);         inflater.inflate(r.layout.wrapping_layout, this);          leftview = (textview) findviewbyid(r.id.left_view);         rightview = (edittext) findviewbyid(r.id.right_view);     }      public wrappinglayout(context context, attributeset attrs) {         super(context, attrs);         layoutinflater inflater = layoutinflater.from(context);         inflater.inflate(r.layout.wrapping_layout, this);          leftview = (textview) findviewbyid(r.id.left_view);         rightview = (edittext) findviewbyid(r.id.right_view);     }      @override     protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {         //call first make sure views' initial widths have been set         super.onmeasure(widthmeasurespec, heightmeasurespec);         int screenwidth = getmeasuredwidth();         int leftviewwidth = getpaddingstart() + leftview.getmeasuredwidth() + leftview.getpaddingend();         int rightviewwidth = getpaddingend() + rightview.getmeasuredwidth() + rightview.getpaddingstart();          layoutparams rightviewparams = (layoutparams) rightview.getlayoutparams();         if (!ismultiline && rightviewwidth + leftviewwidth > screenwidth) {             ismultiline = true;             rightviewparams.addrule(below, r.id.left_view);             rightviewparams.removerule(align_parent_end);             rightviewparams.addrule(align_parent_start);             //call again here adjust dimensions new params             super.onmeasure(widthmeasurespec, heightmeasurespec);         } else if (ismultiline && rightviewwidth + leftviewwidth < screenwidth) {             ismultiline = false;             rightviewparams.removerule(below);             rightviewparams.addrule(align_parent_end);             rightviewparams.removerule(align_parent_start);             //call again here adjust dimensions new params             super.onmeasure(widthmeasurespec, heightmeasurespec);         }     }  } 

the layout xml:

<?xml version="1.0" encoding="utf-8"?> <merge     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     android:layout_width="match_parent"     android:layout_height="match_parent">      <textview         android:id="@id/left_view"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignparentstart="true"         android:layout_centervertical="true"/>      <edittext         android:id="@id/right_view"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignparentend="true"         android:gravity="center"         android:text="@string/hello"/>  </merge> 

Comments

Popular posts from this blog

sql - VB.NET Operand type clash: date is incompatible with int error -

SVG stroke-linecap doesn't work for circles in Firefox? -

python - TypeError: Scalar value for argument 'color' is not numeric in openCV -