Как определить положение столбца в шахматном менеджере макетов сетки

Я использую разметку просмотра ресайклера для списка фотографий. Я хочу, чтобы расстояние между сторонами было равным нулю, но между ними было пространство. Я использую подкласс класса украшения предмета, чтобы получить интервал, указанный на прилагаемой фотографии. Я знаю, что у меня есть контроль над левым и правым интервалом, но проблема в том, что я никогда не знаю, в каком столбце находится фотография. Кажется, что шахматный менеджер макетов делает некоторые из своих собственных переупорядочений. Я попытался использовать getChildAdapterPosition но, похоже, возвращает позицию в массиве источников данных, а не фактическое положение фотографии в макете. Любая идея, как я должен подходить к этому? enter image description here

Ответы

Ответ 1

Мне удалось заставить его работать. Поэтому в моем случае мне не нужны границы на левом и правом краях экрана. Мне просто нужны были границы посередине и внизу. Решение состоит в том, чтобы получить параметры макета вида, которые имеют тип StaggeredGridLayoutManager.LayoutParams. В этих параметрах вы можете получить spanIndex, который сообщает вам, по какому индексу это представление. Поэтому, если у вас есть spanCount из 2, левое представление будет иметь spanIndex 0, а правый вид будет иметь spanIndex из 1.

Вот мой код, так что, возможно, это поможет вам

public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int space;

public SpaceItemDecoration(int space) {
    this.space = space;
}


@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    int position = parent.getChildAdapterPosition(view);

    StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams)view .getLayoutParams();
    int spanIndex = lp.getSpanIndex();

    if(position > 0){
        if(spanIndex == 1){
            outRect.left = space;
        } else{
            outRect.right = space;
        }

        outRect.bottom = space * 2;
    }
}

}

В моем случае сначала я должен получить позицию, поскольку в индексе 0 у меня есть заголовок, который не имеет границ. После этого я получаю индекс span и в зависимости от него я устанавливаю границу, которая мне нужна в этом представлении. И, наконец, я установил нижнюю границу для каждого вида.

Ответ 2

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

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

recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int left = outRect.left;
            int right = outRect.right;
            int top = outRect.top;
            int bottom = outRect.bottom;
            int idx = parent.getChildPosition(view);
            int perRow = gridLayoutManager.getSpanCount();

            int adj = blahh... // some adjustment

            if (idx < itemsPerRow) {
                // on first row, adjust top if needed
            }

           if(idx % perRow == 0){
                // on first column, adjust. Left magically adjusts bottom, so adjust it too...
                left += adj;
                bottom -= adj;
           }

           if(idx % itemsPerRow == perRow - 1){
               // on last column, adjust. Right magically adjusts bottom, so adjust it too...
               right += adjustment;
               bottom -= adjustment;
           }

            outRect.set(left, top, right, bottom);
        }
    });

Опять же, это взломано и требует некоторых проб и ошибок, чтобы получить право.

Еще одно решение, которое я пробовал с некоторым успехом, - это определение разных представлений для разных столбцов. В вашем случае столбцы будут иметь представления с разными отрицательными полями слева и справа, чтобы получить необходимый эффект.

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