LayoutManager是一个抽象类,有3个子类:
- LinearLayoutManager 线性布局管理器
- GridLayoutManager 表格布局管理器
- StaggeredGridLayoutManager 瀑布流布局管理器
3个布局管理器,之前都是很简单地使用,了解的并都算不多。学习下每个布局管理器中常用的方法,同时了解一下涉及思路,也为以后学习自定义LayoutManager先打点基础
1.LinearLayoutManager 线性布局管理器
线性布局使用频率很高,几乎每个应用都会有列表,基本都会用到。
1.1 构造方法
有3个构造方法:
LinearLayoutManager(Context context)LinearLayoutManager(Context context,int orientation,boolean reverseLayout)LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,int defStyleRes)
第一个构造方法内部调用了第二个构造方法,第二个构造方法参数的含义:
- Context context :上下文,初始化时,构造方法内部加载资源用
- int orientation :方向,垂直和水平,默认为垂直
- boolean reverseLayout:是否倒序,设置为
True,从最后一个item开始,倒序加载。此时,RecyclerView第一个item是添加进Adapter中的最后一个,最后一个item是第一个加进Adapter的数据,RecyclerView会自动滑到末尾
将reverseLayout设置为true:
但此时的设置的分割线如果考虑的不够全面,就会受到影响。具体的使用场景不清楚。如果只是为了让数据倒序展示,而RecyclerView还是从头开始而不自动滑动末尾,可以在数据添加进Adapter前,将集合内的数据进行倒序处理
orientation,也可以通过manger.setOritation()设置
reverseLayout,也可以通过manager.setReverseLayout()设置
第3个构造方法,可以使用自定义属性,根据属性优先级选择在不同的时机,根据需求来使用不同的样式,目前使用不多,详细的内容可以查看Android自定义View构造函数详解
1.2 setStackFromEnd(boolean stackFromEnd)
源码中的注释:
When stack from bottom is set to true, the list fills its content starting from the bottom of the view.
当从堆底部开始展示设置为true时,列表便会从底部开始展示内容
设置为true时,RecycelrView会自动滑倒尾部,直到最后一条数据完整展示
这个方法和manager.setReverseLayout(true)共同点就是都自动滑动尾部,RecyclerView默认会展示末尾的item。差别在于,manager.setStackFromEnd(true)不会影响内部的数据顺序,怎么添加进Adapter的,就怎么展示
1.3scrollToPosition(int position)滑动到指定item
使用也特简单,manager.scrollToPosition(15)
方法中需要的position是adapter position,就是在Adapter中,item实际的positon
这个方法在刚刚初始化LayoutManger时,就可以使用,此时还没有向Adapter中添加数据
方法源码:
/**
*Scroll the RecyclerView to make the position visible.
*
*Note that scroll position change will not be reflected until the next layout call.</p>
*
* @param position Scroll to this adapter position
* @see #scrollToPositionWithOffset(int, int)
*/
@Override
public void scrollToPosition(int position) {
mPendingScrollPosition = position;
mPendingScrollPositionOffset = INVALID_OFFSET;
if (mPendingSavedState != null) {
mPendingSavedState.invalidateAnchor();
}
requestLayout();
}
方法将传递进来的positon赋值给了mPendingScrollPosition,并调用了requestLayout()方法。感觉是在布局chidlView时,进行了回调处理
暂时只是简单看了一眼源码,里面具体的过程比较复杂,没有深挖
mPendingScrollPositionOffset = INVALID_OFFSET这行代码是设置偏移量的,INVALID_OFFSET默认为Integer.MIN_VALUE
这个方法还有一个类似的方法scrollToPositionWithOffset(int position, int offset)
源码中两个方法的差别在于mPendingScrollPositionOffset = offset。
将之前的manager.scrollToPosition(15)换成manager.scrollToPositionWithOffset(15,30),同样会调到adapter positoin为15的item,但整个RecycelrView中的内容,向下偏移了30 px
1.4 获取当前RecyclerView首尾可见item的adapter positon方法
| 方法 | 作用 |
|---|---|
findFirstVisibleItemPosition() | 返回当前RecycelrView中第一个可见的item的adapter postion |
findLastVisibleItemPosition() | 返回当前RecycelrView中最后一个可见的item的adapter postion |
findFirstCompletelyVisibleItemPosition() | 返回当前RecycelrView中第一个完整可见的item的adapter postion |
findLastCompletelyVisibleItemPosition() | 返回当前RecycelrView中最后一个完整可见的item的adapter postion |
方法1:findFirstVisibleItemPosition()和方法2:findFirstCompletelyVisibleItemPosition()的差别在于:在RecyclerView中,第一个item_A只是露出一点点,并没有完全展示,item_B是A下方的一个item,完全展示在屏幕上,方法1返回的是item_A的adapter position,方法2返回item_B的adapter position
例如:
- findFirstVisibleItemPosition():14
- findFirstCompletelyVisibleItemPosition():15
- findLastVisibleItemPosition():33
- findLastCompletelyVisibleItemPosition():32
这4个方法,只有当RecyclerView在屏幕展示出来后,才能得到正常的返回值,否则都是-1
LinearLayoutManager暂时就先学习这几个常用的方法
2. GridLayoutManager 表格布局管理器
继承之LinearLayoutManager,在需要使用instanceof对LinearLayoutManager做判断时,需要注意
GridLayoutManager同样也有3个构造方法,由于是继承LiearLayoutMnager,使用起来差别不大,构造方法内使用了super()方法来直接调用了父类的构造方法:
代码:
/**
* Creates a vertical GridLayoutManager
*
* @param context Current context, will be used to access resources.
* @param spanCount The number of columns in the grid
*/
public GridLayoutManager(Context context, int spanCount) {
super(context);
setSpanCount(spanCount);
}
- spanCount : 列数
根据方法的注释,可以知道,默认情况下,GridLayoutManager是垂直的
在方法内,列数是调用setSpanCount(spanCount)进行设置;相应的,getSpanCount()可以得到列数
注意:
setStackFromEnd()不支持GridLayoutManager(),但支持setReverseLayout(boolean)方法
常用的方法在LinearLayoutManager()提过了,其他的方法暂时先放一下
3.StaggeredGridLayoutManager 瀑布流管理器
简单使用:
public class LMActivity extends AppCompatActivity {
private RecyclerView rv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lm);
init();
}
/**
* 初始化
*/
private void init() {
rv = (RecyclerView) findViewById(R.id.rv_lm_activity);
//瀑布流布局管理器
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(manager);
//添加边距
rv.addItemDecoration(new RVItemDecoration(16));
//适配器
RecyclerViewAdapter adapter = new RecyclerViewAdapter(rv,R.layout.id_rv_item_layout,R.id.tv__id_item_layout);
rv.setAdapter(adapter);
//添加数据
List<String> dataList = new ArrayList<>();
final String res = "英勇青铜5";
for (int i = 0 ; i < 50; i ++){
int num = (int)(Math.random() * 20 +1);
StringBuilder stringBuilder = new StringBuilder();
for (int j = 0 ; j < num; j ++){
stringBuilder.append(res,0,res.length());
}
dataList.add(stringBuilder.toString());
stringBuilder.delete(0,stringBuilder.length());
}
adapter.setData(dataList);
}
@Override
protected void onDestroy() {
super.onDestroy();
rv.setAdapter(null);
}
}
Item布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv__id_item_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="20sp" />
</LinearLayout>
效果:
使用这3个布局管理器,差不多90%的需求都能满足吧,自定义LayoutManager打算放在学习过RecycelrView的工作流程后再学习

本文介绍了RecyclerView中的三种布局管理器:LinearLayoutManager、GridLayoutManager及StaggeredGridLayoutManager的基本使用方法和常见API。针对每种布局的特点,提供了实例代码和运行效果。
1072

被折叠的 条评论
为什么被折叠?



