【发布时间】:2020-09-12 15:02:40
【问题描述】:
我仍在尝试使用视图模型,现在有点困惑,因为我也有一个对话框和 recyclerview 项目,但如果我能得到任何帮助,我会尽量在这里尽可能清楚。
我有一个包含项目的对话框,当其中一个被选择并关闭时,应该将数据返回到我的调用片段,以便所选项目显示在该视图下。
但是,一旦选择了该项目并关闭了对话框,我就不会看到新的选定项目显示在 UI 上,而是旧项目。 (当第一次启动片段时,它会显示在我的列表中设置为选中的项目。所选值最初是硬编码的,但在单击项目时会更新,当我在里面调试 viewmodel 观察者时,我可以看到更新已经发生对话框的 onDismiss 方法)。
我在这方面花了几个小时,并尝试了一些不同的事情,例如在 onResume 或 onDismiss 中调用 viewmodel 并根据 this post 更改要启动的 viewmodel by by activityViewModels() 但这些都没有奏效远,我想我现在被困住了。下面是我最新版本的代码。
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)
}
}
非常感谢。
【问题讨论】:
-
您的活动代码在哪里?在您的活动中首先声明 viewModel。然后 CovidCheckInFragment 和 MyDialogFragment 将获得 viewModel ref,因为您使用的是 activityViewModels()。这意味着 CovidCheckInFragment 和 MyDialogFragment 将使用同一个 VM 来共享和侦听数据
-
嗨!抱歉,不知道也需要在活动中包含代码?有没有办法避免这种情况?我想我已经很困惑管理这四个类了..
-
我已经为我的活动更新了一些简化版本的帖子。谢谢。
-
我想我现在已经能够在父片段和对话框之一上用这个
private val viewModel: MainViewModel by viewModels( { requireParentFragment() } )替换 activityViewModels 了。 -
现在只需要弄清楚如何在对话框关闭后立即查看此更新,因为目前我需要离开片段并返回它以进行更改.
标签: android android-fragments viewmodel android-dialogfragment android-viewmodel