Android開發(fā)(26)——RecyclerView

本節(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>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容