AndroidUI

RecyclerView的基础篇-列表的展示

2020-08-30  本文已影响0人  dashingqi
Android_Banner.jpg

简介

使用

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
<uses-permission android:name="android.permission.INTERNET" />
//准备的图片地址
    private var imgUrls = mutableListOf(
        "https://img.fulaishiji.com/images/goods/19883/big/03957c4d-6869-4cef-ad3e-824852f9da2b_800x800.png",
        "https://img.fulaishiji.com/images/goods/19307/big/e2635d9a-d5eb-4acf-b08c-44483a8554e2_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/17249/big/3389ee28-5b14-4b55-8f5d-64a00d5deb37_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/12461/big/b0be6cbd-3164-470b-b355-d9b41b0ce0e6_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/16743/big/65843bf9-7ba1-48d0-884e-aefeebf9b635_964x964.jpg",
        "https://img.fulaishiji.com/images/goods/12534/big/3dabd1b5-f37f-4320-9832-fccbdc8e1ecf_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/14897/big/e1c774c9-7003-4a4a-9e12-1bdf1d729457_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/12753/middle/95f064c5-8bfc-44d6-a7d8-5058cb3f93e7_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/10396/middle/e174305c-b32c-4b9d-a0b1-a14de0ae011a_3648x3648.jpg",
        "https://img.fulaishiji.com/images/goods/17824/middle/19d6253c-1ef9-48f0-b63f-d01d2f354eee_2728x2728.jpg",
        "https://img.fulaishiji.com/images/goods/17337/middle/9974521a-34c4-4daf-9c07-717dface9cce_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/13223/middle/a0a32982-3af5-45ae-9252-a554503ec829_800x800.jpg",
        "https://img.fulaishiji.com/images/goods/19906/middle/41dca304-69b2-490f-b001-0b99fa4fcc60_1008x1008.jpg",
        "https://img.fulaishiji.com/images/goods/19653/middle/c31cca8b-7468-4d5f-a06c-8427a7d01656_800x800.jpg"
    )
常规写法
  <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".GridLayoutManagerActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
  class GridLayoutManagerActivity : AppCompatActivity() {
    private val items = ArrayList<Food>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_grid_layout_manager)

        for (index in 0 until 200) {
            val food = Food()
            food.name = "name $index"
            food.desc = "desc $index"
            val position = (Math.random() * (imgUrls.size - 1)).toInt()
            food.imgUrl = imgUrls[position]
            items.add(food)
        }
        var adapter = GridLayoutAdapter(items)
        rv.adapter = adapter
    }
}
class GridLayoutAdapter(var foodList: ArrayList<Food> = ArrayList()) :
    RecyclerView.Adapter<GridLayoutAdapter.MyViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        var itemView = View.inflate(parent.context, R.layout.grid_layout_item, null)
        return MyViewHolder(itemView)
    }

    override fun getItemCount(): Int {
        return foodList.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.itemView.tvName.text = foodList[position].name
        holder.itemView.tvDesc.text = foodList[position].desc
        Glide.with(holder.itemView.context).load(foodList[position].imgUrl)
            .into(holder.itemView.ivCover)
    }

    class MyViewHolder(item: View) : RecyclerView.ViewHolder(item) {
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

        <ImageView
            android:id="@+id/ivCover"
            android:layout_width="80dp"
            android:scaleType="centerCrop"
            android:layout_height="80dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="4dp"
            android:gravity="center"
            android:textColor="#333333"
            android:textSize="18sp"
            app:layout_constraintLeft_toRightOf="@+id/ivCover"
            app:layout_constraintTop_toTopOf="@+id/ivCover" />

        <TextView
            android:id="@+id/tvDesc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textSize="14sp"
            app:layout_constraintBottom_toBottomOf="@+id/ivCover"
            app:layout_constraintLeft_toLeftOf="@+id/tvName"
            app:layout_constraintTop_toBottomOf="@+id/tvName" />

</androidx.constraintlayout.widget.ConstraintLayout>
配合DataBinding使用
// 在module 的 build.gradle中的 android{}中加入如下
  dataBinding{
        enabled true
    }
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="item"
            type="com.dashingqi.module.recyclerview.Food" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/ivCover"
            // 这里使用了DataBinding中自定义属性功能
            // 自定义属性的文件在下文中也给出了
            imageUrl="@{item.imgUrl}"
            android:layout_width="80dp"
            android:scaleType="centerCrop"
            android:layout_height="80dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="4dp"
            android:gravity="center"
            android:text="@{item.name}"
            android:textColor="#333333"
            android:textSize="18sp"
            app:layout_constraintLeft_toRightOf="@+id/ivCover"
            app:layout_constraintTop_toTopOf="@+id/ivCover" />

        <TextView
            android:id="@+id/tvDesc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="@{item.desc}"
            android:textSize="14sp"
            app:layout_constraintBottom_toBottomOf="@+id/ivCover"
            app:layout_constraintLeft_toLeftOf="@+id/tvName"
            app:layout_constraintTop_toBottomOf="@+id/tvName" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class MainActivity : AppCompatActivity() {

    private var data = ArrayList<Food>()
   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        configRv()
    }

    private fun configRv() {
        for (index in 0 until 200) {
            val food = Food()
            food.name = "name $index"
            food.desc = "desc $index"
            val position = (Math.random() * (imgUrls.size - 1)).toInt()
            food.imgUrl = imgUrls[position]
            data.add(food)
        }
        // RecyclerView中 可以通过在xml文件中指定LayoutManager,这里我们是通过代码形式的
        rv.layoutManager = LinearLayoutManager(this)
        rv.adapter = RVAdapter(data)
    }
}
 <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            // xml文件中指定的LayoutManager
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    </androidx.constraintlayout.widget.ConstraintLayout>
class RVAdapter(var itemData: ArrayList<Food> = ArrayList()) :
    RecyclerView.Adapter<RVAdapter.MyViewHolder>() {
    private val TAG = "RVAdapter"
    private var viewHolderCount = 0


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        viewHolderCount++
        Log.d(TAG, "onCreateViewHolder ---->$viewHolderCount")
        var itemBinding = DataBindingUtil.inflate<RvItemBinding>(
            LayoutInflater.from(parent.context),
            R.layout.rv_item,
            parent,
            false
        )
        return MyViewHolder(itemBinding)
    }

    override fun getItemCount(): Int {
        return itemData.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        Log.d(TAG, ": onBindViewHolder")
        var dataBinding = holder.viewDataBinding as RvItemBinding
        dataBinding.item = itemData[position]
        dataBinding.executePendingBindings()
    }

    class MyViewHolder(var viewDataBinding: ViewDataBinding) :
        RecyclerView.ViewHolder(viewDataBinding.root) {

    }

    companion object {
        private const val TAG = "RVAdapter"
    }
}
object ImageBindAdapter {

   @JvmStatic
   @BindingAdapter(value = ["imageUrl"], requireAll = false)
    fun setImageUrl(view: ImageView, url: String) {
       Glide.with(view.context).load(url).into(view)
   }
}
binding-collection-adapter+DataBinding+ViewModel
引入binding-collection-adapter
implementation 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:4.0.0'
implementation 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:4.0.0'
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mainBinding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        //绑定ViewModel
          val foodViewModel = ViewModelProvider(this)[FoodViewModel::class.java]
        mainBinding.viewModel = foodViewModel
    }

}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="viewModel"
            type="com.dashingqi.module.recyclerview.FoodViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            itemBinding="@{viewModel.itemBinding}"
            items="@{viewModel.items}"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class FoodViewModel: ViewModel() {
    val items = ObservableArrayList<Food>()
    val itemBinding = ItemBinding.of<Food>(BR.item, R.layout.rv_item)
    init {
        for (index in 0 until 200) {
            val food = Food()
            food.name = "name $index"
            food.desc = "desc $index"
            val position = (Math.random() * (imgUrls.size - 1)).toInt()
            food.imgUrl = imgUrls[position]
            items.add(food)
        }
    }
}

总结

针对上述写法做一个对比
实际项目
上一篇下一篇

猜你喜欢

热点阅读