Как заставить 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]()
Ответы
Ответ 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.