从头开始学 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/

时间: 2025-01-13 22:30:50

从头开始学 RecyclerView(六) LayoutManager的相关文章

从头开始学JavaScript (六)——语句

原文:从头开始学JavaScript (六)--语句 一.条件分支语句:if 基本格式: if (<表达式1>){    <语句组1>}else if (<表达式2>){    <语句组2>}else{    <语句组3>} 执行流程: 二.循环语句 2.1前测试循环语句:在循环体内的代码被执行之前就对出口条件求值. 2.1.1while语句 基本格式: do {    <语句组>} while (<表达式>)  执行流程

从头开始学 RecyclerView(二) 添加item点击事件

不管了,先来张图 偶吐了个槽 item点击事件必须手动添加,默认并没有一个显式的API接口可供调用. 为了节约学习时间,网上找了篇很不错的文章.这里基本就复制了. 添加点击事件 RecyclerView#addOnItemTouchListener 分析 查看RecyclerView源码可以看到,RecyclerView预留了一个Item的触摸事件方法: public void addOnItemTouchListener(OnItemTouchListener listener) { mOnI

从头开始学 RecyclerView(三) 封装简化

前言 上一篇的代码,也是基于这些封装的. RV的封装,跟以前的listView之类的封装,大同小异. 这里,从@devwiki 处,将代码搬过来,基本无修改 BaseHolder的优化 使ViewHolder只用来缓存View. 添加SparseArray,使之来缓存View. 添加BaseHolder(View view)构造器,外部更方便控制View. 保留getContext()方法,方便获取Context对象. getView(resid),简化itemView.findviewById

从头开始学 RecyclerView(五) ItemDecoration 详解

前言 RecyclerView.ItemDecoration,通过名字来看,它就是用来装饰Item的. 在类ListView的视图中,可能需要绘制分隔线:在类GridView的网格视图中,可能需要绘制单元格样式- 这些都可以由重写RecyclerView.ItemDecoration来进行定制. 然后调用mRecyclerView.addItemDecoration(itemDecoration); 即可 分析 看下RecyclerView.ItemDecoration的源码: public s

笨鸟学php(六) 数组

一.数组概述 1.1 数组是复合类型 1.2 数组中可以存储任意长度的数据, 也可以存储任意类型的数据 二.数组的类型 2.1 索引数组: 下标是顺序整数作为索引 <?php $user[0] = 1; $user[1] = "zhangsan"; $user[2] = "[email protected]"; echo '<pre>'; print_r($user); echo '</pre>'; ?> 2.2 关联数组: 下标

RecyclerView自定义LayoutManager,打造不规则布局

本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. RecyclerView的时代 自从google推出了RecyclerView这个控件, 铺天盖地的一顿叫好, 开发者们也都逐渐从ListView,GridView等控件上转移到了RecyclerView上, 那为什么RecyclerView这么受开发者的青睐呢? 一个主要的原因它的高灵活性, 我们可以自定义点击事件, 随意切换显示方式, 自定义item动画, 甚至连它的布局方式我们都可以自定义. 吐吐嘈 夸

从头开始学JavaScript (十一)——Object类型

原文:从头开始学JavaScript (十一)--Object类型 一.object类型 一个object就是一系列属性的集合,一个属性包含一个名字(属性名)和一个值(属性值). object对于在应用程序中存储和传输数据而言,是非常理想的选择 二.创建object 创建object实例有两种方法: 使用new 操作符后跟object构造函数 使用对象初始化器,也就是对象字面量表示法 2.1使用new 操作符后跟object构造函数创建object实例: 1 var person = new O

从头开始学JavaScript (二)——变量及其作用域

原文:从头开始学JavaScript (二)--变量及其作用域 一.变量 ECMAscript变量是松散型变量,所谓松散型变量,就是变量名称可以保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符. 定义:var firstDemo; 二.变量的作用域 2.1基本概念 使用var 定义变量:定义该变量的作用域的局部变量,这种定义变量的方法也被成为显式声明. 这么说不理解的话可以看看下面这个简单粗暴的例子: test();function test(){var firstDemo="hello

从头开始学JavaScript (十)——垃圾收集

原文:从头开始学JavaScript (十)--垃圾收集 一.垃圾收集 1.1javascript垃圾收集机制: 自动垃圾收集,执行环境会负责管理代码执行过程中的使用的内存.而在C和C++之类的语言中,开发人员的一项基本任务就是手动跟踪内存的使用情况,这是造成许多问题的一个根源.在编写javascript程序时候,开发人员不用再关心内存使用的问题,所需内存的分配 以及无用的回收完全实现了自动管理. 1.2垃圾收集原理: 找出那些不再继续使用的变量,然后释放其中占用的内存. 垃圾收集器会按照固定的