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);
}
交错布局