Android——RecyclerView入门学习之LayoutManager

    xiaoxiao2021-03-27  40

    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 postionfindLastVisibleItemPosition()返回当前RecycelrView中最后一个可见的item的adapter postionfindFirstCompletelyVisibleItemPosition()返回当前RecycelrView中第一个完整可见的item的adapter postionfindLastCompletelyVisibleItemPosition()返回当前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():14findFirstCompletelyVisibleItemPosition():15findLastVisibleItemPosition():33findLastCompletelyVisibleItemPosition():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的工作流程后再学习

    转载请注明原文地址: https://ju.6miu.com/read-664468.html

    最新回复(0)