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的工作流程后再学习
相关文章推荐
- Android-UI布局---RecyclerView学习(四)匹配GridLayoutManager的ItemDecoration
- Android-UI布局---RecyclerView学习(三)匹配LinearLayoutManager的ItemDecoration
- Android——RecyclerView入门学习之RecyclerView.Adapter
- Android学习之SwipeRefreshLayout+RecyclerView+CardView
- 关于Android RecyclerView的那些开源LayoutManager
- Android 自定义RecyclerView.ItemDecoration(GridLayoutManager布局下)
- Android——RecyclerView入门学习之ItemDecoration
- android RecyclerView GridLayoutManager setSpanSizeLookup 不执行(不调用)
- Android Recyclerview GridLayoutManager column spacing
- AndroidRecyclerviewGridLayoutManager列间距 - Android Recyclerview GridLayoutManager column spacing
- Android Recyclerview GridLayoutManager列间距 - Android Recyclerview GridLayoutManager column spacing
- android RecyclerView LayoutManager 分页加载判断
- android RecyclerView GridLayoutManager 滚动后导致第一行消失
- Android RecyclerView+StaggerLayoutManager实现瀑布流单选item乱跳
- AndroidRecyclerviewGridLayoutManager列间距 - Android Recyclerview GridLayoutManager column spacing
- Android-RecyclerView组件中setLayoutManager方法的使用,使RecyclerView更有趣-刘宇
- Android RecyclerView简单入门学习
- 【Android】【RecyclerView】各种LayoutManager划分割线
- Android学习第四课:Java代码动态创建View及LayoutParams类(二)
- Android开发 解决RecyclerView in SwipeRefreshLayout触发下拉刷新的bug