Android listadapter中未调用DiffCallback

Android listadapter中未调用DiffCallback,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,嗨,我正在尝试在我的应用程序中使用listadapter和diffcallback。不知何故,当我做某事时,视图根本不会更新 当我在回调中的“areItemsTheSame”和“areContentsTheSame”中放入一些日志时,根本不会调用它 这是我的主要活动 class MainActivity : AppCompatActivity() { private lateinit var recyclerView: RecyclerView private lateinit var vie

嗨,我正在尝试在我的应用程序中使用listadapter和diffcallback。不知何故,当我做某事时,视图根本不会更新

当我在回调中的“areItemsTheSame”和“areContentsTheSame”中放入一些日志时,根本不会调用它

这是我的主要活动

class MainActivity : AppCompatActivity() {

private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: TodoAdapter
private lateinit var viewManager: RecyclerView.LayoutManager

private lateinit var viewModel : TodoViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

    //viewModel
    viewModel = ViewModelProviders.of(this).get(TodoViewModel::class.java)
    viewManager = LinearLayoutManager(this)
    viewAdapter = TodoAdapter(viewModel.todos)

    binding.btnNew.setOnClickListener {
        viewModel.todos.value!!.add(Todo(3, binding.newText.text.toString()))
    }

    recyclerView = binding.myRecyclerView

    recyclerView.apply {
        layoutManager = viewManager
        adapter = viewAdapter
    }

    viewModel.todos.observe(this, Observer{ list ->
        viewAdapter.submitList(list)
        Log.i("debug", "im @observe " + list.toString())
    })

}
   viewModel.todos.observe(this, Observer{ list ->
        viewAdapter.submitList(list.toMutableList())
    })
}

这是我的适配器

 class TodoAdapter(var items: MutableLiveData<ArrayList<Todo>>):
    ListAdapter<Todo, TodoAdapter.MyViewHolder>(TodoDiffCallback()) {

// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    // create a new view
    val inflater = LayoutInflater.from(parent.context)
    val binding  = ListItemBinding.inflate(inflater)

    return MyViewHolder(binding)
}


override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.todoText.text = getItem(position).task

    //delete
    holder.delBtn.setOnClickListener {
        items.value!!.removeAt(position)
        submitList(items.value)
        Log.i("debug", "@adapter what is items " + items.value.toString())
    }

//override fun getItemCount() = items.value!!.size


class MyViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root) {
    val todoText = binding.todoItem
    val delBtn = binding.btnDelete
    val ediBtn = binding.btnEdit
}
类ToLoadapter(变量项:MutableLiveData):
ListAdapter(TodoDiffCallback()){
//创建新视图(由布局管理器调用)
重写CreateViewHolder(父级:ViewGroup,viewType:Int):MyViewHolder{
//创建新视图
val inflater=LayoutInflater.from(parent.context)
val binding=ListItemBinding.充气(充气机)
返回MyViewHolder(绑定)
}
覆盖onBindViewHolder(holder:MyViewHolder,位置:Int){
holder.todoText.text=getItem(position).task
//删除
holder.delBtn.setOnClickListener{
items.value!!.removeAt(位置)
submitList(items.value)
Log.i(“debug”,“@adapter what is items”+items.value.toString())
}
//重写fun getItemCount()=items.value!!.size
类MyViewHolder(val绑定:ListItemBinding):RecyclerView.ViewHolder(binding.root){
val todoText=binding.todoItem
val delBtn=binding.btnDelete
val ediBtn=binding.btnEdit
}
}

类TodoDiffCallback:DiffUtil.ItemCallback(){
覆盖乐趣项相同(p0:Todo,p1:Todo):布尔值{
Log.i(“debug”,“here”+p0+“inItems”+p1)
返回p0==p1
}
覆盖乐趣内容相同(p0:Todo,p1:Todo):布尔值{
Log.i(“调试”,“此处”+p0+“inContents”+p1)
返回p0.equals(p1)
}
}

我的视图模型

class TodoViewModel: ViewModel() {

val todos = MutableLiveData<ArrayList<Todo>>()

init{
    todos.value = arrayListOf(
        Todo(1, "cooking"),
        Todo(2, "washing")
    )
}
class-TodoViewModel:ViewModel(){
val todos=MutableLiveData()
初始化{
todos.value=arrayListOf(
Todo(1,“烹饪”),
待办事项(2,“清洗”)
)
}
}

不幸的是,android文档没有给出更多的例子

同样,DiffUtil类中的两个“日志”根本没有被调用。当我单击remove按钮时,UI没有更新,但日志显示了正确的结果


感谢当前的工作解决方案

我读过关于“在liveData中观察”的文章,它直到我调用“setValue”方法才被触发

因此,我在ViewModel类中添加了一些新方法,并在其中应用setValue 添加newItem的示例

fun addTodo(text: String) {
    _todos.value!!.add(Todo(3, text))
    _todos.setValue(_todos.value)
}
到目前为止,它是有效的。我现在只运行一次submitList,在我的observe in Main活动中

class MainActivity : AppCompatActivity() {

private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: TodoAdapter
private lateinit var viewManager: RecyclerView.LayoutManager

private lateinit var viewModel : TodoViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

    //viewModel
    viewModel = ViewModelProviders.of(this).get(TodoViewModel::class.java)
    viewManager = LinearLayoutManager(this)
    viewAdapter = TodoAdapter(viewModel.todos)

    binding.btnNew.setOnClickListener {
        viewModel.todos.value!!.add(Todo(3, binding.newText.text.toString()))
    }

    recyclerView = binding.myRecyclerView

    recyclerView.apply {
        layoutManager = viewManager
        adapter = viewAdapter
    }

    viewModel.todos.observe(this, Observer{ list ->
        viewAdapter.submitList(list)
        Log.i("debug", "im @observe " + list.toString())
    })

}
   viewModel.todos.observe(this, Observer{ list ->
        viewAdapter.submitList(list.toMutableList())
    })
我仍然有一个问题,即项目的“位置”仍然不正确。例如:

  • 当我删除所有项目时,应用程序崩溃
  • 在我从第二个位置(数组[1])删除项,然后删除新添加的任务后,它将给出“错误索引超出范围”
  • 因此,onBindViewHolder中的“位置”在删除/或执行其他操作后没有改变
    [更新](通过使用:holder.getAdapterPosition()解决问题)

    我能看看你的视图模型吗?你确定你的列表确实在变化吗?我昨天和你有同样的问题。那是因为你使用的列表在viewmodel中是相同的索引引用。你可以尝试调试并检查adapter和livedata视图模型中的列表。我的解决方案是从实时数据复制数组,然后用不同的reference@RofieSagara我在上面的问题中添加了它,谢谢,在TODO初始设置后,您并没有真正更改TODO的值。为什么会触发diffutils?