【发布时间】:2021-06-10 05:35:09
【问题描述】:
-
我正在尝试使用
ListAdapter在回收站视图中执行更新和删除操作。对于这个例子,我使用LiveData在数据更新后立即获取更新。 -
我不知道为什么列表没有显示更新的数据,但是当我看到日志时它显示正确的数据。
代码:
@AndroidEntryPoint
class DemoActivity : AppCompatActivity() {
var binding: ActivityDemoBinding? = null
private val demoAdapter = DemoAdapter()
private val demoViewModel: DemoViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDemoBinding.inflate(layoutInflater)
setContentView(binding?.root)
initData()
}
private fun initData() {
binding?.apply {
btnUpdate.setOnClickListener {
demoViewModel.updateData(pos = 2, newName = "This is updated data!")
}
btnDelete.setOnClickListener {
demoViewModel.deleteData(0)
}
rvData.apply {
layoutManager = LinearLayoutManager(this@DemoActivity)
adapter = demoAdapter
}
}
demoViewModel.demoLiveData.observe(this, {
it ?: return@observe
demoAdapter.submitList(it)
Log.d("TAG", "initData: $it")
})
}
}
activity_demo.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.DemoActivity">
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="Update Data" />
<Button
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="Delete Data" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/btn_update" />
</RelativeLayout>
演示适配器:
class DemoAdapter() : ListAdapter<DemoModel, DemoAdapter.DemoViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DemoViewHolder {
val binding =
ListItemDeleteBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return DemoViewHolder(binding)
}
override fun onBindViewHolder(holder: DemoViewHolder, position: Int) {
val currentItem = getItem(position)
holder.bind(currentItem)
}
inner class DemoViewHolder(private val binding: ListItemDeleteBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(student: DemoModel) {
binding.apply {
txtData.text = student.name + " " + student.visible
if (student.visible) txtData.visible()
else txtData.inVisible()
}
}
}
class DiffCallback : DiffUtil.ItemCallback<DemoModel>() {
override fun areItemsTheSame(oldItem: DemoModel, newItem: DemoModel) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: DemoModel, newItem: DemoModel) =
(oldItem.id == newItem.id) &&
(oldItem.visible == newItem.visible) &&
(oldItem.name == newItem.name)
}
}
DemoViewModel:
class DemoViewModel : ViewModel() {
var demoListData = listOf(
DemoModel(1, "One", true),
DemoModel(2, "Two", true),
DemoModel(3, "Three", true),
DemoModel(4, "Four", true),
DemoModel(5, "Five", true),
DemoModel(6, "Six", true),
DemoModel(7, "Seven", true),
DemoModel(8, "Eight", true)
)
var demoLiveData = MutableLiveData(demoListData)
fun updateData(pos: Int, newName: String) {
val listData = demoLiveData.value?.toMutableList()!!
listData[pos].name = newName
demoLiveData.postValue(listData)
}
fun deleteData(pos: Int) {
val listData = demoLiveData.value?.toMutableList()!!
listData.removeAt(pos)
demoLiveData.postValue(listData)
}
}
【问题讨论】:
-
我认为这可以帮助你。 stackoverflow.com/questions/49726385/…
-
我很困惑,为什么您的活动中有 LiveData?那应该在 viewModel 中。
areContentsTheSame也很懒...我会做oldItem.something == newItem.something && oldItem.otherThing == newItem.otherThing等...不仅仅是比较整个项目(这可能会导致意外的错误,具体取决于您的用例) -
好的,我看到你说“为了简单起见,你没有使用 VM”。但是我在您的代码中没有看到...(我还没有喝咖啡)分配给 RecyclerView 的适配器在哪里?在底部......您的代码在“顺序”方面有点奇怪。您的“简单性”导致它更难遵循,因为不执行 ViewModel 等(实际上最多需要 10 分钟来设置),您违反了约定,所以答案是“我没有知道发生了什么”。
-
UNRELATED:
lateinit var delAdapter: DeleteAdapter不需要这样做,你可以这样做val adapter = DeleteAdapter()在你将它附加到 RV 之前它不会做任何事情(你应该在绑定东西之后做,但是它如果你有特定的理由可以等待,我不会)。
标签: android kotlin android-recyclerview listadapter