RecycleView使用详解

RecycleView

1 简介:

一个非常重要和常用的UI组件,在应用中以列表形式或网格形式展示大量数据,是一个可滑动的组件
优点:

  • 可重用有限数量的视图元素
  • 可快速更新变化的数据
    在这里插入图片描述

2 制作一个简单的RecycleView

2.1 在文件中添加RecycleView组件

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/news_list0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/search"
        >

    </androidx.recyclerview.widget.RecyclerView>

2.2 为每一个item创建xml布局

例如:
news.item.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100sp"
    android:orientation="vertical"
    android:paddingBottom="20sp">
    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="36sp"
        android:text="title"
        android:autoSizeTextType="uniform"
        android:textStyle="bold"
        android:paddingRight="50sp"></TextView>
    <TextView
        android:id="@+id/tvAuther"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=" auther"></TextView>
</LinearLayout>

2.3 继承一个Adapter

Adapter:
负责提供数据和创建列表项视图
数据和视图的媒介
当数据发生变化时,管理数据的创建、更新、添加、删除
NewsAdapter

 class NewsAdapter :RecyclerView.Adapter<NewsViewHolder>{
    private val newsList: List<NewsItemBean>;

    constructor(newsList:List<NewsItemBean>){
        this.newsList = newsList;
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
        val view: View = LayoutInflater.from(parent.context).inflate(R.layout.news_item,parent,false);
        return NewsViewHolder(view);
    }

    override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
        val itemBean = newsList[position];

        itemBean.title?.let {
            holder.tvTitle.text = it;
        }

        itemBean.auther.let{
            holder.tvAuther.text = it;
        }
    }

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

}

NewItemBean:

data class NewsItemBean(
    /*
    标题
     */
    val title: String?,

    /*
    作者
     */
    val auther: String?
)

2.4 继承RecycleView.ViewHolder

class NewsViewHolder : RecyclerView.ViewHolder {
    var tvTitle:TextView
        private set

    var tvAuther:TextView
        private set

    constructor(view: View) :super(view){
        tvTitle=view.findViewById(R.id.tvTitle)
        tvAuther=view.findViewById(R.id.tvAuther)
    }
}

2.5 在相应Acitivity的onCreat()中,获取RecycleView,并且为它设置Adapter和LayoutParams

//在对应activity的onCreate()方法中调用addRecycleView()

//…………

private fun addRecycleView(){
        newsRecycleView = findViewById(R.id.news_list0);
        newsAdapter = NewsAdapter(createNewsData());//创建了假数据
        newsRecycleView?.adapter = newsAdapter
        newsRecycleView?.layoutManager = LinearLayoutManager(this)
    }

效果如下:
在这里插入图片描述
至此一个简单的RecycleView就做好了!!!❀

3 实现多种item布局

有时我们想要显示的列表中,不仅仅只有一种item布局,可能有多种布局。那么接下来我们看看如何改善成为一个包含多种item的RecycleView.

3.1 编写每一种布局的xml文件

例如:在上面程序的基础上,再添加一个news_item2.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200sp"
    android:orientation="vertical"
    xmlns:tools="http://schemas.android.com/tools">
    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="36sp"
        android:text="title"
        android:textSize="28sp"
        android:textStyle="bold"
        android:paddingRight="50sp"
        tools:ignore="end"
        >

    </TextView>

    <ImageView
        android:id="@+id/ivImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/role"
        >

    </ImageView>

</LinearLayout>

3.2.adapter的修改:

对于每个类型的item有type来标识、区分他们

  1. 重写getItemViewType()方法,传进来的是位置,传出是类型:具体逻辑根据需要完成:

    override fun getItemViewType(position: Int): Int {
        return itemType_pos.get(position)
        //这里简单的自定义了个List记录类型,直接查表即可。(RecycleView的item的数量、类型排列是死的)
    }
    
  2. 修改onCreatViewHolder方法;
    根据传进来的viewType去选择加载成哪一种item,并且返回哪一种ViewHolder;

    NewsViewHolder1和NewsViewHolder2都继承于ViewHolder,因此返回ViewHolder类型

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view: View
        return when (viewType) {
            ITEM_TYPE1 -> {
                view = LayoutInflater.from(parent.context).inflate(R.layout.news_item, parent, false)
                NewsViewHolder1(view)
            }
            ITEM_TYPE2 -> {
                view = LayoutInflater.from(parent.context).inflate(R.layout.news_item2, parent, false)
                NewsViewHolder2(view)
            }
            // 添加其他类型对应的 ViewHolder...
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }
    
  3. 修改onBindViewHolder方法:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val newsItem = newsList[position]
    
        when (holder) {
            is NewsViewHolder1 -> holder.bindData(newsItem as NewsItemBeanWithAuther) // 如果是 NewsViewHolder 类型,调用其 bindData 方法
            is NewsViewHolder2 -> holder.bindData(newsItem as NewsItemBeanWithImage) // 如果是 NewsViewHolder2 类型,调用其 bindData 方法
            // 添加其他类型对应的 bindData 调用...
        }
    }
    

3.3.再新建一个NewsViewHolder2.kt类,用于处理第二种news_item2:

class NewsViewHolder2 : ViewHolder {
    var tvTitle: TextView
        private set

    var ivImage: ImageView
        private set

    constructor(view: View) :super(view){
        tvTitle=view.findViewById(R.id.tvTitle)
        ivImage=view.findViewById(R.id.ivImage)
    }

    fun bindData(newsItemBeanWithImage: NewsItemBeanWithImage){
        tvTitle.text = newsItemBeanWithImage.title
        ivImage.setImageResource(newsItemBeanWithImage.imageUrl)
    }
}

同样得再NewsViewHolder1中也添加一个bindData方法。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值