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

Как заставить GridView генерировать квадратные ячейки в Android

Как я могу заставить андроид GridView генерировать квадратные ячейки (высота ячейки равна ширине ячейки) GridView имеет 10 * 9 ячеек, и приложение должно поддерживать несколько экранов!

Я использовал линейную компоновку:

row_grid.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="0dp" >

        <ImageView
            android:id="@+id/item_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:src="@drawable/ic_launcher" >
        </ImageView>

    </LinearLayout>

и GridView: activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/katy" >

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="0dp"
        android:numColumns="4"
        android:stretchMode="columnWidth"
        android:verticalSpacing="0dp" >
    </GridView>
</RelativeLayout>

Каждая ячейка GridView содержит изображение с одинаковой шириной и высотой. изображения больше, чем ячейки, и должны растягиваться, чтобы соответствовать ячейкам. enter image description here

4b9b3361

Ответ 1

Сначала вы захотите создать собственный класс View, который вы можете использовать вместо используемого LinearLayout по умолчанию. Затем вы хотите переопределить вызов View onMeasure и заставить его быть квадратным:

public class GridViewItem extends ImageView {

    public GridViewItem(Context context) {
        super(context);
    }

    public GridViewItem(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GridViewItem(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
    }
}

Затем вы можете изменить файл row_grid.xml на:

<path.to.item.GridViewItem xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/ic_launcher" >
</path.to.item.GridViewItem>

Просто не забудьте изменить "path.to.item" в пакет, в котором находится ваш класс GridViewItem.java.

Я также удалил родителя LinearLayout, поскольку он ничего не делал для вас.

Edit:

Также изменил scaleType от fitXY до centerCrop, чтобы ваше изображение не растягивалось и поддерживало его соотношение сторон. И, пока это квадратное изображение, ничто не должно быть обрезано, независимо.

Ответ 2

Вы можете переопределить линейный макет

public class MyLinearLayout extends LinearLayout {
    public MyLinearLayout(Context context) {
        super(context);
    }

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
    }
}

затем используйте его в item_grid.xml

<?xml version="1.0" encoding="utf-8"?>
<com.example.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/item_grid"

    android:layout_margin="2dp"
    android:padding="3dp"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Category Name"
        android:textStyle="bold"
        android:textColor="@color/colorPrimary"
        android:id="@+id/tvCategoryName" />


</com.example.MyLinearLayout>

Ответ 3

Хорошо работает, спасибо! Небольшое улучшение, которое я требовал, всегда будет выбирать меньшее значение, чтобы предотвратить превышение экрана:

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(heightMeasureSpec < widthMeasureSpec) {
        super.onMeasure(heightMeasureSpec, heightMeasureSpec);
    } else if(widthMeasureSpec < heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
    } else {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

Ответ 4

import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

public class GridViewItem extends RelativeLayout {

    public GridViewItem(Context context) {
        super(context);
    }

    public GridViewItem(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GridViewItem(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
    }
}

Если у вашего элемента сетки просто изображение, ответ answer очень хорош. Но вы хотите добавить несколько элементов в сетку, тогда вы должны создать свой пользовательский GridViewItem, расширяющий макет, которым вы хотите, чтобы ваш элемент сетки был. Например, в моем случае я использовал RelativeLayout в качестве родительского представления, поэтому я создал GridViewItem, расширяющий RelativeLayout, и он работал безупречно.

Ответ 5

Просто убедитесь, что ваши изображения квадратные. И сделайте контейнер wrap_content.