Подтвердить что ты не робот

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

Что я не так?

4b9b3361

Ответ 1

//вы забыли вызвать 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> 

Ответ 2

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

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

Ответ 3

Edit:

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

Исходный ответ:

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

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