RecyclerView Observer, фрагмент не обновляет данные - PullRequest
1 голос
/ 03 мая 2020

Мой MainFragment содержит RecyclerView образовательных путей, при выборе элемента он переводит пользователя в CourseFragment с другим RecyclerView соответствующих курсов. Однако, если пользователь возвращается к первому 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>()
}

Репозиторий курсов

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)

1 Ответ

3 голосов
/ 04 мая 2020

Вы используете ViewModelProvider(requireActivity()).get(CourseViewModel::class.java), что означает, что вы создаете CourseViewModel для всей деятельности. Это означает, что будет только один экземпляр CourseViewModel, созданный для всего времени жизни действия.

Если вы хотите отдельный CourseViewModel (и, следовательно, отдельный CourseRepository экземпляр) для каждого фрагмента, Вы должны использовать ViewModelProvider(this), чтобы охватить ViewModel для самого фрагмента:

viewModel = ViewModelProvider(this).get(CourseViewModel::class.java)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...