Android RecyclerView中最后一个子项的边距/填充
我试图在最后一行添加Padding/Margin-Bottom,在第一行添加Padding/Margin-Top。我不能在项目xml中这样做,因为它会影响我所有的孩子 我的RecyclerView适配器中有标题和子项,因此无法使用Android RecyclerView中最后一个子项的边距/填充,android,android-recyclerview,padding,Android,Android Recyclerview,Padding,我试图在最后一行添加Padding/Margin-Bottom,在第一行添加Padding/Margin-Top。我不能在项目xml中这样做,因为它会影响我所有的孩子 我的RecyclerView适配器中有标题和子项,因此无法使用 android:padding="4dp" android:clipToPadding="false" 我需要在每个标题的最后第一行单独使用它使用: 及 您可以只将填充添加到RecyclerView的顶部和底部,并
android:padding="4dp"
android:clipToPadding="false"
我需要在每个标题的最后第一行单独使用它使用:
及
您可以只将填充添加到RecyclerView的顶部和底部,并将
cliptoppadding
属性设置为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" />
这个问题更容易解决。您可以对
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
padding添加到您的子项的所有侧面,就可以开始了。总的来说,您在项目的两侧和项目之间得到了8dp的填充。出于某种原因,旧的cliptoppadding=false
解决方案对我不起作用。所以我加了一个装饰
在您的回收视图中添加android:clipToPadding=“false”
和android:paddingBottom=“100dp”
。我在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 ...
}
我已经修改了神奇的答案@snachmsm-answer,让你知道如何使用它 恰当地
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;
}*/
}
}
在回收视图中添加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"/>
Java等效于@Radesh answer:
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position == itemsList.size() - 1) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
params.bottomMargin = 100;
holder.itemView.setLayoutParams(params);
} else {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
params.bottomMargin = 0;
holder.itemView.setLayoutParams(params);
}
}
这是一个简单的解决方案,但我的RecyclerView中有标题和子项,因此我无法使用it@RedEagle试着看看你是否得到了想要的效果,但我相信它是有效的。这个解决方案比项目装饰方案要好。当我使用ListAdapter并提交一个不同的列表时,如果前一个列表的最后一个项目没有改变其位置,但之后添加了新项目,则前一个项目将保留其底部填充,即使它不再是列表中的最后一个项目。是的,这是我通常的做法,但我认为我的RecyclerView由标题组成,每个标题都有自己的子项,这就是为什么我需要通过编程将其设置为每个标题的最后一行和第一行,但我不确定我是否理解。这与RecyclerView中的标题有什么关系?是否希望标题没有填充?即使是这样,,您可以使用相同的解决方案消除左/右填充。我有标题,每个标题都有非特定的子项计数,因此我想在每个标题的最后一个子项添加顶部填充/边距、第一个子项和底部填充/边距。我唯一的想法是将顶部和底部边距设置到标题的布局中,但我想知道有一个更聪明的方法来实现它。在这种情况下,你可以简单地在你最后一个孩子之后在回收视图中添加一个假的项目。这是实现这一目标的最简单、也是最聪明的方法。:)这样使用:您可以更改onBindViewHolder中的填充和边距,然后在视图holder上调用setIsRecyclable(false)。它们看起来不像RecyclerView.ItemDecoration。再获取资源类,我只是将其作为参数添加到构造函数中。Goog解决方案!使用反向布局支持:此答案必须向上投票!虽然Subin Sebastian的答案很有效,但是,与item装饰空间并不相等。但是在插入移除项目后,它不会为所有项目重新绘制偏移量,因为
notifyItemInserted
/Removed
将只绘制一个项目/移除项目,并将其清理到视图中,而不触及所有其他孩子。e、 当某个项目在列表的第一个位置(用顶部填充绘制)并且我们正在向顶部添加新项目时,之前的第一个项目当前的第二个项目仍然会在顶部填充。。。简单的解决方法是调用notifyDataSetChanged
(强制重画全部…),更复杂的是需要一些逻辑来识别第一个和/或最后一个位置移动的项目,然后调用notifyItemChanged(newPositionOfOldFirstandLastItem)
!最好改成dp,谢谢
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 ...
}
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;
}*/
}
}
<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"/>
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position == itemsList.size() - 1) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
params.bottomMargin = 100;
holder.itemView.setLayoutParams(params);
} else {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
params.bottomMargin = 0;
holder.itemView.setLayoutParams(params);
}
}