RecyclerViewの最後の子のマージン/パディング


126

最後の行にPadding / Margin Bottomを追加し、最初の行にPadding / Margin Topを追加しようとしています。すべてのチャイルドに影響するため、アイテムxmlではできません。

RecyclerViewアダプターにヘッダーと子があるので、

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

各ヘッダーの最後の最初の行で個別に使用する必要があります


次のように使用します:<android.support.v7.widget.RecyclerView android:id = "@ + id / list" android:paddingBottom = "5dp" android:layout_width = "match_parent" android:layout_height = "wrap_content" />
Pankajアロラ2015年

onBindViewHolderでパディングとマージンを変更してから、ビューホルダーでsetIsRecyclable(false)を呼び出すことができます
user3425867

回答:


9

私はこれをコトリンで使用します

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 ...
}

232

この問題はさらに簡単に解決できます。必要なパディングをRecylerViewそれ自体に適用clipToPaddingしてfalseに設定できます。そうしないと、パディングによってスクロール領域が途切れます。ここに例があります

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

パディングにより、上下を含むすべての側面に4 dpが追加されます。次に、clipToPaddingパラメータを使用して、子アイテムが切り取られないようにします。次に、4dp子アイテムのすべての側面にパディングを追加します。これで問題ありません。合計で、側面およびアイテム間に8 dpのパディングが得られます。


そうです、私は通常それをしていますが、RecyclerViewはヘッダーで構成されており、各ヘッダーには独自の子があります。そのため、プログラムで各ヘッダーの最後と最初の行のみに設定する必要があります
RedEagle

わかりません。これはRecyclerView内のヘッダーとどのように関連していますか?ヘッダーにパディングを付けませんか?その場合でも、同じソリューションを使用して左右のパディングを取り除くことができます。
Subin Sebastian 2015

ヘッダーがあり、各ヘッダーには特定されていない子の数があるため、各ヘッダーの最後の子に上部パディング/マージンと最初の子と下部パディング/マージンを追加します。
RedEagle 2015年

私が持っていた唯一のアイデアは、ヘッダーのレイアウトに上下のマージンを設定することでしたが、それを実現するよりスマートな方法があるかどうか疑問に思いました
RedEagle

その場合は、最後の子の後に偽のアイテムをRecyclerViewに追加するだけです。これは、これを実現する最も賢い方法ではないにしても、最も簡単な方法です。:)
Subin Sebastian 2015

82

上部と下部の両方のアイテムにパディングを追加する代わりに、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" />

これは簡単な解決策ですが、RecyclerViewにヘッダーと子があり、使用できません
RedEagle

@RedEagle希望の効果が得られるかどうか試してみてください。
Collins Abitekaniza、2015年

1
このソリューションは、アイテムの装飾よりも優れています。ListAdapterを使用して別のリストを送信しているときに、前のリストの最後のアイテムの位置が変更されず、その後に新しいアイテムが追加された場合、前者はリストの最後のアイテムではなくても、下のパディングを保持しますもっと。
Ana Koridze

38

使用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));

1
RecyclerView.ItemDecorationがリソースクラスを取得するようには見えないので、コンストラクターの引数として追加しました。
Krtko 2016年

2
Googソリューション!逆レイアウトのサポートあり:gist.github.com/Miha-x64/4e8754e72a1e65e3ca742744ea501f16
Miha_x64

2
この答えは賛成されなければなりません!Subin Sebastianの答えはうまくいきますが、ItemDecorationのスペースは等しくありません。
iroiroys 2017

1
しかし、削除アイテムを挿入した後、すべてのアイテムのオフセットを再描画しません
user924

notifyItemInserted/ Removedは1つのアイテムのみを描画し、アイテムを削除してそれをクリーンアップするためView、他のすべての子には影響を与えないため、trueになる場合があります。たとえば、一部の項目がリストの最初にある場合(上部のパディングで描画)、新しい項目を上部に追加すると、以前は現在現在2番目の項目が引き続き上部にパディングされます...簡単な修正は、notifyDataSetChanged(force redraw を呼び出すことです。すべて...)、より複雑な場合、その項目を認識するためのロジックが必要です。これは、最初または最後の位置にあり、移動してから呼び出しますnotifyItemChanged(newPositionOfOldFirstAndOrLastItem)
snachmsm

28
<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"あなたのrecyclerviewインチ


2
驚くばかり!それは完璧です
KevinB

16

android:clipToPadding = "false"とandroid:paddingBottom = "65dp"をリサイクラービューに追加します。リサイクルメニュービューのセルでfabメニューボタンとアクションを使用している場合。

<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"/>

3

何らかの理由で、古い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);
        }
    }
}

1

私は素晴らしい答え@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;
        }*/
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.