本文章实现了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了,没有设置积分,大家可以随意参考