Как перекомпоновать элементы в RecyclerView с помощью StaggeredGridLayoutManager

Я играю с StaggeredGridLayoutManager, и у меня есть что-то близкое к тому, что я хочу. У меня есть горизонтальная шахматная сетка с 2 строками, где некоторые элементы имеют высоту 1 строки, а другие охватывают обе строки. Я хочу, чтобы элементы с одной высотой строки складывались, и я подумал, что этого можно добиться, установив для стратегии разрыва значение GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS, но, похоже, это не работает.

Текущий:

 ___    ___    ___    ___
|___|  |   |  |___|  |   |
       |   |         |   |
       |___|         |___|

Что я хочу:

 ___    ___    ___
|___|  |   |  |   |
 ___   |   |  |   |
|___|  |___|  |___|

Соответствующие фрагменты кода:

Настройка менеджера компоновки для recyclerview:

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(layoutManager);

Вот onBindViewHolder для моего пользовательского адаптера (это просто упрощенный пример). В основном у меня есть ImageView внутри CardView (для CardView установлено значение wrap_content для высоты и ширины).

if(position%3==0) {
    ViewGroup.LayoutParams layoutParams = viewHolder.myImage.getLayoutParams();
    layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 75, context.getResources().getDisplayMetrics());
    viewHolder.myImage.setLayoutParams(layoutParams);

    StaggeredGridLayoutManager.LayoutParams layoutParams1 = ((StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams());
    layoutParams1.setFullSpan(false);
}
else {
    ViewGroup.LayoutParams layoutParams = viewHolder.myImage.getLayoutParams();
    layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    viewHolder.myImage.setLayoutParams(layoutParams);

    StaggeredGridLayoutManager.LayoutParams layoutParams1 = ((StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams());
    layoutParams1.setFullSpan(true);
}

person Niraj    schedule 11.11.2014    source источник
comment
Как сделать так, чтобы элементы этого макета занимали обе строки? - В настоящее время я пытаюсь добиться этого с помощью вертикальной прокрутки - 2 столбца, где первый элемент должен представлять заголовок, охватывающий оба столбца.   -  person CodingMeSwiftly    schedule 28.11.2014
comment
Ах! Не берите в голову. это [layoutParams.setFullSpan(true)]   -  person CodingMeSwiftly    schedule 28.11.2014
comment
Важно сделать это в onBindViewHolder, так как это первое место, в котором к представлению применяется StaggeredGridLayoutManager.LayoutParams. Хотя странно, что это место для этого... Этот метод следует использовать только для привязки.   -  person mato    schedule 29.11.2014


Ответы (3)


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

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

Я надеюсь, это поможет вам!

person mato    schedule 11.11.2014
comment
Да, я надеялся, что, возможно, я просто что-то упустил из-за ограниченной документации, доступной в настоящее время. Спасибо за ответ! - person Niraj; 11.11.2014

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

person yigit    schedule 11.11.2014

То, чего вы хотите достичь, вполне возможно с помощью GridLayoiutManager вместо StaggerdLayoutmanager. Здесь я бы использовал Gridlayoutmanager следующим образом.

 mGridLayoutManager = new GridLayoutManager(mContext,2,GridLayoutManager.HORIZONTAL,false);
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if(position==0 && position ==1){
                    return 1;
                }else {
                    return 2;
                }
            }
        });
person Mahendra Chhimwal    schedule 08.03.2016
comment
Попробуйте это, я использовал этот API менеджера gridlayout для создания разнородных макетов. - person Mahendra Chhimwal; 08.03.2016