Margin/padding в последнем дочернем элементе RecyclerView

Я пытаюсь добавить Padding/Margin Bottom в последнем ряду и Padding/Margin Top в первом ряду. Я не могу сделать это в элементе xml, так как это повлияет на всех моих детей.

В адаптере RecyclerView есть заголовки и дочерние элементы, поэтому я не могу использовать

   android:padding="4dp"
   android:clipToPadding="false"

Мне нужно использовать его отдельно в последней первой строке каждого заголовка

Ответ 1

Эта проблема еще проще решить. Вы можете применить необходимое дополнение к самому RecylerView и установить clipToPadding в значение false, в противном случае отступы отрубают вашу область прокрутки. Вот пример

<android.support.v7.widget.RecyclerView
    android:padding="4dp"
    android:clipToPadding="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

См. дополнение добавит 4dp со всех сторон, включая верхнюю и нижнюю. Затем параметр clipToPadding гарантирует, что ваши дочерние элементы не будут отрублены. Теперь добавьте 4dp дополнение ко всем сторонам для ваших дочерних элементов, и вам хорошо идти. В общей сложности вы получаете 8dp дополнение по бокам и между пунктами.

Ответ 2

Вместо добавления отступов к верхнему и нижнему элементам вы можете просто добавить дополнение к верхней и нижней части вашего RecyclerView и установить атрибут clipToPadding на false.

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:paddingTop="8dp"
    android:paddingBottom="8dp" />

Ответ 3

используйте ItemDecoration:

private class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

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

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        boolean isLast = position == state.getItemCount()-1;
        if(isLast){
            outRect.bottom = space;
            outRect.top = 0; //don't forget about recycling...
        }
        if(position == 0){
            outRect.top = space;
            // don't recycle bottom if first item is also last
            // should keep bottom padding set above
            if(!isLast)
                outRect.bottom = 0;
        }
    }
}

и

//8dp as px
int space = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
            getResources().getDisplayMetrics()); // calculated
//int space = getResources().getDimensionPixelSize(
//    R.dimen.list_item_padding_vertical); // from resources
recyclerView.addItemDecoration(new SpacesItemDecoration(space));

Ответ 4

 <android.support.v7.widget.RecyclerView
                android:id="@+id/rv_tpf"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clipToPadding="false"
                android:paddingBottom="100dp" />

Добавьте android:clipToPadding="false" и android:paddingBottom="100dp" в своем android:paddingBottom="100dp" переработчика.

Ответ 5

По какой-то причине старое решение clipToPadding=false не работает для меня. Поэтому я добавил ItemDecoration

https://gist.github.com/kassim/582888fa5960791264fc92bc41fb6bcf

public class BottomPaddingDecoration extends RecyclerView.ItemDecoration {
    private final int bottomPadding;

    public BottomPaddingDecoration(int bottomPadding) {
        this.bottomPadding = bottomPadding;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
        if (position == parent.getAdapter().getItemCount() - 1) {
            outRect.set(0, 0, 0, bottomPadding);
        }
    }
}

Ответ 6

Я изменил изумительный ответ @snachmsm, чтобы лучше понять, как правильно его использовать.

public class SpacesItemDecoration extends DividerItemDecoration {
    private int space;

    public SpacesItemDecoration(Context clContext,int oriantation,int space) {
        super(clContext,oriantation);
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect,view,parent,state);
        int position = parent.getChildAdapterPosition(view);
        boolean isLast = position == state.getItemCount()-1;
        if(isLast){
            outRect.bottom = space;
            outRect.top = 0; //don't forget about recycling...
        }
       /* if(position == 0){
            outRect.top = space;
            // don't recycle bottom if first item is also last
            // should keep bottom padding set above
            if(!isLast)
                outRect.bottom = 0;
        }*/
    }
}

Ответ 7

Добавьте android: clipToPadding = "false" и android: paddingBottom = "65dp" в своем обзоре переработчика. Если вы используете потрясающую кнопку меню и действия в ячейке просмотра переработчика.

<androidx.recyclerview.widget.RecyclerView
      android:id="@+id/dinner_recycler_view"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:clipToPadding="false"
      android:paddingBottom="65dp"/>

Ответ 8

Я использую это в kotlin

override fun onBindViewHolder(holder: RecyclerView.ViewHolder(view), position: Int) {
    if (position == itemsList.lastIndex){
        val params = holder.itemView.layoutParams as FrameLayout.LayoutParams
        params.bottomMargin = 100
        holder.itemView.layoutParams = params
    }else{
        val params = holder.itemView.layoutParams as RecyclerView.LayoutParams
        params.bottomMargin = 0
        holder.itemView.layoutParams = params
    }
  //other codes ...
}