Intereting Posts
Исключение SQLite Cursor вне пределов исключения в SELECT count (*) FROM table Android – добавление изображений в проект Предварительный просмотр пользовательского интерфейса камеры на Android? Как использовать бесплатную базу данных облаков с Android-приложением? Пример использования вкладок Android с представлениями вместо действий? Почему EditText в пользовательском составном представлении повторно использует текст, введенный в другой составной экземпляр вида? Трансляция, когда состояние сети изменилось Получить номер телефона входящего вызова в Android Я могу изменить внешний вид кликабельности Как я могу правильно передать уникальные дополнения к ожидающемуся намерению? IOException: сбой чтения, сокет может быть закрыт – Bluetooth на Android 4.3 Google + Вход: активность не запускается Получить абсолютный путь к папке с ресурсами в PhoneGap Доступ запрещен при создании хранилища ключей для приложения для Android Android: Можно ли обновить ImageView / ImageButton с номером, чтобы показать количество новых сообщений?

LayoutManager для сетки RecyclerView с различной шириной ячейки

StaggeredGridLayoutManager , похоже, не позволяет настраивать ширину ячейки или диапазон нескольких столбцов (кроме полного диапазона) для вертикальной ориентации.

Введите описание изображения здесь

Каков предпочтительный LayoutManager для организации ячеек, как показано выше?

PS Я просто хочу знать, как настроить ширину ячейки, а не высоту с помощью StaggeredGridLayoutManager . Я знаю, что высота может быть изменена, как реализовано в этом примере .

 public class VerticalStaggeredGridFragment extends RecyclerFragment { public static VerticalStaggeredGridFragment newInstance() { VerticalStaggeredGridFragment fragment = new VerticalStaggeredGridFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } @Override protected RecyclerView.LayoutManager getLayoutManager() { return new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); } @Override protected RecyclerView.ItemDecoration getItemDecoration() { return new InsetDecoration(getActivity()); } @Override protected int getDefaultItemCount() { return 100; } @Override protected SimpleAdapter getAdapter() { return new SimpleStaggeredAdapter(); } } 

адаптер

 public class SimpleStaggeredAdapter extends SimpleAdapter { @Override public void onBindViewHolder(VerticalItemHolder itemHolder, int position) { super.onBindViewHolder(itemHolder, position); final View itemView = itemHolder.itemView; if (position % 4 == 0) { int height = itemView.getContext().getResources() .getDimensionPixelSize(R.dimen.card_staggered_height); itemView.setMinimumHeight(height); } else { itemView.setMinimumHeight(0); } } } 

itemView.setMinimumWidth(customWidth) не влияет на ширину ячейки.

Чтобы упростить, я обновляю схему сетки до

Введите описание изображения здесь

Как увеличить ширину ячейки 0 по сравнению с ячейкой 1 в StaggeredGridLayoutManager или любом другом менеджере компоновки?

Solutions Collecting From Web of "LayoutManager для сетки RecyclerView с различной шириной ячейки"

Вы можете использовать StaggeredGridLayoutManager.LayoutParams для изменения ширины и высоты ячеек. То, что вы ожидаете от дизайна, следует по простому шаблону. Если вы назначаете каждой ячейке индекс (в том порядке, в котором StaggeredGridLayoutManager упорядочивает их по умолчанию), вы получите следующее:

 index % 4 == 3 ---> full span cell index % 8 == 0, 5 ---> half span cell index % 8 == 1, 2, 4, 6 ---> quarter span cell 

Сначала объявите некоторые константы в адаптере для определения типов span:

 private static final int TYPE_FULL = 0; private static final int TYPE_HALF = 1; private static final int TYPE_QUARTER = 2; 

Затем переопределите метод getItemViewType в вашем адаптере следующим образом:

 @Override public int getItemViewType(int position) { final int modeEight = position % 8; switch (modeEight) { case 0: case 5: return TYPE_HALF; case 1: case 2: case 4: case 6: return TYPE_QUARTER; } return TYPE_FULL; } 

Все, что вам нужно сделать, это изменить layoutparams с учетом viewType holder :

 @Override public MyHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { final View itemView = LayoutInflater.from(mContext).inflate(R.layout.items, parent, false); itemView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { final int type = viewType; final ViewGroup.LayoutParams lp = itemView.getLayoutParams(); if (lp instanceof StaggeredGridLayoutManager.LayoutParams) { StaggeredGridLayoutManager.LayoutParams sglp = (StaggeredGridLayoutManager.LayoutParams) lp; switch (type) { case TYPE_FULL: sglp.setFullSpan(true); break; case TYPE_HALF: sglp.setFullSpan(false); sglp.width = itemView.getWidth() / 2; break; case TYPE_QUARTER: sglp.setFullSpan(false); sglp.width = itemView.getWidth() / 2; sglp.height = itemView.getHeight() / 2; break; } itemView.setLayoutParams(sglp); final StaggeredGridLayoutManager lm = (StaggeredGridLayoutManager) ((RecyclerView) parent).getLayoutManager(); lm.invalidateSpanAssignments(); } itemView.getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); MyHolder holder = new MyHolder(itemView); return holder; } 

Мой адаптер всегда возвращает 50 для количества элементов (только тест), и я использовал простой файл макета для элементов. Он содержит LinearLayout и TextView чтобы показать позицию владельца. Помните, что вы должны передать 2 для spanCount (int в конструкторе StaggeredGridLayoutManager ) Из-за вашего дизайна.

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView rv = (RecyclerView) findViewById(R.id.rv); StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); rv.setLayoutManager(lm); rv.setAdapter(new MyAdapter(this)); } 

Введите описание изображения здесь

PS : Для ленивых людей, таких как я, может быть, это более простой способ, чем расширение моего настраиваемого LayoutManager , но я уверен, что есть лучшие способы достичь этого.

Обновление . Обновленная часть вашего вопроса более проста, вы можете использовать GridLayoutManager :

  GridLayoutManager glm = new GridLayoutManager(this, 3); glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position % 3 == 2) { return 3; } switch (position % 4) { case 1: case 3: return 1; case 0: case 2: return 2; default: //never gonna happen return -1 ; } } }); rv.setLayoutManager(glm); 

Таким образом, вы устанавливаете 3 для размера диапазона по умолчанию. Затем, учитывая положение вашего диапазона, каждый элемент занимает 1, 2 или 3 пролета, что-то вроде этого:

Введите описание изображения здесь

 Item0.width == 2 X Item1.width Item2.width == 3 X Item1.width Item0.width == 2/3 X Item1.width 

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

Большое спасибо Нику Батчеру ! Его менеджер макетов под названием SpannableGridLayoutManager способен это сделать.

  1. Загрузить SpannableGridLayoutManager здесь

    По какой-то причине мне пришлось изменить эту строку:

     while (availableSpace > 0 && lastVisiblePosition < lastItemPosition) { 

    в

     while (lastVisiblePosition < lastItemPosition) { 

    Чтобы менеджер работал.

  2. Установите SpannableGridLayoutManger в свой RecyclerView

В твоем случае:

 SpannedGridLayoutManager manager = new SpannedGridLayoutManager( new SpannedGridLayoutManager.GridSpanLookup() { @Override public SpannedGridLayoutManager.SpanInfo getSpanInfo(int position) { switch (position % 8) { case 0: case 5: return new SpannedGridLayoutManager.SpanInfo(2, 2); case 3: case 7: return new SpannedGridLayoutManager.SpanInfo(3, 2); default: return new SpannedGridLayoutManager.SpanInfo(1, 1); } } }, 3, // number of columns 1f // default size of item ); 

Это даст вам именно то, что находится в первой картине вопроса.

Введите описание изображения здесь