对话框关闭后,ViewModel仍显示旧数据,父片段返回查看 [英] ViewModel still displaying old data after dialog dismissed and parent fragment back to view

查看:79
本文介绍了对话框关闭后,ViewModel仍显示旧数据,父片段返回查看的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我还拥有一个对话框和recyclerview项,因此我仍在努力处理视图模型,这有点困惑,但是如果可以得到任何帮助,我会在这里尽可能地清楚.

I'm still trying to wrap my head around working with viewmodels and a bit confused now that I also have a dialog and recyclerview items but will try to be as clear as I can here if I can get any help please.

我有一个对话框,其中的项目被选中并关闭时,应将数据返回到我的调用片段,以便所选项目显示在该视图下.

I have a dialog with items that when one of them is selected and closed should return data to my calling fragment so the selected item is displayed under that view.

但是,一旦选择了该项目并关闭了对话框,我就看不到新选择的项目是UI上显示的项目,而是旧项目.(当片段首次启动时,它会显示设置为列表中所选项目的项目.所选值最初是硬编码的,但是在单击该项目时会更新,并且当我在其中调试viewmodel观察器时,我看到更新已进行对话框的onDismiss方法.

However, once the item is selected and the dialog dismissed, I don't see the new selected item as the one showing on the UI but still the old item instead. (When the fragment is first started it displays the item that is set as selected on my list. The selected value is hardcoded at first but updated when the item is clicked and I can see the update has taken place when I debug the viewmodel observer inside the onDismiss method for the dialog).

我花了几个小时,尝试了一些不同的事情,例如在onResume或onDismiss内调用viewmodel并更改由activityViewModels()由初始化的viewmodel,按照这篇文章,但是到目前为止,这些方法都没有起作用我现在被困住了.在我最新版本的代码下面.

I'm a couple of hours on this and have tried a few different things such as calling the viewmodel inside onResume or onDismiss and changing the viewmodel to be initiated by by activityViewModels() as per this post but none of these have worked so far and I think I'm stuck at the moment. Below my most recent version of the code.

class CovidCheckInFragment : Fragment(R.layout.fragment_covid_check_in) {

var navController: NavController? = null
private val model: MainViewModel by activityViewModels()

@RequiresApi(Build.VERSION_CODES.M)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    navController = Navigation.findNavController(view)
    
    model.userMutableLiveData.observe(viewLifecycleOwner, Observer<Any?> { list ->
        if (list != null)

            (list as Iterable<*>).map {

                if ((it as ModelDialogOption).selected == true) {
                    tvHeader.text = it.title
                }

            }

    })

}

}

..

class MyDialogFragment : DialogFragment(), RecyclerDialogOptionsItem.AdapterListener {

private val viewModel: MainViewModel by activityViewModels()
private lateinit var adapter: GroupAdapter<GroupieViewHolder>
var selectedPosition = -1

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_TITLE, R.style.AppTheme_Dialog_Custom)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_dialog, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    rvOptions.layoutManager = LinearLayoutManager(activity)
    adapter = GroupAdapter()
    rvOptions.adapter = adapter


    ivClose.setOnClickListener {

        this.dismiss()
    }


    initViewModel()
}

private fun initViewModel() {

    viewModel.userMutableLiveData.observe(this, Observer { list ->
        for (i in list!!) {
            adapter.add(
                RecyclerDialogOptionsItem(
                    this@MyDialogFragment,
                    i,
                    this@MyDialogFragment
                )
            )
        }

    })

}

override fun onClickItem(position: Int) {

    selectedPosition = position
    adapter.notifyDataSetChanged()

    Log.i("clicked", "position: $position")
}

}

..

class MainViewModel : ViewModel() {

private var list: ArrayList<ModelDialogOption>? = null

val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()

init {
    populateList()
    userMutableLiveData.value = list!!
}

private fun populateList() {

    list = ArrayList()

    list!!.add(ModelDialogOption("Prefer not to say", false))
    list!!.add(ModelDialogOption("16-39", false))
    list!!.add(ModelDialogOption("40-59", true))
    list!!.add(ModelDialogOption("60+", false))
}

}

..

class RecyclerDialogOptionsItem(
private val fragment: MyDialogFragment,
private val modelDialogOption: ModelDialogOption,
private val adapterListener: AdapterListener
) : Item<GroupieViewHolder>() {

companion object {
    var clickListener: AdapterListener? = null
}

override fun bind(viewHolder: GroupieViewHolder, position: Int) {

    viewHolder.apply {

        with(viewHolder.itemView) {

            tvTitle.text = modelDialogOption.title

            clickListener = adapterListener

            if (fragment.selectedPosition == position) {
                ivChecked.visible()
                modelDialogOption.selected = true

            } else {
                ivChecked.invisible()
                modelDialogOption.selected = false
            }

            itemView.setOnClickListener {

                clickListener?.onClickItem(adapterPosition)

            }

        }

    }

}

override fun getLayout() = R.layout.rv_options_item_row

interface AdapterListener {
    fun onClickItem(position: Int)
}

}

非常感谢您.

推荐答案

您的主视图模型应该是这样的

Your main view model should be like this

class MainViewModel : ViewModel() {

private var list: ArrayList<ModelDialogOption>? = null

val userMutableLiveData = MutableLiveData<ArrayList<ModelDialogOption>>()

init {
    populateList()
    userMutableLiveData.value = list!!
}


private fun populateList() {

    list = ArrayList()

    list!!.add(ModelDialogOption("Prefer not to say", false))
    list!!.add(ModelDialogOption("16-39", false))
    list!!.add(ModelDialogOption("40-59", true))
    list!!.add(ModelDialogOption("60+", false))

}

fun updateItem(position:Int){
    val itemToUpdate = list!!.get(position)
    itemToUpdate.selected = !itemToUpdate.selected!!
    list!![position] = itemToUpdate
}

fun flushItems(){
    userMutableLiveData.value = list!!
}

}

然后来自MyDialogFragment的应该是这样.

Then from MyDialogFragment Should be like this.

class MyDialogFragment : DialogFragment(), RecyclerDialogOptionsItem.AdapterListener {

private val viewModel: MainViewModel by activityViewModels()

private lateinit var adapter: GroupAdapter<GroupieViewHolder>
var selectedPosition = -1

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_TITLE, R.style.AppTheme_Dialog_Custom)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_dialog, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    rvOptions.layoutManager = LinearLayoutManager(activity)
    adapter = GroupAdapter()
    rvOptions.adapter = adapter


    ivClose.setOnClickListener {

        this.dismiss()
    }


    initViewModel()
}

override fun onDismiss(dialog: DialogInterface) {
    super.onDismiss(dialog)
    viewModel.flushItems()
}

private fun initViewModel() {

    viewModel.userMutableLiveData.observe(this, Observer { list ->
        for (i in list!!) {
            adapter.add(
                RecyclerDialogOptionsItem(
                    this@MyDialogFragment,
                    i,
                    this@MyDialogFragment
                )
            )
        }

    })

}


override fun onClickItem(position: Int) {

    selectedPosition = position
    adapter.notifyDataSetChanged()

    viewModel.updateItem(position)
    Log.i("clicked", "position: $position")
}

}

这篇关于对话框关闭后,ViewModel仍显示旧数据,父片段返回查看的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆