查看模型建筑困境

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

我有三个片段,每个片段都有自己的RecyclerView。如果用户从第一个片段中选择了一个路径,它就会根据用户的选择带他到下一个有相关课程的片段,然后选择一个课程,再到最后一个有相关课程的片段。所以每个RecyclerView都是依赖于前一个RecyclerView的数据。

enter image description here

我为所有的片段使用了共享的ViewModel,但效果并不好,因为当活动开始时,它们都会被初始化,因为数据检索功能在Repository中,而Repository是在ViewModel中初始化的。

我为每个ViewModel使用了一个单独的ViewModel,但效果不好,也是因为数据只在活动开始时被检索一次,而不会再被检索,所以当在片段之间来回浏览时,会出现相同的数据和项目。

如果我只把单个ViewModels的范围扩大到片段,那么后一个片段就不能访问前一个片段所需的数据。

如何使用ViewModel架构来解决这个难题,还是说我应该直接使用SafeArgs来传递数据?

课程ViewModel

class CourseViewModel(app: Application): AndroidViewModel(app) {

    private val courseDataRepository = CourseRepository(app)
    val courseData = courseDataRepository.courseData
    val selectedCourse = MutableLiveData<Course>()
}

CourseFragment.kt

class CourseFragment : Fragment(),
    CourseRecyclerAdapter.CourseItemListener {

    private lateinit var viewModel: CourseViewModel
    private lateinit var recyclerView: RecyclerView
    private lateinit var navController: NavController

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_course, container, false)
        recyclerView = view.findViewById(R.id.courseRecyclerView)
        navController = Navigation.findNavController(requireActivity(), R.id.nav_host )

        viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)
        viewModel.courseData.observe(viewLifecycleOwner, Observer {
            val adapter =
                CourseRecyclerAdapter(
                    requireContext(),
                    it,
                    this
                )
            recyclerView.adapter = adapter
        } )
        return view
    }

这是我之前的共享模型,在我放弃它之前,我有三个片段,每个片段都有自己的RecyclerView。

class SharedViewModel(app: Application): AndroidViewModel(app) {

    private val pathDataRepository = PathRepository(app)
    val pathData = pathDataRepository.pathData
    val selectedPath = MutableLiveData<Path>()

    private val courseDataRepository = CourseRepository(app)
    val courseData = courseDataRepository.courseData
    val selectedCourse = MutableLiveData<Course>()

    private val lessonDataRepository = LessonRepository(app)
    val lessonData = lessonDataRepository.lessonData
    val selectedLesson = MutableLiveData<Lesson>()
}
android android-fragments kotlin android-viewmodel
1个回答
1
投票

如果我的理解没错的话,你可以将片段架构成以下结构。

MainFragment
 - CourseFragment 
 - DetailsFragment 

这个想法是为了让 MainFragment 作为父体,并使用以下方法启动其他两个片段。getChildFragmentManager() 来自 MainFragment 如下所示。

getChildFragmentManager().beginTransaction()
    .replace(R.id.fragment_container, courseFragment)
    .addToBackStack(null).commit();

现在创建一个 ViewModel 对于 MainFragment 和范围,即 ViewModel 到您的生命周期 MainFragment. 这将作为一个共享的工作 ViewModel 对于两个 CourseFragmentDetailsFragment. 您可以访问 ViewModel 范围内的父片段(即 MainFragment),如下所示。

SharedViewModel vm = ViewModelProviders.of(getParentFragment())
                         .get(SharedViewModel.class);

0
投票

按照@sonnet的建议,我通过将数据存储在Room数据库中,然后每当用户输入re-输入任何fragment时就检索数据,从而限制远程数据检索来解决这个问题。

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