android - Resizing rotated child view in custom ViewGroup subclass -


background

i have custom viewgroup subclass rotates , mirrors child view. purpose correctly display traditional mongolian text.

i put viewgroup, current project putting edittext in it. (i never successful in rotating , mirroring edittext directly. however, wrapping in custom view group work.)

problem

my problem when try resize viewgroup programmatically, child view not getting resized along it. edittext match size of parent viewgroup appears single view.

mcve

i made new project show problem. button increases width of viewgroup (shown in red). images show project start (with working fine) , 2 width increments. edittext white , not getting resized though width , height set match_parent

enter image description here

the full project code below.

mongolviewgroup.java (custom viewgroup rotates , mirrors content)

public class mongolviewgroup extends viewgroup {      private int angle = 90;     private final matrix rotatematrix = new matrix();     private final rect viewrectrotated = new rect();     private final rectf temprectf1 = new rectf();     private final rectf temprectf2 = new rectf();     private final float[] viewtouchpoint = new float[2];     private final float[] childtouchpoint = new float[2];     private boolean anglechanged = true;      public mongolviewgroup(context context) {         this(context, null);     }      public mongolviewgroup(context context, attributeset attrs) {         super(context, attrs);         setwillnotdraw(false);     }      public view getview() {         return getchildat(0);     }      @override     protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {         final view view = getview();         if (view != null) {             measurechild(view, heightmeasurespec, widthmeasurespec);             setmeasureddimension(resolvesize(view.getmeasuredheight(), widthmeasurespec),                     resolvesize(view.getmeasuredwidth(), heightmeasurespec));         } else {             super.onmeasure(widthmeasurespec, heightmeasurespec);         }     }      @override     protected void onlayout(boolean changed, int left, int top, int right, int bottom) {         if (anglechanged) {             final rectf layoutrect = temprectf1;             final rectf layoutrectrotated = temprectf2;             layoutrect.set(0, 0, right - left, bottom - top);             rotatematrix.setrotate(angle, layoutrect.centerx(), layoutrect.centery());             rotatematrix.postscale(-1, 1);             rotatematrix.maprect(layoutrectrotated, layoutrect);             layoutrectrotated.round(viewrectrotated);             anglechanged = false;         }         final view view = getview();         if (view != null) {             view.layout(viewrectrotated.left, viewrectrotated.top, viewrectrotated.right,                     viewrectrotated.bottom);         }     }       @override     protected void dispatchdraw(canvas canvas) {          canvas.save();         canvas.rotate(-angle, getwidth() / 2f, getheight() / 2f);         canvas.scale(-1, 1);         super.dispatchdraw(canvas);         canvas.restore();     }      @override     public viewparent invalidatechildinparent(int[] location, rect dirty) {         invalidate();         return super.invalidatechildinparent(location, dirty);     }      @override     public boolean dispatchtouchevent(motionevent event) {         viewtouchpoint[0] = event.getx();         viewtouchpoint[1] = event.gety();         rotatematrix.mappoints(childtouchpoint, viewtouchpoint);         event.setlocation(childtouchpoint[0], childtouchpoint[1]);         boolean result = super.dispatchtouchevent(event);         event.setlocation(viewtouchpoint[0], viewtouchpoint[1]);         return result;     }  } 

mainactivity.java

public class mainactivity extends appcompatactivity {      mongolviewgroup viewgroup;     edittext edittext;     int newwidth = 300;      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          viewgroup = (mongolviewgroup) findviewbyid(r.id.viewgroup);         edittext = (edittext) findviewbyid(r.id.edittext);     }      public void buttonclicked(view view) {          newwidth += 200;         viewgroup.layoutparams params = viewgroup.getlayoutparams();         params.width=newwidth;         viewgroup.setlayoutparams(params);     } } 

activity_main.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:id="@+id/activity_main"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingbottom="@dimen/activity_vertical_margin"     android:paddingleft="@dimen/activity_horizontal_margin"     android:paddingright="@dimen/activity_horizontal_margin"     android:paddingtop="@dimen/activity_vertical_margin"     tools:context="com.example.mongolviewgrouptest.mainactivity">      <com.example.mongolviewgrouptest.mongolviewgroup         android:id="@+id/viewgroup"         android:layout_width="100dp"         android:layout_height="200dp"         android:background="@color/coloraccent">          <edittext             android:id="@+id/edittext"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:textcolor="@android:color/black"             android:background="@android:color/white"/>      </com.example.mongolviewgrouptest.mongolviewgroup>      <button         android:text="button"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:id="@+id/button"         android:onclick="buttonclicked"         android:layout_alignparenttop="true"         android:layout_alignparentright="true"         android:layout_alignparentend="true"/>   </relativelayout> 

  • you're not recalculating viewrectrotated edittext when viewgroup's onlayout(...) method called again.
  • since anglechanged set false (and never changes) after viewgroups first layout, part calculates left, right, top , bottom values edittext skipped time after first time when viewgroup requestslayout (when change height or width).
  • as such, edittext still laid out same left,right,top , bottom values laid out with.

do away anglechanged , should work fine. so:

@override protected void onlayout(boolean changed, int left, int top, int right, int bottom) {     final rectf layoutrect = temprectf1;     final rectf layoutrectrotated = temprectf2;     layoutrect.set(0, 0, right - left, bottom - top);     rotatematrix.setrotate(angle, layoutrect.centerx(), layoutrect.centery());     rotatematrix.postscale(-1, 1);     rotatematrix.maprect(layoutrectrotated, layoutrect);     layoutrectrotated.round(viewrectrotated);     final view view = getview();     if (view != null) {         view.layout(viewrectrotated.left, viewrectrotated.top, viewrectrotated.right,                 viewrectrotated.bottom);     } } 

i've tested , works fine way.

if need anglechanged reason, make sure it's changed true inside viewgroup's onmeasure method viewrectrotated recalculated again. wouldn't recommend that.


Comments

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - jQuery UI Splitter/Resizable for unlimited amount of columns -

javascript - IE9 error '$'is not defined -