RecyclerView的高效使用第一节

在开发的过程中列表相关的布局是最不可或缺的一部分,而掌握一些高效的技巧可以帮助我们提升开发效率的同时,还能优化代码,减少冗余和bug的产生。

1.listitem实时预览

在UI绘制时,免不了进行细节和样式的调整,如果每次的调整都去run之后查看效果,则效率低下,使用listitem,则可以避免运行,直接使用AndroidStudio自带的预览功能进行调试
例如

<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rv_student"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:listitem="@layout/item_study"
    tools:context=".one.StudentActivity" />

效果如下:
在这里插入图片描述

2,xml中设置layoutManager

<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rv_student"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:listitem="@layout/item_study"
    android:orientation="vertical"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    tools:context=".one.StudentActivity" />

在布局代码中可以直接设置LayoutManager类型和相关的一些属性,例如方向,网格布局时每一行的个数等。

3,使用默认的分割线

可以使用官方提供的默认的分割线样式,减少重复的创建。

    //添加默认的分割线
        rv_student.addItemDecoration(DividerItemDecoration(this,
            (rv_student.layoutManager as LinearLayoutManager).orientation))

如需个性化定制,需要自己基于ItemDecoration进行定制

4,添加Item点击事件

使用Kotlin函数式的思想,快捷的添加点击事件
1)在Adapter的构造函数中添加入参

class StudentAdapter(private val data:ArrayList<StudentInfo>,
                     private val itemClick:(StudentInfo) ->Unit):
    RecyclerView.Adapter<StudentAdapter.ViewHolder>() {
    
}

2)初始化Adapter时传入点击的函数

    //学生数据列表
    private val studentEntities = ArrayList<StudentInfo>()
    //适配器
    private val  studentAdapter by lazy {
        StudentAdapter(studentEntities,this::onStudentItemClick)
    }

	/**
	*点击事件
	*/
    private fun onStudentItemClick(entity:StudentInfo){
        /**
         * 点击Item时,获取的当前点击的用户信息
         */
        Log.d(TAG,"onStudentItemClick()--->$entity")
        Toast.makeText(this,"$entity",Toast.LENGTH_LONG).show()
    }

3)使用时

  itemView.setOnClickListener { itemClick(entity) }

5,Adapter中获取上下文

在onCreateViewHolder中获取context对象,减少构建时的传参

  //定义上下文
    private lateinit var context:Context

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        context = parent.context
    }

如上功能完成的代码如下:
1,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="wrap_content"
    android:layout_margin="16dp"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/iv_icon"
        android:layout_width="48dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_height="48dp"/>

    <TextView

        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:id="@+id/tv_title"
        android:gravity="center"
        android:text="Study"
        android:textSize="22sp"
        android:layout_marginLeft="16dp"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintBottom_toTopOf="@+id/tv_second"
        android:textColor="@android:color/black"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_subtitle"
        android:layout_width="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/iv_icon"
        app:layout_constraintTop_toBottomOf="@+id/tv_study"
        android:textSize="16sp"
        android:layout_marginLeft="16dp"
        app:layout_constraintVertical_chainStyle="packed"
        android:text="zhansan"
        android:textColor="@color/cardview_dark_background"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_gender"
        android:layout_width="wrap_content"
        android:textSize="18sp"
        android:text=""
        android:textColor="@color/material_on_surface_emphasis_high_type"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_height="wrap_content"/>


</androidx.constraintlayout.widget.ConstraintLayout>

2,Activity布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rv_student"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:listitem="@layout/item_study"
    android:orientation="vertical"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    tools:context=".one.StudentActivity" />

3,Activity代码

package com.example.recyclerviewstudy.one

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerviewstudy.R
import com.example.recyclerviewstudy.StudentInfo

class StudentActivity : AppCompatActivity() {
    companion object{
        val TAG = this::class.simpleName
    }
    //学生数据列表
    private val studentEntities = ArrayList<StudentInfo>()
    //适配器
    private val  studentAdapter by lazy {
        StudentAdapter(studentEntities,this::onStudentItemClick)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_study)
        initRecyclerView()
    }

    private fun initRecyclerView(){
        val rv_student = findViewById<RecyclerView>(R.id.rv_student)
        //添加默认的分割线
        rv_student.addItemDecoration(DividerItemDecoration(this,
            (rv_student.layoutManager as LinearLayoutManager).orientation))
        rv_student.adapter = studentAdapter
        produceData()
    }

    private fun onStudentItemClick(entity:StudentInfo){
        /**
         * 点击Item时,获取的当前点击的用户信息
         */
        Log.d(TAG,"onStudentItemClick()--->$entity")
        Toast.makeText(this,"$entity",Toast.LENGTH_LONG).show()
    }
	
	//生产数据
    private fun produceData(){
        for (i in 0..20){
            studentEntities.add(StudentInfo("zhang san $i",i,if (i%2==0)"男" else "女"))
        }
    }
}

4,Adapter完整代码

package com.example.recyclerviewstudy.one

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerviewstudy.R
import com.example.recyclerviewstudy.StudentInfo

class StudentAdapter(private val data:ArrayList<StudentInfo>,
                     private val itemClick:(StudentInfo) ->Unit):
    RecyclerView.Adapter<StudentAdapter.ViewHolder>() {

    //定义上下文
    private lateinit var context:Context

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        context = parent.context
        return ViewHolder(LayoutInflater.from(context)
            .inflate(R.layout.item_study,parent,false),itemClick)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(data[position])
    }

    override fun getItemCount() = data.size

    inner class ViewHolder(itemView:View,val itemClick:(StudentInfo) -> Unit):RecyclerView.ViewHolder(itemView){
        val tv_name:TextView = itemView.findViewById(R.id.tv_title)
        val tv_age:TextView = itemView.findViewById(R.id.tv_subtitle)
        val tv_gender:TextView = itemView.findViewById(R.id.tv_gender)
        private lateinit var entity:StudentInfo

        init {
            itemView.setOnClickListener { itemClick(entity) }
        }

        fun bind(entity:StudentInfo){
            this.entity = entity
            entity.apply {
                tv_name.text = name
                tv_age.text = "$age"
                tv_gender.text = gander
            }
        }
    }
}

针对RecyclerView相关的实际使用目前学到的就这些,具体实践还需结合自己项目架构进行优化实现。
RecyclerView是开发中必不可少的,虽然它的功能和性能相较于ListView有了很大的改善和提升,但使用不当还是会存在一些性能问题,且目还有进一步的优化空间,结合mCacheViewExtension和DiffUtil的实现,让你的UI更加流畅。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值