Android RecyclerView不更新项目

Android RecyclerView不更新项目,android,android-fragments,kotlin,android-recyclerview,Android,Android Fragments,Kotlin,Android Recyclerview,MainFragment包含路径的RecyclerView,当用户选择其导航到CourseFragment的路径时,该路径包含相关课程的RecyclerView。但是,如果用户返回选择不同的路径,则每次都会显示相同的课程项目 课程片段 class CourseFragment : Fragment(), CourseRecyclerAdapter.CourseItemListener { private lateinit var viewModel: CourseViewMo

MainFragment包含路径的RecyclerView,当用户选择其导航到CourseFragment的路径时,该路径包含相关课程的RecyclerView。但是,如果用户返回选择不同的路径,则每次都会显示相同的课程项目

课程片段

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? {
        Log.i(LOG_TAG, "Course Fragment onCreateView(): selectedItem = $globalSelectedPath")

        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(requireActivity()).get(CourseViewModel::class.java)
        viewModel.courseData.observe(viewLifecycleOwner, Observer {
            val adapter =
                CourseRecyclerAdapter(
                    requireContext(),
                    it,
                    this
                )
            recyclerView.adapter = adapter
        } )
        return view
    }
CourseViewModel

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

    private val courseDataRepository = CourseRepository(app)
    val courseData = courseDataRepository.courseData
    val selectedCourse = MutableLiveData<Course>()
}
为了确保我创建了callWebService()的Okhttp侦听器日志,该日志确认数据只提取了一次:

    12:24:02.551 D/OkHttp: --> GET https://.../mobile/feed/course_data.php?pathName=MOB001
    12:24:02.551 D/OkHttp: --> END GET
    12:24:03.007 D/OkHttp: <-- 200 https://.../mobile/feed/course_data.php?pathName=MOB001 (455ms)
    12:24:03.007 D/OkHttp: date: Sat, 02 May 2020 09:24:03 GMT
    12:24:03.007 D/OkHttp: server: Apache
    12:24:03.007 D/OkHttp: x-powered-by: PHP/5.6.40
    12:24:03.007 D/OkHttp: vary: Accept-Encoding
    12:24:03.007 D/OkHttp: content-type: text/html; charset=UTF-8
    12:24:03.009 D/OkHttp: [{"courseName":"Android App Development Essentials","instructor":"John Lennon","courseDescription":"Description ...","courseImage":"android_development_essentials.jpg","instructorImage":"john.jpg"}]
    12:24:03.009 D/OkHttp: <-- END HTTP (206-byte body)
12:24:02.551 D/ok http:-->获取https://.../mobile/feed/course_data.php?pathName=MOB001
12:24:02.551 D/OkHttp:-->结束获取

12:24:03.007 D/OkHttp:ViewModelProvider(requirectivity())导致检索以前的视图模型,因为视图模型存储保留对以前创建的视图模型的引用,如果需要,请再次提供它。您应该将片段作为视图模型存储所有者而不是活动提供。此外,如果您不需要在其他地方使用相同的课程列表,我认为您的存储库设计是不正确的,每当创建课程列表片段时,您应该使用相应的参数调用该方法,以便从服务器检索适当的数据。

问题很可能是因为观察者没有得到更新。您可以通过getViewLifeCycleOwner()或getViewLifeCycleLiveData()使用片段的视图生命周期,这样每次片段被销毁时,LiveData都会删除观察者。

结果如下:

viewModel = ViewModelProvider(requireActivity()).get(CourseViewModel::class.java)
我使用了
requireActivity()
,它将我的片段的视图模型范围限定到活动生命周期,因此当应用程序(以及活动)首次启动时,RecyclerView将正确更新,但在片段之间来回导航时不会再次更新

因此,为了解决这个问题,我将
requireActivity()
替换为
this
,这意味着viewmodel的作用域仅限于它所在的片段,因此每当用户输入并重新输入片段时,RecyclerView都会更新

viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)

我认为您的
课程片段
不是每次都创建视图,或者另一个机会是您的
视图模型的
数据仍然存在,而不是显示以前的数据。如何从课程选择中打开课程片段?我想如果用户在主片段中选择了一个路径,并且课程片段应该显示结果,那么服务如何知道哪个是路径?我在callWebService中看不到路径,只使用WEB_SERVICE_URL构建改装实例,但使用any路径,因此服务如何知道哪个是所选课程?@Manuel Mato,我目前在一个单独的文件中使用一个项目级变量(globalSelectedVaible)来存储路径,它在函数onPathItemClick()val serviceData=service.getCourseData(globalSelectedPath).body()的第一个片段中初始化:?:emptyList()导航组件可以阻止片段重新创建,因此请检查主片段是否重新创建视图,因为如果未重新创建视图,然后用当前方法无法获取更多数据。我明白你的意思,你可能是正确的,但是,我传入了RequirePreentFragment()而不是RequireResponsibility(),但仍然存在相同的问题。关于存储库设计,我同意我应该将path参数传递给存储库,但我需要创建一个工厂类,这是我在解决这个问题后的意图。您可以尝试这一点,而不需要父片段,因为在您的情况下,它可能为null或指向相同的问题。我还想知道在哪里调用callWebService()方法?callWebService()是在coroutines块内的CourseSpository中调用的。
viewModel = ViewModelProvider(requireActivity()).get(CourseViewModel::class.java)
viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)