Пользовательский квадрат LinearLayout. Как?

Я создаю свой собственный класс для квадратного макета:

public class SquareLayout extends LinearLayout{ public SquareLayout(Context context) { super(context); } public SquareLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SquareLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int size = width > height ? height : width; setMeasuredDimension(size, size); } 

Затем в моем xml:

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

В моем java-коде ничего больше не написано. Но вместо этого, если мой макет и мой образ, я вижу только белый прямоугольник …

Что я не так?

Solutions Collecting From Web of "Пользовательский квадрат LinearLayout. Как?"

// вы забыли вызвать super.onMeasure (widthMeasureSpec, widthMeasureSpec);

 @Override public 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-файл

 <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> 

У меня были проблемы с вызовом setMeasuredDimension непосредственно при применении той же методики к RelativeLayout. Я не смог правильно выровнять нижний край. Вместо этого super.onMeasure() на super.onMeasure() с новым показателем спекуляции.

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

Редактировать:

Нижеприведенное решение теперь устарело, поскольку ConstraintLayout стал новым стандартом и предоставляет эту функциональность.

Оригинальный ответ:

Оказывается, команда Android дала нам решение, но об этом никто не знает! Проверьте эти два класса в библиотеке поддержки процентов :

  • PercentFrameLayout
  • PercentRelativeLayout

Если вы хотите навязать соотношение вида, вы должны поместить его в один из этих макетов. Поэтому в этом случае вы должны поместить стандартный LinearLayout , а не ваш подкласс, в один из этих макетов с правильным соотношением сторон. Пример, если вы хотите использовать 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> 

И там вы идете, все ваши взгляды будут содержаться в квадратной линейной компоновке!

Не забудьте добавить компиляцию зависимостей gradle compile 'com.android.support:percent:23.3.0' Откорректируйте номер версии по мере необходимости