RecyclerView Observer,片段不更新数据
RecyclerView Observer, fragment not updating data
My MainFragment contains a RecyclerView of educational paths, when an item is selected it takes the user to CourseFragment with a different RecyclerView of relevant courses.但是,如果用户返回到第一个 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
}
课程视图模型
class CourseViewModel(app: Application): AndroidViewModel(app) {
private val courseDataRepository = CourseRepository(app)
val courseData = courseDataRepository.courseData
val selectedCourse = MutableLiveData<Course>()
}
课程资料库
class CourseRepository(val app: Application) {
val courseData = MutableLiveData<List<Course>>()
init {
CoroutineScope(Dispatchers.IO).launch {
callWebService()
}
}
@WorkerThread
suspend fun callWebService() {
if (Utility.networkAvailable(app)) {
val retrofit = Retrofit.Builder().baseUrl(WEB_SERVICE_URL).addConverterFactory(MoshiConverterFactory.create()).build()
val service = retrofit.create(CourseService::class.java)
val serviceData = service.getCourseData(globalSelectedPath).body() ?: emptyList()
courseData.postValue(serviceData)
}
else
Toast.makeText(app, Resources.getSystem().getString(R.string.noConnectivity), Toast.LENGTH_LONG).show()
}
}
我添加了一些日志并注意到我的存储库仅在应用程序第一次打开时被调用,但再也不会获取数据,因为 callWebService() 再也不会被调用。
12:24:02.520 I/mylog: Course Fragment onCreateView(): selected path = MOB001
12:24:02.529 I/mylog: Course Repository callWebService(): selected path = MOB001
-------------------------------
12:24:35.009 I/mylog: Course Fragment onCreateView(): selected path = WEB999
我添加了一些 http 日志来跟踪数据并确认数据只被检索了一次:
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)
您正在使用 ViewModelProvider(requireActivity()).get(CourseViewModel::class.java)
,这意味着您正在创建范围为整个 activity 的 CourseViewModel
。这意味着在 activity.
的整个生命周期中只会创建一个 CourseViewModel
实例
如果您希望每个片段有一个单独的 CourseViewModel
(因此,一个单独的 CourseRepository
实例),您应该使用 ViewModelProvider(this)
将 ViewModel 的范围限定为片段本身:
viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)
My MainFragment contains a RecyclerView of educational paths, when an item is selected it takes the user to CourseFragment with a different RecyclerView of relevant courses.但是,如果用户返回到第一个 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
}
课程视图模型
class CourseViewModel(app: Application): AndroidViewModel(app) {
private val courseDataRepository = CourseRepository(app)
val courseData = courseDataRepository.courseData
val selectedCourse = MutableLiveData<Course>()
}
课程资料库
class CourseRepository(val app: Application) {
val courseData = MutableLiveData<List<Course>>()
init {
CoroutineScope(Dispatchers.IO).launch {
callWebService()
}
}
@WorkerThread
suspend fun callWebService() {
if (Utility.networkAvailable(app)) {
val retrofit = Retrofit.Builder().baseUrl(WEB_SERVICE_URL).addConverterFactory(MoshiConverterFactory.create()).build()
val service = retrofit.create(CourseService::class.java)
val serviceData = service.getCourseData(globalSelectedPath).body() ?: emptyList()
courseData.postValue(serviceData)
}
else
Toast.makeText(app, Resources.getSystem().getString(R.string.noConnectivity), Toast.LENGTH_LONG).show()
}
}
我添加了一些日志并注意到我的存储库仅在应用程序第一次打开时被调用,但再也不会获取数据,因为 callWebService() 再也不会被调用。
12:24:02.520 I/mylog: Course Fragment onCreateView(): selected path = MOB001
12:24:02.529 I/mylog: Course Repository callWebService(): selected path = MOB001
-------------------------------
12:24:35.009 I/mylog: Course Fragment onCreateView(): selected path = WEB999
我添加了一些 http 日志来跟踪数据并确认数据只被检索了一次:
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)
您正在使用 ViewModelProvider(requireActivity()).get(CourseViewModel::class.java)
,这意味着您正在创建范围为整个 activity 的 CourseViewModel
。这意味着在 activity.
CourseViewModel
实例
如果您希望每个片段有一个单独的 CourseViewModel
(因此,一个单独的 CourseRepository
实例),您应该使用 ViewModelProvider(this)
将 ViewModel 的范围限定为片段本身:
viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)