RecyclerView源码剖析
本人Android菜鸟一枚,很多没写博客了。言归正传,RecyclerView平时开发中用的比较多,打算试着剖析它的源码,因为白天上班,水平有限,但是坚持每天剖析更新一些,记录在博客上,欢迎指正交流。
前言
RecyclerView继承于ViewGroup,那么万变不离其中,主要的还是onMeasure、onLayout方法。onMeasure测量以及决定RecyclerView的大小,onLayout方法而是将Adapter中的Child(子View)以合适的坐标进行布局排列。onMeasure
todoonLayout
此方法将Adapter中的Child(子View)以合适的方法进行布局排列。RecyclerView作为一个大量数据集合的容器展示控件,那么还是一样,我们猜想其中的每个Child都需要调用View.layout(left,top,right,bottom)方法对Child进行按照正确的坐标进行布局摆放。在onLayout中一层一层追踪,方法中看到了这段代码
public void layoutDecoratedWithMargins(View child, int left, int top, int right,
int bottom) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final Rect insets = lp.mDecorInsets;
child.layout(left + insets.left + lp.leftMargin, top + insets.top + lp.topMargin,
right - insets.right - lp.rightMargin,
bottom - insets.bottom - lp.bottomMargin);
}
其中的参数我解释下。
child:即将展示在RecyclerView中的子view。
left:RecyclerView左边边缘的坐标,为相对坐标。注意是边缘坐标。这个坐标是测量之后的出来的。注意:在此坐标中包括了Margin以及装饰物的布局大小。
insets:装饰物的布局参数,比如我们平时通过以下代码来添加分割线,这里就是每条分割线的布局参数。
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
这个我需要记录下。当为添加此分割线时候,只有bottom的值为1,其余全为0,这个1px就是分割线的高度。其实也就顺带出了DividerItemDecoration中这段代码的作用。
@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}这也就是为什么这段的outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());只设置了一个值。
快捷键
- 加粗
Ctrl + B - 斜体
Ctrl + I - 引用
Ctrl + Q - 插入链接
Ctrl + L - 插入代码
Ctrl + K - 插入图片
Ctrl + G - 提升标题
Ctrl + H - 有序列表
Ctrl + O - 无序列表
Ctrl + U - 横线
Ctrl + R - 撤销
Ctrl + Z - 重做
Ctrl + Y
代码块
代码块语法遵循标准markdown代码,例如:
@requires_authorization
def somefunc(param1='', param2=0):
'''A docstring'''
if param1 > param2: # interesting
print 'Greater'
return (param2 - param1 + 1) or None
class SomeClass:
pass
>>> message = '''interpreter
... prompt'''