1.RecyclerView 导入包的方式(可以避免build高版本调用低版本v7包编译不过问题)
compile ‘com.android.support:recyclerview-v7:+’
2.RecyclerView setAdapter前需要先设置LayoutManager,原因:明确其是水平展示还是纵向显示
3.RecyclerView 设置头部(尾部)View的方式
- 原始方式:
//复写getItemViewType方法,返回不同的iType值(与onCreateViewHolder保持一致)
@Override
public int getItemViewType(int position) {
int iType;
if (position == 0) {
iType = HEADVIEW;
} else {
iType = ORDINARYVIEW;
}
return iType;
}
@Override
//复写onCreateViewHolder方法,根据不同的viewType产生不同的View
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == HEADVIEW){
view=LayoutInflater.from(parent.getContext()).
inflate(R.layout.layout_item_head, null, false);
} else {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_item, null, false);
}
return new MyHolder(view);
}
//复写onBindViewHolder方法,这里headView是一个固定的View,仅对普通布局进行bean类设定
public void onBindViewHolder(MyHolder holder, int position) {
//除头部外,其余项设置文字内同
if (position != 0) {
holder.txtContent.setText(lists.get(position));
if (position % 2 == 0) {
holder.txtContent.setBackgroundColor(Color.
parseColor("#000000"));
}
}
}
关键代码:
//在build.gradle(Module)文件中添加
compile 'com.bartoszlipinski.recyclerviewheader:library: 1.2.0'
//相应Activity中调用:
RecyclerViewHeader header = RecyclerViewHeader.fromXml(
MainActivity.this,R.layout.ayout_item_head);
header.attachTo(recyclerView);
注意:
RecyclerViewHeader必须在RecyclerView设置了LayoutManager之后调用。
目前该库适用于LinearLayoutManager,GridLayoutManager和
StaggeredGridLayoutManager布局的RecyclerViews。
只支持垂直布局LayoutManager
4.RecyclerView为子项添加监听事件
在MyAdapter中对ItemView设定点击事件的监听,通过getAdapterPosition可以获取到当前点击的position,再通过该position可以获取到ArrayList中的Bean对象。代码如下:
public MyHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView. findViewById(
R.id.txtContent);
txtTit = (TextView) itemView.findViewById(R.id.txtTit);
img = (ImageView) itemView.findViewById(R.id.img);
//监控点击项
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("adapter","position: " +
getAdapterPosition()); }
});
}
在如果想要将点击事件(点击位置position)暴露给外部的话,可以自定义一个接口,利用回调机制,在onClick中的调用接口中的相应方法即可.对Item添加监听的方式有很多种,修改源码,setOnItem-Touch方法等,在此使用一种最简单的方式去实现。
5.RecyclerView显示不同的布局方式,例如:
- ①仅有content的Item
- ②有content又有title的Item
- ③有img,content,title的Item
Bean类设计如下:
public class DataBean {
public static final int DATA_TYPE_CONTENT = 1;
public static final int DATA_TYPE_TIT = 2;
public static final int DATA_TYPE_IMG = 3;
int iType = DATA_TYPE_IMG;
String strTit = "";
String strContent = "";
String strImgSource = "";
public DataBean(String _strContext) {
setType(DATA_TYPE_CONTENT);
setContent(_strContext);
}
public DataBean(String _strTit, String _strContext) {
this(_strContext);
setType(DATA_TYPE_TIT);
setTit(_strTit);
}
public DataBean(String strTit, String strContext, String _strImgSource) {
this(strTit, strContext);
setType(DATA_TYPE_IMG);
setImgSource(_strImgSource);
}
public void setTit(String strTit) {
this.strTit = strTit;
}
public String getTit() {
return strTit;
}
public void setType(int iType) {
this.iType = iType;
}
public int getType() {
return iType;
}
public void setContent(String strContent) {
this.strContent = strContent;
}
public String getContent() {
return strContent;
}
public void setImgSource(String strImgSource) {
this.strImgSource = strImgSource;
}
public String getImgSource() {
return strImgSource;
}
}
MyAdapter中进行复写getItemViewType方法,根据Bean中的type来确定Item的type值:
public int getItemViewType(int position) {
DataBean data = datalists.get(position);
return data.getType();
}
同时需要对onCreateViewHolder方法进行修改(根据viewType的值来加载不同的布局文件),核心代码如下:
switch (viewType){
case DataBean.DATA_TYPE_CONTENT:
iItemView = R.layout.layout_item_content;
break;
case DataBean.DATA_TYPE_TIT:
iItemView = R.layout.layout_item_title;
break;
case DataBean.DATA_TYPE_IMG:
iItemView = R.layout.layout_item_img;
break;
default:
break;
}
view = LayoutInflater.from(parent.getContext()).inflate(
iItemView, null, false);
return new MyHolder(view);
更改绑定数据的方法onBindViewHolder,注意在onBindViewHolder方法中没有onCreateViewHolder方法中的viewType参数,所以需要根据position在ArrayList中获取相应的元素,再通过Bean类中的getType来确定需要绑定数据的种类。核心代码如下:
DataBean _data = datalists.get(position);
switch (_data.getType()){
case DataBean.DATA_TYPE_CONTENT:
if (holder.txtContent != null) {
holder.txtContent.setText(_data.getContent());
}
break;
case DataBean.DATA_TYPE_TIT:
if(holder.txtContent != null){
holder.txtContent.setText(_data.getContent());
}
if(holder.txtTit != null){
holder.txtTit.setText(_data.getTit());
}
break;
case DataBean.DATA_TYPE_IMG:
if(holder.txtContent != null){
holder.txtContent.setText(_data.getContent());
}
if(holder.txtTit != null){
holder.txtTit.setText(_data.getTit());
}
if(holder.img != null){
holder.img.setBackgroundColor(Color.GREEN);
}
break;
}
方便期间,在这里没有实际为ImageView加载真实的图片,仅仅设定了控件的背景色代表设置图片的操作。
6.RecyclerrView设定分割线
官方没有提供设置分割线的方法recyclerView.addItemDecoration()
遗憾的是分割线是一个虚拟类,需要我们自行继承并去实现分割线的显示样式
参考万能的分割线:
完整RecycleViewDivider代码如下:
public class RecycleViewDivider extends RecyclerView.ItemDecoration {
private Paint mPaint;
private Drawable mDivider;
private int mDividerHeight = 2;//分割线高度,默认为1px
private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
/**
* 默认分割线:高度为2px,颜色为灰色
*
* @param context
* @param orientation 列表方向
*/
public RecycleViewDivider(Context context, int orientation) {
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("请输入正确的参数!");
}
mOrientation = orientation;
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public RecycleViewDivider(Context context, int orientation, int drawableId) {
this(context, orientation);
mDivider = ContextCompat.getDrawable(context, drawableId);
mDividerHeight = mDivider.getIntrinsicHeight();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) {
this(context, orientation);
mDividerHeight = dividerHeight;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
}
//获取分割线尺寸
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(0, 0, 0, mDividerHeight);
}
//绘制分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
//绘制横向 item 分割线
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin;
final int bottom = top + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}
//绘制纵向 item 分割线
private void drawVertical(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin;
final int right = left + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}
}
3种使用方式:
//自定义分割线高,指定分割线颜色
/*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
LinearLayoutManager.HORIZONTAL,10, Color.BLUE));
*/
//指定样式(在shape中进行颜色,线高的设置)的分割线
/*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
LinearLayoutManager.HORIZONTAL, R.drawable.shape_item_line));*/
//默认样式实现分割线
recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,LinearLayoutManager.HORIZONTAL));
drawable/shape_item_line.xml代码如下:
<gradient
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:startColor="#ffff0000"
android:type="linear" />
<size android:height="4dp"/>