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