Recycler没有直接提供设置item间距的功能,而是提供了一个更强大的基类ItemDecoration。类如其名,这个类是Item的装饰。它既可以作为Item的间距,也可以在item之间绘制分隔线,甚至可以对每个item的边缘都进行不同的绘制。
ItemDecoration本身是一个虚类,我们在使用时,只能继承它。
先看一个简单版本,这个版本的ItemDecoration只提供一个Item的间距。
import android.graphics.Rect; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; /** * Created by fishboneLsy on 2016/6/25. */ public class DivideDecoration extends RecyclerView.ItemDecoration{ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (parent.getChildAdapterPosition(view) < parent.getAdapter().getItemCount() - 1){ outRect.bottom = 30; } } }
上面的例子中,我们将每个item下面,留出30像素的间隔,并且增加一个判断语句,即最后一个item的下方不会加间隔。从上面的例子举一反三,我们可以为不同的item,加上不同的空格。
----------------------------------------------------------------------------------------------------------------------
除了设置间隔外,我们还可以绘制分隔线:
import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Created by fishboneLsy on 2016/6/25. */ public class DrawerDecoration extends RecyclerView.ItemDecoration { Drawable mDivider; public DrawerDecoration(Context context){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher ,null); }else { mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher ); } } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.bottom = mDivider.getIntrinsicHeight(); } }
由上面的例子,我们可以看到,分隔线的绘制实质是在一个循环中完成的。也就是说,我们可以为每个item绘制不同的分隔线。我们可以自己在Canvas上绘制,也可以直接将一个Drawable绘制在Canvas上,上面的代码,就是将一个Drawable直接绘制在Canvas上。
在这个例子中,我们的outRect.bottom就必须获取Drawable的实质高度了。这样的一个类,为我们提供了极大的分隔线订制的灵活性。 也许打造了一个体验良好的列表控件,提供了很多方便。
Done~
importandroid.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by fishboneLsy on 2016/6/25.
*/
public class DrawerDecoration extends RecyclerView.ItemDecoration {
Drawable mDivider;
public DrawerDecoration(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher ,null);
}else {
mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher );
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.bottom = mDivider.getIntrinsicHeight();
}
}