如何解决binding.list.addAll不适用于数据绑定,也使用binding.executePendingBindings,但用户界面未更新
我是数据绑定的新手。我的例子很简单,我在recyclerview中添加了一些静态数据,并且在单击按钮一段时间后,我在recyclerview中添加了其他数据,
所以,第一次列表大小为0时,它工作正常,第二次添加数据,我将addAll()
与executePendingBindings()
一起使用,但不会在ui中反映新数据。
if(binding.list?.size==0){
binding.list = it
}else{
binding.list?.addAll(it)
}
binding.executePendingBindings()
所以,但是如果我使用,那么没有executePendingBinding()
if(binding.list?.size==0){
binding.list = it
}else{
var old_newdata:ArrayList<Person> = (binding?.list!!+it) as ArrayList<Person>
binding.list = old_newdata
}
那是为什么?我不明白为什么不使用addAll()和executependingbinding()?
MainActivity.kt:
class MainActivity : AppCompatActivity(),ListActionHandler {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
binding.viewModel = viewModel
binding.list = ArrayList()
binding.itemclickHandler = this
startObserving()
}
private fun startObserving() {
Handler().postDelayed(Runnable {
var mutableList = ArrayList<Person>()
mutableList.add(Person("Mansi Shah","User001",""))
mutableList.add(Person("Muuni Shah","User002",1,""))
mutableList.add(Person("Alpa Shah","User003",""))
mutableList.add(Person("Solani Shah","User004",""))
mutableList.add(Person("Menka Shah","User005",""))
mutableList.add(Person("Misri Shah","User006",""))
mutableList.add(Person("Moti Shah","User007",""))
mutableList.add(Person("Khevana Shah","User008",""))
//binding.list?.addAll(mutableList)
viewModel.setListData(mutableList)
},10000)
viewModel.mutablelistData?.observe(this,Observer {
it?.let {
//binding.list = it
if (binding.list?.size == 0) {
binding.list = it
} else {
// todo: working without execute binding and without addAll,but with =
// var old_newdata:ArrayList<Person> = (binding?.list!!+it) as ArrayList<Person>
// binding.list = old_newdata
//todo : Not working with execute binding,so need to notify adapter
//binding.list?.addAll(it)
//binding.executePendingBindings()
val startposition = binding.list!!.size
binding.list?.addAll(it)
binding.rvPerson.adapter?.notifyItemRangeChanged(startposition,it.size)
}
}
})
}
override fun btnClick(position: Int) {
val item = binding.list?.get(position)
item?.let {
when (item.follow_status) {
0 -> {
val item1 = binding.list?.get(position)?.copy(follow_status = 1)
viewModel.mutablelistData.value?.set(position,item1!!)
binding.rvPerson.adapter?.notifyItemChanged(position,item1!!)
//binding.rvPerson.adapter?.notifyDataSetChanged()
}
1 -> {
val item1 = binding.list?.get(position)?.copy(follow_status = 0)
viewModel.mutablelistData.value?.set(position,item1!!)
// viewModel.mutablelistData.value?.set(position,item1!!)
}
else -> {
val item1 = binding.list?.get(position)?.copy(follow_status = 0)
viewModel.mutablelistData.value?.set(position,item1!!)
}
}
}
}
override fun btnAddClick() {
var mutableList = ArrayList<Person>()
mutableList.add(Person("Denma Shah","User009",""))
mutableList.add(Person("Irish Shah","User0010",""))
mutableList.add(Person("Mangolia Shah","User0011",""))
mutableList.add(Person("Lily Shah","User0012",""))
mutableList.add(Person("Bloom Shah","User0013",""))
mutableList.add(Person("Iva Shah","User0014",""))
mutableList.add(Person("Ishika Shah","User0015",""))
mutableList.add(Person("Oliver Shah","User0016",""))
//old data
// mutableList.addAll(viewModel.getListData())
viewModel.setListData(mutableList)
}
}
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<import type="java.util.ArrayList"/>
<variable
name="viewModel"
type="com.example.databindingdemo.viewmodel.MainViewModel" />
<variable
name="list"
type="ArrayList<com.example.databindingdemo.model.Person>" />
<variable
name="itemclickHandler"
type="com.example.databindingdemo.actionhandler.ListActionHandler" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnAdd"
style="@style/buttonTheme"
android:background="@color/colorPrimaryDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick="@{(v)->itemclickHandler.btnAddClick()}"
android:text="ADD"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnNext"
style="@style/buttonTheme"
android:background="@color/colorPrimaryDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Next"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvPerson"
app:layout_constraintTop_toBottomOf="@+id/btnAdd"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
bind:list="@{list}"
bind:clickHandler="@{itemclickHandler}"
android:visibility="@{list!=null && list.size()>0? View.VISIBLE:View.GONE}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<TextView
android:id="@+id/no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Data in List !!!"
android:visibility="@{list!=null && list.size()>0? View.GONE:View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
ListDataAdpater.kt:
class ListDataAdpater(
private val listData: ArrayList<Person>,private val clickHandler: ListActionHandler
) : RecyclerView.Adapter<ListDataAdpater.ViewHolder>() {
private var binding: ListItemDataBinding? = null
inner class ViewHolder(val binding: ListItemDataBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
setIsRecyclable(true)
}
fun bind(data: Person) {
binding?.listItemData = data
binding?.clickHandler = clickHandler
}
}
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewHolder {
binding = ListItemDataBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return ViewHolder(binding!!)
}
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
holder.bind(listData[position])
holder.binding.position = position
}
override fun getItemCount(): Int {
return listData.size
}
}
list_item.xml:
<?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"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="listItemData"
type="com.example.databindingdemo.model.Person" />
<variable
name="clickHandler"
type="com.example.databindingdemo.actionhandler.ListActionHandler" />
<variable
name="position"
type="int" />
</data>
<!-- <LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/_10sdp"
android:orientation="vertical"
android:visibility="gone"/>-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:padding="@dimen/_2sdp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/imgUserSeach"
android:layout_width="@dimen/_58sdp"
android:layout_height="@dimen/_58sdp"
android:adjustViewBounds="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
bind:roundedCornersRad="@{`3`}"
bind:url="@{listItemData==null?``:listItemData.url}" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="@dimen/_5sdp"
android:paddingEnd="@dimen/_5sdp"
android:weightSum="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgUserSeach"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="2">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@font/montserrat_medium"
android:letterSpacing="0.02"
android:lineSpacingExtra="8sp"
android:lines="1"
android:text="@{listItemData.full_name}"
android:textColor="@android:color/white"
android:textSize="13.3sp"
tools:text="Mansi Shah" />
<!-- android:onClick="@{(v)->searchItemHandler.onItemClick(searchData)}"-->
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvUserName"
android:layout_marginTop="@dimen/_8sdp"
android:ellipsize="end"
android:fontFamily="@font/montserrat_medium"
android:letterSpacing="0.02"
android:lineSpacingExtra="11.3sp"
android:lines="1"
android:text="@{listItemData.username}"
android:textColor="#80ffffff"
android:textSize="10sp"
tools:text="User001" />
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvUserName"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/btnFollow"
style="@style/buttonTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@{listItemData.follow_status == 0?@drawable/cyan_button: @drawable/grey_button}"
android:ellipsize="end"
android:lineSpacingExtra="4.5sp"
android:lines="1"
android:onClick="@{(v)->clickHandler.btnClick(position)}"
android:text="@{listItemData.follow_status == 0? @string/follow : @string/following}" />
</RelativeLayout>
</LinearLayout>
<View
android:id="@+id/vdivider"
android:layout_width="match_parent"
android:layout_height="@dimen/_1sdp"
android:layout_marginTop="@dimen/_10sdp"
android:background="#8b9096"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imgUserSeach" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
BindAdapters.kt:
@JvmStatic // add this line !!
@BindingAdapter(value = ["bind:list","bind:clickHandler"],requireAll = false)
fun bindAdapter(view: RecyclerView,list: ArrayList<Person>?,handler: ListActionHandler) {
list?.let {
val adapter = ListDataAdpater(list,handler)
view.adapter = adapter
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com(将#修改为@)