Custom Square LinearLayout. How? Custom Square LinearLayout. How? xml xml

Custom Square LinearLayout. How?


// you forget to call super.onMeasure(widthMeasureSpec, widthMeasureSpec);

@Overridepublic void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, widthMeasureSpec);    int width = MeasureSpec.getSize(widthMeasureSpec);    int height = MeasureSpec.getSize(heightMeasureSpec);    int size = width > height ? height : width;    setMeasuredDimension(size, size);}

// xml file

<com.example.testapplication.SquareLayout    android:id="@+id/layout"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:layout_gravity="center_horizontal"    android:orientation="horizontal" >    <ImageView        android:id="@+id/cellImageView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="2dp"        android:adjustViewBounds="true"        android:padding="2dp"        android:scaleType="centerCrop"        android:src="@drawable/ic_launcher" />  </com.example.testapplication.SquareLayout> 


I had problems calling setMeasuredDimension directly when applying the same technique to a RelativeLayout. I was unable to correctly align against the bottom edge. Changing to instead call up to super.onMeasure() with a new measure spec worked better.

  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    int width = MeasureSpec.getSize(widthMeasureSpec);    int height = MeasureSpec.getSize(heightMeasureSpec);    int size = Math.min(width, height);    super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY),        MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));  }


Edit:

The solution below has now been deprecated, as ConstraintLayout has become the new standard and provides this functionality.

Original Answer:

Turns out the Android team gave us the solution, but nobody knows about it! Check out these two classes from the Percent Support Library:

If you want to impose the ratio of a view, you have to place it within one of these layouts. So in this case, you have to place a standard LinearLayout, not your subclass, within one of these layouts with the right aspect ratio. Example if you want to use a PercentFrameLayout:

<android.support.percent.PercentFrameLayout         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">     <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         app:layout_aspectRatio="100%">         <!-- Whatever subviews you want here -->     </LinearLayout> </android.support.percent.PercentFrameLayout>

And there you go, all your views will be contained within a square linear layout!

don't forget to add the gradle dependency compile 'com.android.support:percent:23.3.0' Adjust the version number as required