首页 > 代码库 > 从头开始学 RecyclerView(六) LayoutManager
从头开始学 RecyclerView(六) LayoutManager
前言
在前面的文章中,每个示例,都使用了LayoutManager,毕竟它是RecyclerView不可缺少的一部分。
LayoutManager,顾名思义,就是『布局管理器』。
使用如下代码,设置RecyclerView的LayoutManager:
mRecyclerView.setLayoutManager(layoutManager);
已提供的LayoutManager
android.support.v7.widget.LinearLayoutManager
android.support.v7.widget.GridLayoutManager
android.support.v7.widget.StaggeredGridLayoutManager
LinearLayoutManager
线性 水平或垂直 布局
构造函数如下:
public LinearLayoutManager(Context context) {
this(context, VERTICAL, false);
}
public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
setOrientation(orientation);
setReverseLayout(reverseLayout);
setAutoMeasureEnabled(true);
}
public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
...
}
第1个中,内部使用了第2个。第3个是xml中配置时使用的。实现跟第2个的实现类似。这里就解释下第2个构造方法中的参数意义:
orientation —— 取值 LinearLayoutManager.HORIZONTAL,表示水平方向;取值 LinearLayoutManager.VERTICAL,表示垂直方向
reverseLayout —— 是否需要布局反转。true,表示需要:若是方向为HORIZONTAL,则内容会从右到左显示,滚动方向也是;同样,方向为VERTICAL时,则内容会从下向上显示,滚动方向也是
GridLayoutManager
网格布局。
构造函数如下:
public GridLayoutManager(Context context, int spanCount) {
super(context);
setSpanCount(spanCount);
}
public GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
setSpanCount(spanCount);
}
public GridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {…} //xml
由于GridLayoutManager 继承了 LinearLayoutManager,所以构建函数中的参数意思差不多。
主要说下参数 spanCount 意义:在方向为HORIZONTAL时,spanCount就表示有几行;在方向为VERTICAL时,spanCount就表示有几列
StaggeredGridLayoutManager
交错的网格布局。
构造函数如下:
public StaggeredGridLayoutManager(int spanCount, int orientation){
mOrientation = orientation;
setSpanCount(spanCount);
setAutoMeasureEnabled(mGapStrategy != GAP_HANDLING_NONE);
mLayoutState = new LayoutState();
createOrientationHelpers();
}
public StaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {…} //xml
StaggeredGridLayoutManager 继承了 GridLayoutManager。参数意义与GridLayoutManager类似。
要实现交错式,除了设定RV的layoutManger为StaggeredGridLayoutManager外,还要设置item的宽或高的尺寸。
当方向为HORIZONTAL时,spanCount表示总的行数,这时为item设置不一样的宽度,即有横向交错的感觉。
当方向为HORIZONTAL时,spanCount表示总的列数,这时为item设置不一样的高度,即有纵向交错的感觉。
如果只是对item设置LayoutParams,那么还需要相应的设置item的内容view的LayoutParams。所以如果可以,直接改变item内容view的LayoutParams即可
关于改变宽或高的示例代码:
@Override
public void bindCustomViewHolder(BaseHolder holder, int position) {
holder.itemView.setFocusable(true);//加了这句,电视上就能滚动了
TextView tvTitle = holder.getView(R.id.tv_title);
tvTitle.setText(getItem(position));
View vImg = holder.getView(R.id.v_img);
vImg.setBackgroundColor(getColor());
if (mIsStaggered) {
float size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());//100dip转px
int w = mOrientation == LinearLayoutManager.HORIZONTAL ? (int)size : -1;
int h = mOrientation == LinearLayoutManager.HORIZONTAL ? -1 : (int)size;
if (mOrientation == LinearLayoutManager.HORIZONTAL) {
w = (int) (size + Math.random() * size);
} else {
h = (int) (size + Math.random() * size);
}
// holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(w, h));
vImg.setLayoutParams(new RelativeLayout.LayoutParams(w, h));
}
}
注:由于这里设置成宽高随机值,所以每次重新滑动到开始位置时,都会重新布局。如果给一个定长就不会了:
w = (int)size;
if (position % 2 == 1) {
w = w / 2;
}
示例详情:https://github.com/aa86799/RecyclerView/tree/recycler-restart/
从头开始学 RecyclerView(六) LayoutManager