RecyclerView заполняет данные из ViewModel только после изменения ориентации - PullRequest
1 голос
/ 22 апреля 2020

Я использую NavigationDrawer и пробую архитектуру MVVM, все макеты были в порядке, затем я реализовал RecyclerView, который отображает данные из Firebase в одном из фрагментов.

Ошибки не отображаются, но RecyclerView не заполняет данные. Я добавил запись в приложение, обнаружил, что адаптер возвращает размер, data != null, но, что интересно, recyclerView заполняет данные только об изменениях конфигурации устройства, таких как ориентация устройства

Переключение между фрагментами и возврат к фрагменту RecyclerView: та же проблема снова, пока я не поверну устройство

1 2 3 on switching back after switching back

Я пробовал:

  • отодвигая процесс от ссылки на onCreateView

  • , изменяющие источник данных на фиктивный набор, и он работает

  • , отображая данные на терминале, и он печатает данные

HomeFragment

...
class HomeFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel

    lateinit var recyclerView: RecyclerView

    lateinit var swipeRefresh: SwipeRefreshLayout

    lateinit var postAdapter: PostAdapter

    val viewModelFactory = HomeViewModelFactory()



    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {

        val view = inflater.inflate(R.layout.fragment_home, container, false)
    homeViewModel = ViewModelProviders.of(this, viewModelFactory).get(HomeViewModel::class.java)


        recyclerView  = view.findViewById(R.id.post_recycler_view)
        recyclerView.setHasFixedSize(true)
        val linearLayoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, true)
        linearLayoutManager.stackFromEnd = true

        recyclerView.layoutManager = linearLayoutManager

        // Observe the model
        homeViewModel.postList.observe(this@HomeFragment, Observer { posts ->

            postAdapter = PostAdapter(context!!, posts)
            recyclerView.adapter = postAdapter
            postAdapter.notifyDataSetChanged()

            homeViewModel.myRef.keepSynced(true)
        })

        swipeRefresh = view.findViewById(R.id.swiperefresh)

        swipeRefresh.setOnRefreshListener {

            Toast.makeText(context, " Adapter size: ${postAdapter.itemCount}", Toast.LENGTH_LONG).show() // works : returns 12
            println("list:${homeViewmodel.postList.value} ") works : prints data

            swipeRefresh.isRefreshing = false
        }

        return view
    }

viewModel

class HomeViewModel() : ViewModel() {

var postList = loadPosts()

fun loadPosts(): MutableLiveData<MutableList<Post>> {

        val postList = mutableListOf<Post>()
        val l_postList = MutableLiveData<MutableList<Post>>()

        firebaseRepo.retrievePosts(postList)

       l_postList.value =  postList


        return l_postList
    }
}

firebaseRepo

       fun retrievePosts(postList: MutableList<Post>) {

        val postsRef = ref.child("Posts")

        postsRef.addValueEventListener(object : ValueEventListener{
            override fun onCancelled(p0: DatabaseError) {}

            override fun onDataChange(p0: DataSnapshot) {
                postList.clear()

                for(snapshot in p0.children){
                    val post = snapshot.getValue(Post::class.java)

                    postList.add(post!!)


                    }
                }
        })
    }

1 Ответ

1 голос
/ 22 апреля 2020

Ваш метод retrievePosts изменяет только MutableList<Post> в postList, а не MutableLiveData<MutableList<Post>> в l_postList, поэтому RecyclerView никогда не уведомляется об изменении. MutableLiveData может обнаруживать изменения, которые происходят только путем установки его value.

. Вы должны обновить метод retrievePosts, чтобы получить ссылку на MutableLiveData и установить value этого MutableLiveData об изменениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...