本節(jié)內(nèi)容
1.RecyclerView簡介
2.viewBinding使用步驟
3.設(shè)置數(shù)據(jù)源,顯示數(shù)據(jù)
4.布局方向和內(nèi)容尺寸
5.卡片上布局
一、RecyclerView簡介
1.RecyclerView應(yīng)用場景:微博、知乎、網(wǎng)易新聞等軟件。就是你在頁面上可以不斷的往下拉,然后查看各種內(nèi)容。
2.RecyclerView可以轉(zhuǎn)換很多種數(shù)據(jù),對于不同的軟件,轉(zhuǎn)換的數(shù)據(jù)也不一樣。如果是音樂軟件,那么就是歌曲;如果是新聞?lì)愜浖敲淳褪歉鞣N信息。
使用適配器adapter模式可以適配各種各樣的數(shù)據(jù),所以它是一個(gè)接口。
這個(gè)接口里面有一些方法:getItemCount,獲取數(shù)據(jù)的個(gè)數(shù)(歌曲或新聞的數(shù)量)。onBindView和onBindViewHolder,獲取數(shù)據(jù)的樣式(歌曲或新聞的布局排版)。
3.使用者使用數(shù)據(jù)的時(shí)候,會(huì)先去找適配器(adapter),適配器里面有一些接口,由數(shù)據(jù)實(shí)現(xiàn)者來實(shí)現(xiàn)這些接口。
4.RecyclerView有很多部件
(1)adapter 完成數(shù)據(jù)的顯示 :RecyclerView.Adapter(接口)
(2)layoutManager(布局管理器) 樣式 (線性 網(wǎng)格 瀑布流 滾動(dòng)方向)
(3)itemDecoration :每一個(gè)item 的裝飾器
(4)xx-layout.xml :每一個(gè)item顯示的樣子模板
二、viewBinding使用步驟
1.創(chuàng)建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其實(shí)就是把MainActivity和activity_main.xml綁定在一起。先在gradle中設(shè)置一下
viewBinding.enabled = true
3.在MainActivity里面創(chuàng)建一個(gè)ActivityMainBinding對象。
private var mBinding: ActivityMainBinding? = null
4.在onCreate方法里面把它解析出來。這樣就實(shí)現(xiàn)了viewBinding的綁定。
mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this))
setContentView(mBinding?.root)
三、設(shè)置數(shù)據(jù)源,顯示數(shù)據(jù)
1.在代碼中配置屬性,要先確定樣式LayoutManager,再確定數(shù)據(jù)源。
在下面的代碼中。先確定樣式LayoutManager
第一個(gè)參數(shù)表示上下文,第二個(gè)表示豎向不停地滑動(dòng)顯示,第三個(gè)參數(shù)說明不用反轉(zhuǎn)顯示(反轉(zhuǎn)顯示:內(nèi)容從后往前顯示)
mBinding?.mRecycle?.layoutManager = LinearLayoutManager(
this,
LinearLayoutManager.VERTICAL,
false
)
(1)還有很多其他的樣式。比如網(wǎng)格布局,第二個(gè)參數(shù)3的意思為spanCount,表示有多少列,它會(huì)自動(dòng)分配。
mBinding?.mRecycle?.layoutManager = GridLayoutManager(
this, 3,
GridLayoutManager.VERTICAL,
false
)
(2)交錯(cuò)式?格布局 - 瀑布流布局。第一個(gè)參數(shù)的意思是列數(shù)。使用這個(gè)布局的時(shí)候,高度不要寫死,寫成wrap_content。
mBinding?.mRecycle?.layoutManager = StaggeredGridLayoutManager(
2,StaggeredGridLayoutManager.VERTICAL,false
)
2.確定數(shù)據(jù)源
(1)先創(chuàng)建一個(gè)保存所有數(shù)據(jù)源的數(shù)組,(假如數(shù)據(jù)源是圖片)
private val dataSource = mutableListOf<Int>()
(2)先自己拖動(dòng)幾張圖片到drawable里面,然后確定數(shù)據(jù)源。使用隨機(jī)數(shù)來隨機(jī)確定數(shù)據(jù)源。
for (i in 0..10) {
if ((Random.nextInt() % 2 == 0)) {
dataSource.add(R.drawable.cute1)
}else{
dataSource.add(R.drawable.cute2)
}
}
3.定義一個(gè)類實(shí)現(xiàn)RecyclerView.Adapter接口,RecyclerView就是通過這個(gè)接口里的方法訪問數(shù)據(jù)的。
class PhotosAdapter: RecyclerView.Adapter<PhotosAdapter.MyViewHolder>() {
}
a.創(chuàng)建一個(gè)類繼承于RecyclerView.ViewHolder,用來重復(fù)利用的。每次滾動(dòng)的時(shí)候,上面的內(nèi)容在消失,下面又在加載,消失的工程會(huì)放在一個(gè)隊(duì)列里面,如果有可以重復(fù)利用的,那么新加載就可直接從里面獲取,不用再重新創(chuàng)建了。
傳遞過來的view就是 RecyclerView中每一個(gè)item的視圖,拿過來才有可能做重復(fù)利用。其中item_icon是圖片的id
class MyViewHolder(item: View) : RecyclerView.ViewHolder(item) {
//獲取id對應(yīng)的視圖
val iconImageView = item.findViewById<ImageView>(R.id.item_icon)
}
4.因?yàn)檫@個(gè)方法繼承自RecyclerView.ViewHolder,所以必須重寫adapter里面的抽象方法,分別是onCreateViewHolder(), onBindViewHolder()和 getItemCount()。
5.在Mainactivity里面設(shè)置一下適配器對象。
val adapter = PhotosAdapter();
要讓這兩個(gè)類里面的數(shù)據(jù)進(jìn)行交互的話,在PhotosAdapter里面添加一個(gè)數(shù)據(jù)變量。
lateinit var datas:MutableList<Int>
然后在MainActivity里面調(diào)用數(shù)據(jù)化對象,這樣就把這里面的數(shù)據(jù)拿到另外一個(gè)類里去了。
adapter.datas = dataSource;
mBinding?.mRecycle?.adapter = adapter;
6.既然數(shù)據(jù)都整過來了,那么就可以實(shí)現(xiàn)上面的三個(gè)抽象方法了。
首先是getItemCount()方法,確定當(dāng)前有多少個(gè)item
override fun getItemCount(): Int {
return datas.size
}
其次是onCreateViewHolder() 確定每一個(gè)item的視圖
(1)自己創(chuàng)建一個(gè)View 或者 用一個(gè)xml文件來布局。那么我們先創(chuàng)建一個(gè)xml視圖,然后隨意布局一下。

xml布局
(2)通過LayoutInflater 解析布局文件 xml->view
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
//獲取xml布局的視圖 xml -> View
//如果知道一個(gè)view 就可以通過這個(gè)view獲取view所在的上下文context
val layoutInflater = LayoutInflater.from(parent.context)
val itemView = layoutInflater.inflate(R.layout.photos_item,
parent,false)
return MyViewHolder(itemView)
}
最后實(shí)現(xiàn)onBindViewHolder()方法,視圖解析出來之后 需不需要將數(shù)據(jù)綁定到上面
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.iconImageView.setImageResource(datas[position])
}
四、布局方向和內(nèi)容尺寸
1.在MainActivity里面設(shè)置一下分割線,這是每個(gè)視圖之間的分割線。
mBinding?.mRecycle?.addItemDecoration(
DividerItemDecoration(this,DividerItemDecoration.VERTICAL))
2.設(shè)置item裝飾器addItemDecoration
(1)系統(tǒng)提供的 DividerItemDecoration 分割線
(2)自己創(chuàng)建一個(gè)類繼承于ItemDecoration 重寫 onDraw 或者 onDrawOver
3.使用addItemDecoration方法時(shí),里面可以是自己創(chuàng)建的類,讓它繼承于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)為視圖的左上右下與邊框的距離。
通過以下方法調(diào)用該類即可。
mBinding?.mRecycle?.addItemDecoration(MyDecoration())
4.如果每個(gè)Item顯示一屏,按頁來顯示。那么設(shè)置一下滑動(dòng)的幫助類。當(dāng)我們左右滑動(dòng)的時(shí)候,哪邊占的面積大,最后就顯示哪邊的內(nèi)容。
LinearSnapHelper().attachToRecyclerView(mBinding?.mRecycle)
5.如果修改一下每個(gè)子控件,把它們的高度都設(shè)為150dp,寬度不變。然后在設(shè)置LayoutManager把縱向改為橫向,那么就可以做一個(gè)簡單的廣告頁了。
五、卡片式布局
1.創(chuàng)建一個(gè)resourceFile,然后拖動(dòng)一個(gè)卡片式布局過來。

卡片式布局
2.然后拖動(dòng)一張圖片過來,然后用約束布局,布局一下。并把這個(gè)圖片的id改為item_icon
3.這個(gè)卡片式布局還可以設(shè)置圖片的圓角半徑
app:cardCornerRadius="20dp"
4.整個(gè)卡片式布局的代碼如下圖所示
<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>