Android开发(26)——RecyclerView

本节内容

1.RecyclerView简介

2.viewBinding使用步骤

3.设置数据源,显示数据

4.布局方向和内容尺寸

5.卡片上布局

一、RecyclerView简介
1.RecyclerView应用场景:微博、知乎、网易新闻等软件。就是你在页面上可以不断的往下拉,然后查看各种内容。
2.RecyclerView可以转换很多种数据,对于不同的软件,转换的数据也不一样。如果是音乐软件,那么就是歌曲;如果是新闻类软件,那么就是各种信息。
  • 使用适配器adapter模式可以适配各种各样的数据,所以它是一个接口。
  • 这个接口里面有一些方法:getItemCount,获取数据的个数(歌曲或新闻的数量)。onBindView和onBindViewHolder,获取数据的样式(歌曲或新闻的布局排版)。
3.使用者使用数据的时候,会先去找适配器(adapter),适配器里面有一些接口,由数据实现者来实现这些接口。
4.RecyclerView有很多部件
  • (1)adapter 完成数据的显示 :RecyclerView.Adapter(接口)
  • (2)layoutManager(布局管理器) 样式 (线性 网格 瀑布流 滚动方向)
  • (3)itemDecoration :每一个item 的装饰器
  • (4)xx-layout.xml :每一个item显示的样子模板
二、viewBinding使用步骤
1.创建RecyclerView xml里面配置。这是在activity_main.xml中配置的。
<view class="androidx.appcompat.app.AlertController$RecycleListView"
        android:id="@+id/mRecycle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
2.代码中配置属性,使用viewBinding ,viewBinding其实就是把MainActivity和activity_main.xml绑定在一起。先在gradle中设置一下
viewBinding.enabled = true
3.在MainActivity里面创建一个ActivityMainBinding对象。
private var mBinding: ActivityMainBinding? = null
4.在onCreate方法里面把它解析出来。这样就实现了viewBinding的绑定。
 mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this))
        setContentView(mBinding?.root)
三、设置数据源,显示数据
1.在代码中配置属性,要先确定样式LayoutManager,再确定数据源。
  • 在下面的代码中。先确定样式LayoutManager
  • 第一个参数表示上下文,第二个表示竖向不停地滑动显示,第三个参数说明不用反转显示(反转显示:内容从后往前显示)
 mBinding?.mRecycle?.layoutManager = LinearLayoutManager(
            this,
            LinearLayoutManager.VERTICAL,
            false
        )
  • (1)还有很多其他的样式。比如网格布局,第二个参数3的意思为spanCount,表示有多少列,它会自动分配。
mBinding?.mRecycle?.layoutManager = GridLayoutManager(
        this, 3,
        GridLayoutManager.VERTICAL,
        false
        )
  • (2)交错式⽹格布局 - 瀑布流布局。第一个参数的意思是列数。使用这个布局的时候,高度不要写死,写成wrap_content。
mBinding?.mRecycle?.layoutManager = StaggeredGridLayoutManager(
        2,StaggeredGridLayoutManager.VERTICAL,false
        )
2.确定数据源
  • (1)先创建一个保存所有数据源的数组,(假如数据源是图片)
 private val dataSource = mutableListOf<Int>()
  • (2)先自己拖动几张图片到drawable里面,然后确定数据源。使用随机数来随机确定数据源。
for (i in 0..10) {
            if ((Random.nextInt() % 2 == 0)) {
                dataSource.add(R.drawable.cute1)
            }else{
                dataSource.add(R.drawable.cute2)
            }
        }
3.定义一个类实现RecyclerView.Adapter接口,RecyclerView就是通过这个接口里的方法访问数据的。
class PhotosAdapter: RecyclerView.Adapter<PhotosAdapter.MyViewHolder>() {
}
  • a.创建一个类继承于RecyclerView.ViewHolder,用来重复利用的。每次滚动的时候,上面的内容在消失,下面又在加载,消失的工程会放在一个队列里面,如果有可以重复利用的,那么新加载就可直接从里面获取,不用再重新创建了。
  • 传递过来的view就是 RecyclerView中每一个item的视图,拿过来才有可能做重复利用。其中item_icon是图片的id
class MyViewHolder(item: View) : RecyclerView.ViewHolder(item) {
        //获取id对应的视图
        val iconImageView = item.findViewById<ImageView>(R.id.item_icon)
    }
4.因为这个方法继承自RecyclerView.ViewHolder,所以必须重写adapter里面的抽象方法,分别是onCreateViewHolder(), onBindViewHolder()和 getItemCount()。
5.在Mainactivity里面设置一下适配器对象。
 val adapter = PhotosAdapter();
  • 要让这两个类里面的数据进行交互的话,在PhotosAdapter里面添加一个数据变量。
lateinit var datas:MutableList<Int>
  • 然后在MainActivity里面调用数据化对象,这样就把这里面的数据拿到另外一个类里去了。
        adapter.datas = dataSource;
        mBinding?.mRecycle?.adapter = adapter;
6.既然数据都整过来了,那么就可以实现上面的三个抽象方法了。
  • 首先是getItemCount()方法,确定当前有多少个item
override fun getItemCount(): Int {
        return datas.size
    }
  • 其次是onCreateViewHolder() 确定每一个item的视图
  • (1)自己创建一个View 或者 用一个xml文件来布局。那么我们先创建一个xml视图,然后随意布局一下。
xml布局
  • (2)通过LayoutInflater 解析布局文件 xml->view
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        //获取xml布局的视图  xml -> View
        //如果知道一个view  就可以通过这个view获取view所在的上下文context
        val layoutInflater = LayoutInflater.from(parent.context)
        val itemView = layoutInflater.inflate(R.layout.photos_item,
            parent,false)
        return MyViewHolder(itemView)
    }
  • 最后实现onBindViewHolder()方法,视图解析出来之后 需不需要将数据绑定到上面
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.iconImageView.setImageResource(datas[position])
    }
四、布局方向和内容尺寸
1.在MainActivity里面设置一下分割线,这是每个视图之间的分割线。
     mBinding?.mRecycle?.addItemDecoration(
        DividerItemDecoration(this,DividerItemDecoration.VERTICAL))
2.设置item装饰器addItemDecoration
  • (1)系统提供的 DividerItemDecoration 分割线
  • (2)自己创建一个类继承于ItemDecoration 重写 onDraw 或者 onDrawOver
3.使用addItemDecoration方法时,里面可以是自己创建的类,让它继承于RecyclerView.ItemDecoration(),然后自己在里面布局即可。
class MyDecoration: RecyclerView.ItemDecoration() {
        override fun getItemOffsets(
            outRect: Rect, view: View, parent:
            RecyclerView, state: RecyclerView.State
        ) {
            super.getItemOffsets(outRect, view, parent, state)
            outRect.set(20, 20, 20, 20)
        }
    }
  • outRect.set(20, 20, 20, 20)为视图的左上右下与边框的距离。
  • 通过以下方法调用该类即可。
mBinding?.mRecycle?.addItemDecoration(MyDecoration())
4.如果每个Item显示一屏,按页来显示。那么设置一下滑动的帮助类。当我们左右滑动的时候,哪边占的面积大,最后就显示哪边的内容。
LinearSnapHelper().attachToRecyclerView(mBinding?.mRecycle)
5.如果修改一下每个子控件,把它们的高度都设为150dp,宽度不变。然后在设置LayoutManager把纵向改为横向,那么就可以做一个简单的广告页了。
五、卡片式布局
1.创建一个resourceFile,然后拖动一个卡片式布局过来。
卡片式布局
2.然后拖动一张图片过来,然后用约束布局,布局一下。并把这个图片的id改为item_icon
3.这个卡片式布局还可以设置图片的圆角半径
app:cardCornerRadius="20dp"
4.整个卡片式布局的代码如下图所示
<androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="20dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/item_icon"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/cute1" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容