使用kotlin语言书写listView和recyclerView,并且使用databinding实现逻辑与视图分离

本文章实现了listView和RecyclerView数据的修改和增加,同时运用了databinding进行数据绑定以及事件绑定

先看一张效果图

效果图

现在就贴上源码

首先在app下的build.gradle下添加相关依赖,值得注意的是databinding是添加到android代码段的

  //databinding
    dataBinding {
        enabled = true
    }

//recycleView
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

主程序就放了两个按钮,用于事件的跳转

MainActivity.kt



import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.yang.databindingdemo.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var bindingData: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //实例化dataBinding
        bindingData = DataBindingUtil.setContentView(this,R.layout.activity_main)
        //绑定事件
        bindingData.setOnClick=MainActivity_OnClick(this)
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!--注册绑定数据类-->
    <data>
        <variable
            name="setOnClick"
            type="com.yang.databindingdemo.MainActivity_OnClick" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <Button
            android:id="@+id/bt_lv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="listView"
            android:textAllCaps="false"
            android:onClick="@{setOnClick.onClick}"
            />
        <Button
            android:id="@+id/bt_rv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="recyclerView"
            android:textAllCaps="false"
            android:onClick="@{setOnClick.onClick}"
            />
    </LinearLayout>


</layout>

我特意为MainActivity里面的按钮设置了一个单独的监听事件,这也是databinding的强大之处,视图和逻辑完全分离

MainActivity_Onclick.kt

import android.app.Activity
import android.content.Intent
import android.view.View
import com.yang.databindingdemo.listView.ListViewActivity
import com.yang.databindingdemo.recycleView.RecycleViewActivity

class MainActivity_OnClick(activity: Activity) {

    private val activity = activity

    fun onClick(view: View){

        when(view.id){
            R.id.bt_lv->{
                val intent : Intent =Intent(activity,ListViewActivity::class.java)
                activity.startActivity(intent)
            }
            R.id.bt_rv->{
                val intent : Intent =Intent(activity,RecycleViewActivity::class.java)
                activity.startActivity(intent)
            }
        }
    }

}

在书写listView和RecyclerView控键之前,我们需要给他们加上item和modle,我是按照官方的mvvm模式来设计的,也是目前Android最流行的模式,这种模式可以高效的减少代码之间的耦合以及oom

好了,下面请看数据类,也就是我们的modle

import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt


class Student{
    val name = ObservableField<String>()
    val id = ObservableInt()
    val sex = ObservableField<String>()
}

我们之前的Java代码是有Javabean这个概念的,但是kotlin没有bean这个概念,我们可以用data关键字修饰一个数据类,但是由于我们需要更新,所以我们就用到databinding中的观察者模式来设计数据类。因为考虑到后面要重复的创建对象,我建议大家设计一个对象工厂。如下所示:

class StudentFactory {
    companion object{
        @JvmStatic
        fun getStudent(id:Int,name:String,sex:String):Student{
            val st:Student= Student()
            st.id.set(id)
            st.name.set(name)
            st.sex.set(sex)
            return st
        }
    }
}

工厂的设计并不复杂,我这里使用了kotlin的静态方法,由于kotlin没有static关键字修饰,所以我们用了以上方法把getStudent彻底变成了静态,方便我们的调用

item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="data"
            type="com.yang.databindingdemo.data.Student" />
    </data>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        >
        <TextView
            android:id="@+id/item_id"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="20sp"
            android:layout_marginLeft="10dp"
            android:text="@{String.valueOf(data.id)}"
            />
        <TextView
            android:id="@+id/item_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="20sp"
            android:layout_marginLeft="10dp"
            android:text='@{"    "+data.name,default =名字}'
            />
        <TextView
            android:id="@+id/item_sex"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="20sp"
            android:layout_marginLeft="10dp"
            android:text='@{"    "+data.sex,default =性别}'
            />
    </LinearLayout>
</layout>


现在我们先来看listView



import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ListView
import com.yang.databindingdemo.R
import com.yang.databindingdemo.data.Student
import com.yang.databindingdemo.data.StudentFactory
import com.yang.databindingdemo.listView.adapter.ListViewAdapter

class ListViewActivity : AppCompatActivity() {
    private lateinit var listView: ListView
    private  val list = ArrayList<Student>()
    private lateinit var bt:Button
    private lateinit var add:Button
    private lateinit var adapter: ListViewAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_list_view)
        listView=findViewById(R.id.listView)
        bt = findViewById(R.id.bt_up_lv)
        add = findViewById(R.id.bt_add_lv)
        repeat(5){
            list.add(StudentFactory.getStudent(it,"呃呃呃","男"))
        }
        adapter=ListViewAdapter(list,this)
        listView.adapter = adapter
        bt.setOnClickListener {
            list[0].name.set("嘻嘻嘻")
        }

        add.setOnClickListener {
            list.add(StudentFactory.getStudent(list.size,"哇哇哇","女"))
            adapter.notifyDataSetChanged()
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    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=".listView.ListViewActivity">
<Button
    android:id="@+id/bt_up_lv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="修改数据"
    />
    <Button
        android:id="@+id/bt_add_lv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加数据"
        />
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter

import androidx.databinding.DataBindingUtil
import com.yang.databindingdemo.R
import com.yang.databindingdemo.data.Student

import com.yang.databindingdemo.databinding.ItemBinding

class ListViewAdapter(val list: List<Student>,val context: Context) : BaseAdapter() {
    override fun getCount(): Int =list.size

    override fun getItem(position: Int): Any = list[position]

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int,convertView: View?, parent: ViewGroup?): View {
       val itemBinding: ItemBinding = if (convertView == null){
            DataBindingUtil.inflate(LayoutInflater.from(context),
                R.layout.item,parent,false)
        }else {
            DataBindingUtil.getBinding(convertView)!!
        }
        itemBinding.data = list[position]
        return itemBinding.root
    }
}

和传统的listView一样,做一个页面布局,书写适配器,但是,同学请注意观察getView函数下的代码逻辑,以往我们需要书写大量的代码,还要定义一个UI业务逻辑类来帮助我们进行控件实例化,而现在,完全不用再写那么多重复的代码,彻底告别了findbyId,是不是很激动,下面的RecyclerView更让你激动,我们一起来看吧。


import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yang.databindingdemo.R
import com.yang.databindingdemo.data.Student
import com.yang.databindingdemo.data.StudentFactory
import com.yang.databindingdemo.recycleView.adapter.RecycleViewAdapter

class RecycleViewActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private var list = ArrayList<Student>()
    private lateinit var adapter: RecycleViewAdapter
    private lateinit var add:Button
    private lateinit var update:Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recycle_view)
        recyclerView = findViewById(R.id.recyclerView)
        add = findViewById(R.id.bt_add_rv)
        update = findViewById(R.id.bt_up_rv)
        //设置布局
        recyclerView.layoutManager=LinearLayoutManager(this)
        repeat(5){
            list.add(StudentFactory.getStudent(it,"rv哈哈哈","女"))
        }
        adapter = RecycleViewAdapter(list,this)
        recyclerView.adapter = adapter
        add.setOnClickListener {
            list.add(StudentFactory.getStudent(list.size,"update","男"))
            adapter.notifyDataSetChanged()
        }
        update.setOnClickListener {
            list[1].sex.set("她是女生")

        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    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=".recycleView.RecycleViewActivity">

    <Button
        android:id="@+id/bt_add_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加数据"
        />
    <Button
        android:id="@+id/bt_up_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="修改数据"
        />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
class RecycleViewAdapter(val list: List<Student>, val context: Context)
    :RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>(){

    inner class ViewHolder(val dataBinding: ViewDataBinding):RecyclerView.ViewHolder(dataBinding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemBinding :ItemBinding = DataBindingUtil.inflate(LayoutInflater.from(context),
            com.yang.databindingdemo.R.layout.item,parent,false)
        return ViewHolder(itemBinding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val binding : ViewDataBinding = holder.dataBinding
        binding.setVariable(1,list[position])
    }

    override fun getItemCount(): Int = list.size
}

recyclerView的适配器只用了十几行代码就完全实现,这在我们使用Java语言书写的时候是不能想象的,我们用更低耦合的代码实现了自己想要的功能,是不是想想就很开心了。

好了,今天就到这里,如果代码有什么问题,欢迎大家下方留言,我每天都在关注哟。

源码地址,我上传到csdn了,没有设置积分,大家可以随意参考

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值