您的位置:首页 > 移动开发 > Android开发

Android——RecyclerView入门学习之LayoutManager

2017-04-04 12:10 786 查看
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:



倒序展示,RecycelrView自动滑动到最后

但此时的设置的分割线如果考虑的不够全面,就会受到影响。具体的使用场景不清楚。如果只是为了让数据倒序展示,而
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
会自动滑倒尾部,直到最后一条数据完整展示



setStackFromEnd(true)时

这个方法和
manager.setReverseLayout(true)
共同点就是都自动滑动尾部,
RecyclerView
默认会展示末尾的
item
。差别在于,
manager.setStackFromEnd(true)
不会影响内部的数据顺序,怎么添加进
Adapter
的,就怎么展示

1.3scrollToPosition(int position)滑动到指定item

使用也特简单,
manager.scrollToPosition(15)




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




设置偏移量为30

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


例如:



设置偏移量为30

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
的工作流程后再学习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: