创建自定义RecylerView
- 前言
我们的代码,为了节省大家的时间,大部分考虑复制、 粘贴的形式,代码在gitee都有,视频在B站有,如沐春风116
自定义RecylerView
- 定义适配器
public interface Adapter {
/**
* 创建ViewHolder的方法
*
* @param position
* @param convertView
* @param parent
* @return
*/
View onCreateViewHolder(int position, View convertView, ViewGroup parent);
/**
* 绑定ViewHolder的方法
*
* @param position
* @param convertView
* @param parent
* @return
*/
View onBinderViewHolder(int position, View convertView, ViewGroup parent);
/**
* 获取当前row item的控件类型
*
* @param row
* @return
*/
int getItemViewType(int row);
/**
* 获取当前控件类型的总数量
*
* @return
*/
int getViewTypeCount();
/**
* 获取当前Item的总数量
*
* @return
*/
int getCount();
/**
* 获取index Item的高度
*
* @return
*/
int getHeight(int index);
}
- onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取RecylerView在当前布局的宽高
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//当前内容的高度
int h = 0;
//判断适配器是否为空
if (mAdapter != null) {
//获取到当前数据中的总条数
rowCount = mAdapter.getCount();
//根据适配器的数据的总长度来创建数组
heights = new int[rowCount];
//循环获取到所有View的高度
for (int x = 0; x < heights.length; x++) {
heights[x] = mAdapter.getHeight(x);
}
}
//获取所有数据的高度
int tempHeight = sumArray(heights, 0, heights.length);
//判断所有ItemView的高度和RecylerView的高度谁低
h = Math.min(tempHeight, heightSize);
setMeasuredDimension(widthSize, h);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 获取到数组中数据的高度
*
* @param heights 数组
* @param index 从哪一个Item获取
* @param count 一共要拿多少个Item高度
* @return
*/
private int sumArray(int[] heights, int index, int count) {
int sum = 0;
count = index + count;
for (int x = index; x < count; x++) {
sum += heights[x];
}
return sum;
}
- onLayout方法
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//先判断是否需要布局,布局发生改变的时候重新调用
if (needRelayout || changed) {
needRelayout = false;
//清除掉所有的View
removeAllViews();
//清除掉当前屏幕中显示的ItemView
viewlist.clear();
//如果适配器不为空,就去摆放itemView
if (mAdapter != null) {
//获取到RecylerView的宽高
width = r - l;
height = b - t;
//定义布局ItemView的四个变量
int top = 0, right, bottom, left = 0;
for (int x = 0; x < rowCount; x++) {
//获取到绘制宽度的最右边
right = width;
bottom = top + heights[x];
//生成View
View view = makeAndStep(x, left, top, right, bottom);
//添加到当前ItemView的集合中
viewlist.add(view);
//因为循环摆放,所以 下一个控件的top就是上一个控件的bottom,而且需要累加
top=bottom;
}
}
}
}
我们本节课程,讲了RecylerView的测量和布局,下节课程我们将View的生成,再见,下节课继续。