Fragment 不显示从 BottomSheetFragment(房间 + Viewmodel)完成的更新

问题描述 投票:0回答:1

我有 ToDoList 应用程序,当我按回收器的项目时,底部片断(ModifyFragment)显示我选择的任务来进行修改工作。但自从我离开 Home Fragment 并重新创建以来,更新过程尚未完成。但是如果我离开应用程序并再次返回(当 oncreate 再次工作时),我可以看到我的更改。我正在分享我的代码:

My TaskViewModel ( which is sharedviewmodel for both my home fragment and my bottom sheet fragment : 

@HiltViewModel
class TaskViewModel @Inject constructor(private var tRepo: TaskRepository) : ViewModel() {

    val notesList = MutableLiveData<List<Task>>()


    init {
        loadAllTask()
    }

     fun loadAllTask() {
        CoroutineScope(Dispatchers.Main).launch {
            notesList.postValue(tRepo.getAllTask())
        }
    }

    fun delete(task: Task) = CoroutineScope(Dispatchers.Main).launch {
        tRepo.delete(task)
        loadAllTask()
    }

    fun update(task: Task) = CoroutineScope(Dispatchers.Main).launch{
        tRepo.update(task)
    }

     fun search(searchText : String)   = CoroutineScope(Dispatchers.Main).launch {
         notesList.value = tRepo.search(searchText)
     }

}

我的底页片段:

class ModifyFragment(val task: Task) : BottomSheetDialogFragment() {

    private lateinit var binding: FragmentModifyBinding
    private val viewModel: TaskViewModel by activityViewModels()
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        binding = FragmentModifyBinding.inflate(inflater, container, false)


        val date = task.date
        val priority = task.priority
        val taskCurrent = task.task

        binding.date.text = date
        binding.task.setText(taskCurrent)
        binding.add.setOnClickListener {
            val task = Task(task.id,priority,binding.task.text.toString(),task.date,task.isDone)
            viewModel.update(task)
            dismiss()
        }

        return binding.root
    }
}

首页片段:

@AndroidEntryPoint
class HomeFragment : Fragment() {

    private lateinit var binding: FragmentHomeBinding
    private lateinit var viewmodel: TaskViewModel
  
 

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = FragmentHomeBinding.inflate(inflater, container, false)


        val snapHelper = LinearSnapHelper()
        snapHelper.attachToRecyclerView(binding.recyclerDays)

        binding.fab.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.toSave)
        }
        
        binding.search.setOnQueryTextListener(object : OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                query?.let { viewmodel.search(it) }
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                newText?.let { viewmodel.search(it) }
                return true
            }
        })

        val adapter = TaskAdapter(requireContext(), emptyList(), viewmodel, this)
        binding.recyclerTask.adapter = adapter
        viewmodel.notesList.observe(viewLifecycleOwner) {
            Log.e("tag","observer")
            adapter.updateList(it)
        }

        return binding.root
    }

此外,我也想共享我的适配器,我使用了 updateList 方法(也许问题就是这样),因为当我想创建新任务时,视图模型没有观察我的更改。适配器:

class TaskAdapter(private val mContext : Context, private var list : List<Task>, private val viewModel: TaskViewModel, private val fragment : Fragment) : RecyclerView.Adapter<TaskAdapter.TaskDesignHolder>(){


    inner class TaskDesignHolder( val binding : TaskItemBinding) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskDesignHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = TaskItemBinding.inflate(inflater,parent,false)
        return TaskDesignHolder(binding)
    }
    override fun getItemCount(): Int {
        return list.size
    }
    override fun onBindViewHolder(holder: TaskDesignHolder, position: Int) {

        val b = holder.binding
        val itemlist = list[position]

        b.task.text = itemlist.task
        b.time.text = itemlist.date
        if (itemlist.isDone){
            b.task.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG
            b.time.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG
            b.checkbox.isChecked = true
        }
        b.root.setOnClickListener{
            if (!itemlist.isDone) {
                val bottomSheetFragment = ModifyFragment(itemlist)
                bottomSheetFragment.show(fragment.childFragmentManager, bottomSheetFragment.tag)
            }
            else{
                Toast.makeText(mContext,"You can't modify finished tasks.",Toast.LENGTH_SHORT).show()
            }
        }

        b.priority.backgroundTintList = when(itemlist.priority){
            "Low" -> ContextCompat.getColorStateList(mContext, R.color.green)
            "Medium" -> ContextCompat.getColorStateList(mContext, R.color.yellow)
            "High" -> ContextCompat.getColorStateList(mContext, R.color.red)
            else -> ContextCompat.getColorStateList(mContext, R.color.green)

        }

        b.delete.setOnClickListener {
            viewModel.delete(itemlist)
        }

        b.checkbox.setOnCheckedChangeListener { _, isChecked ->
            if (isChecked){
                b.task.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG
                b.time.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG
                val task = Task(itemlist.id,itemlist.priority,itemlist.task,itemlist.date,true)
                viewModel.update(task)
            }
            else{
                b.task.paintFlags = 0
                b.time.paintFlags = 0
                val task = Task(itemlist.id,itemlist.priority,itemlist.task,itemlist.date,false)
                viewModel.update(task)
            }
        }



    }
    fun updateList(list : List<Task>){
        this.list = list
        notifyDataSetChanged()
    }
}

我尝试使用 OnResume 获取数据,并在更新函数中调用 loadAllTask 来再次检索。没有工作。

android kotlin fragment android-room viewmodel
1个回答
0
投票

我发现您的 VM 和 DI 存在一些问题,这里应该归咎于前者。您的 TaskViewmodel 未在 HomeFragment 中实例化。 您应该以与第一个片段相同的方式实例化它。

private val viewModel:由activityViewModels()创建的TaskViewModel

如果您打算将对象注入其中,您还应该记住使用 @AndroidEntryPoint 注释您的片段。否则你的应用程序可能会崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.