本节内容
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视图,然后随意布局一下。
-
(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>