Как сделать элемент сетки RecyclerView равным по высоте и ширине?

Я определяю свой RecyclerView как сетку, задав свой макет с помощью GridLayoutManger который имеет счетчик интервалов 3, которые уже работают нормально. Я также добавляю декоратор предметов к моему просмотру recycler, который будет управлять интервалом между элементами сетки, это также отлично работает.

 public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; private boolean includeEdge; public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { this.spanCount = spanCount; this.spacing = spacing; this.includeEdge = includeEdge; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); // item position int column = position % spanCount; // item column if (includeEdge) { outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing) outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing) if (position < spanCount) { // top edge outRect.top = spacing; } outRect.bottom = spacing; // item bottom } else { outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing) outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing) if (position >= spanCount) { outRect.top = spacing; // item top } } } } 

Моя реализация для добавления украшения элемента в мой вид ресайклера:

 mBuddiesGrid = (RecyclerView) findViewById(R.id.buddies_grid); mLayoutManager = new GridLayoutManager(getApplicationContext(), 3); mBuddiesGrid.addItemDecoration(new GridSpacingItemDecoration(3, (int) dpToPx(10) , true)); mBuddiesAdapter = new BuddiesGridAdapter(getApplicationContext(), new Buddies()); mBuddiesGrid.setLayoutManager(mLayoutManager); 

Моя таблица элементов xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:layout_weight="1" android:cropToPadding="false" android:id="@+id/profile_picture" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:text="Theodore" android:includeFontPadding="false" android:textColor="@android:color/black" android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 

Добавляя пробелы между элементами сетки, вы будете корректировать ширину элемента сетки, что может привести к тому, что вы не получите размер пропорции моего представления элемента. То, что я хочу получить, – это изменить размер высоты элемента сетки, равный его ширине, динамически. Как мне это сделать?

Одним из способов обеспечения равной ширины / высоты является использование настраиваемого представления, которое вычисляет высоту, основанную на ее ширине, когда onMeasure() . Оптимальная вещь заключается в том, что кроме создания пользовательского представления нет кодирования.

Вот пользовательский вид, расширяющий LinearLayout :

 public class SquareLayout extends LinearLayout { public SquareLayout(Context context) { super(context); } public SquareLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SquareLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int width, int height) { // note we are applying the width value as the height super.onMeasure(width, width); } } 

Ниже приведена измененная версия макета элемента сетки, используя вышеупомянутый пользовательский LinearLayout :

 <com.yourpackage.name.views.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/profile_picture" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:cropToPadding="false" android:scaleType="centerCrop" /> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:includeFontPadding="false" android:textColor="@android:color/black" android:text="Theodore"/> </com.yourpackage.name.views.SquareLayout> 

Вы можете написать код в функции «onBindViewHolder» в держателе просмотра ресайклеров. В этом случае вы можете получить наблюдателя дерева просмотра просмотра ресайклера и изменить ширину или (и) высоту представления элементов ресайклеров.