Android RecyclerView的LayoutManager配置

RecyclerView的item布局方式依赖于其配置的布局管理器。不同的布局管理器可以实现不同的界面效果。

LayoutManager介绍

RecyclerView可以通过setLayoutManager设置布局管理器,该方法的源码如下:

    /**
     * Set the {@link LayoutManager} that this RecyclerView will use.
     *
     * <p>In contrast to other adapter-backed views such as {@link android.widget.ListView}
     * or {@link android.widget.GridView}, RecyclerView allows client code to provide custom
     * layout arrangements for child views. These arrangements are controlled by the
     * {@link LayoutManager}. A LayoutManager must be provided for RecyclerView to function.</p>
     *
     * <p>Several default strategies are provided for common uses such as lists and grids.</p>
     *
     * @param layout LayoutManager to use
     */
    public void setLayoutManager(@Nullable LayoutManager layout)

上述方法的入参为LayoutManager,该类为RecyclerView的抽象静态类。该类型的具体实现存在以下几种:
在这里插入图片描述

  • MaterialCalendar中的匿名实现类:日历管理器中实现的布局管理器,由于是内部匿名类,因此开发过程中无法进行使用。
  • LinearLayoutManager:线性布局管理器,线性排列RecyclerView的item,可以分为水平和垂直两个方向。
  • GridLayoutManager:网格布局管理器,继承了LinearLayoutManager,可以将item以网格的形式进行展示,构造方法中存在spanCount参数,可以表明每行存在数据的个数。
  • LinearLayoutManagerImpl:线性布局的进一步加工实现,主要为了viewPage的布局切换实现。
  • SmoothCalendarLayoutManager:com.google.android.material.datepicker包下package作用范围的 LinearLayoutManager子类。主要为日期选择器提供布局支持,开发过程中无法进行使用。
  • StaggeredGridLayoutManager:交错网格布局管理器,可以再两个方向(垂直、水平)交错的进行item布局,计算机输入键盘可以使用该布局进行实现(也可以用网格布局管理器)

LinearLayoutManager详解

/**
 * A {@link RecyclerView.LayoutManager} implementation which provides
 * similar functionality to {@link android.widget.ListView}.
 */
public class LinearLayoutManager extends RecyclerView.LayoutManager implements
        ItemTouchHelper.ViewDropHandler, RecyclerView.SmoothScroller.ScrollVectorProvider 

ViewDropHandler:滑动消除、拖动支持的辅助接口
ScrollVectorProvider:平滑滚动的接口

最简单的构造方法,本质上是调用LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation, boolean reverseLayout) 进行初始化实例。

    /**
     * Creates a vertical LinearLayoutManager
     *
     * @param context Current context, will be used to access resources.
     */
    public LinearLayoutManager(Context context) {
        this(context, RecyclerView.DEFAULT_ORIENTATION, false);
    }

参数较为齐全的构造方法,包含了布局方式【水平、竖直】以及是否反转item展示。
例如展示list=[1,2,3,4,5],如果reverseLayout=true则从左到右或从上到下(受orientation参数影响)的展示1,2,3,4,5,否则展示内容为:5,4,3,2,1

    /**
     * @param context       Current context, will be used to access resources.
     * @param orientation   Layout orientation. Should be {@link #HORIZONTAL} or {@link
     *                      #VERTICAL}.
     * @param reverseLayout When set to true, layouts from end to start.
     */
    public LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation,
            boolean reverseLayout) {
        setOrientation(orientation);
        setReverseLayout(reverseLayout);
    }

如注释说明,该构造方法使用通过XML配置线性构造管理器,相比较上面构造方法外该方法增加了setStackFromEnd(properties.stackFromEnd);调用。setStackFromEnd表明从底部进行数据加载和展示。

    /**
     * Constructor used when layout manager is set in XML by RecyclerView attribute
     * "layoutManager". Defaults to vertical orientation.
     *
     * {@link android.R.attr#orientation}
     * {@link androidx.recyclerview.R.attr#reverseLayout}
     * {@link androidx.recyclerview.R.attr#stackFromEnd}
     */
    public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        Properties properties = getProperties(context, attrs, defStyleAttr, defStyleRes);
        setOrientation(properties.orientation);
        setReverseLayout(properties.reverseLayout);
        setStackFromEnd(properties.stackFromEnd);
    }

通过上述构造方法可以初始化创建一个线性布局管理器,并针对该管理器进行了基础配置。每个item都交友该管理器进行布局管理,此外线性管理器还提供配置布局参数(宽度、高度、权重)的方法,以及定位到指定位置的方法。

GridLayoutManager详解

网格管理器的构造方法类似于线性布局管理器,在其基础上还增加了spanCount参数的配置。该参数配置了在一行或者一列中展示item的最大数量

    /**
     * @param context Current context, will be used to access resources.
     * @param spanCount The number of columns or rows in the grid
     * @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link
     *                      #VERTICAL}.
     * @param reverseLayout When set to true, layouts from end to start.
     */
    public GridLayoutManager(Context context, int spanCount,
            @RecyclerView.Orientation int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        setSpanCount(spanCount);
    }

StaggeredGridLayoutManager详解

交错网格布局类似于网格布局的构造方法

使用示例

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        recyclerView = binding.recyclerView;
        //设置垂直的线性布局管理器,Orientation --> VERTICAL:垂直 HORIZONTAL:水平
        LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,false);
        layoutManager.setStackFromEnd(false);
//        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        //
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),2);

        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
        BaseAdapter<String> baseAdapter = new BaseAdapter<String>(R.layout.item_line) {
            @Override
            public void bindView(ViewHolder holder, String obj, int position) {
                holder.setText(R.id.item,obj);
            }
        };
        baseAdapter.add("一个");
        baseAdapter.add("二个");
        baseAdapter.add("三个");
        baseAdapter.add("四个");
        baseAdapter.add("五个");
        baseAdapter.add("六个");
        baseAdapter.add("七个");
        recyclerView.setAdapter(baseAdapter);

    }

交错布局
在这里插入图片描述

上一篇:小例子Flask网站开发—args(三)


下一篇:WINFORM画笔实现画板(如何实现橡皮擦和清空画板功能)