首先listview 布局,这是一个fragment的layout,通过binding 自动注入!
fragment_yao_ce.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="yaoCeAdapter" type="android.widget.BaseAdapter"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_yaoce_view"
app:adapter="@{yaoCeAdapter}"/>
</LinearLayout>
</layout>
对应 fragment 代码 kotlin:
var mContext : Context = context
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var fragmentYaoCeBinding : FragmentYaoCeBinding = FragmentYaoCeBinding.inflate(inflater,
container, false)
//初始化 空list data
var mListYaoCeData : List<YaoCe> = ArrayList<YaoCe>()
//初始化 空的 属性展示 list
var listViewProperty : MutableList<ItemThreeProperty> = ArrayList<ItemThreeProperty>()
//添加title信息
var itemThreeProperty = ItemThreeProperty()
itemThreeProperty.indexNum = "序号"
itemThreeProperty.strPropertyOne = "数值"
itemThreeProperty.strPropertyTwo = "代号描述"
itemThreeProperty.strPropertyThree = "信息"
listViewProperty.add(itemThreeProperty)
var adapter : ListAdapter<ItemThreeProperty> = ListAdapter<ItemThreeProperty>(mContext, listViewProperty,
R.layout.linear_text_three_item, BR.itemThree)
val model = ViewModelProviders.of(this)[YaoCeViewModel::class.java]
//做数据绑定和监听
model.getYaoCe().observe(this, Observer<List<YaoCe>>{ yaoceList ->
// update UI, data change
if (yaoceList != null && yaoceList.isNotEmpty()){
mListYaoCeData = yaoceList
var listProperty = DataBeanToViewUtil.ListYaoCeBean2View(mListYaoCeData)
for (property in listProperty) {
listViewProperty.add(property)
}
adapter.notifyDataSetChanged()
}
})
//设置adapter 变量
fragmentYaoCeBinding.setVariable(BR.yaoCeAdapter, adapter)
//返回 view root
return fragmentYaoCeBinding.root
}
对应viewmodel+livedata
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.daobo.wand.data.bean.SOE
import com.daobo.wand.data.bean.YaoCe
import kotlin.concurrent.thread
/**
* 遥测
* @author xiaolong.li
* @time 2020-02-14
*/
class YaoCeViewModel : ViewModel() {
var list : MutableList<YaoCe> = ArrayList<YaoCe>()
//遥测信息
private val listYaoCeData: MutableLiveData<List<YaoCe>> by lazy {
MutableLiveData<List<YaoCe>>().also {
loadData()
}
}
/**
* 获取数据
*/
fun getYaoCe() : LiveData<List<YaoCe>> {
return listYaoCeData
}
private fun loadData() {
// Do an asynchronous operation to fetch data.
//写死数据
thread(start = true) {
for(i in 1..30){
val yaoCe = YaoCe()
yaoCe.strMsg = "遥测 test"
yaoCe.strValue = "10"
yaoCe.numDesc = "点数"
list.add(yaoCe)
}
listYaoCeData.postValue(list)
}
}
fun refreshData() {
thread(start = true) {
val yaoCe = YaoCe()
yaoCe.strMsg = "遥测 fresh add"
yaoCe.strValue = "10"
yaoCe.numDesc = "点数"
list.add(yaoCe)
listYaoCeData.postValue(list)
}
}
}
对应的 listview item 布局:统一使用的ItemTwoProperties bean,这就是为什么在fragment中,有一个bean 转换。
<?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="itemTwo" type="com.daobo.wand.data.viewbean.ItemTwoProperty"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/num"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintHorizontal_weight="0.8"
app:layout_constraintRight_toLeftOf="@+id/textOne"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center_horizontal"
android:background="@drawable/item_text_backgroud">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{itemTwo.indexNum}"
android:textColor="@color/colorGray"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/textOne"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintRight_toLeftOf="@+id/textTwo"
app:layout_constraintLeft_toRightOf="@+id/num"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center_horizontal"
android:background="@drawable/item_text_backgroud">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{itemTwo.strPropertyOne}"
android:textColor="@color/colorGray"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/textTwo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintLeft_toRightOf="@+id/textOne"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center_horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{itemTwo.strPropertyTwo}"
android:textColor="@color/colorGray"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
ListAdapter 代码:
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 androidx.databinding.ViewDataBinding
// ListView 适配器 DataBindingUtil
/**
* 统一的 list binding adapter
* @author xiaolong.li
* @time 2020-02-14
*/
class ListAdapter<T>(
private val context: Context, private val list: List<T>,
private val layoutId: Int, private val variableId: Int) : BaseAdapter() {
override fun getCount(): Int {
return list.size
}
override fun getItem(position: Int): Any {
return list[position]!!
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var binding: ViewDataBinding? = null
if (convertView == null) {
binding = DataBindingUtil.inflate(LayoutInflater.from(context), layoutId, parent, false)
} else {
binding = DataBindingUtil.getBinding(convertView)
}
binding!!.setVariable(variableId, list[position])
return binding.root
}
}