首页 > 解决方案 > 使用带有 RecyclerView 的 ViewPager2 并将导航组件用于 RecyclerView 的 onItemClick 的最佳实践

问题描述

我正在使用单个活动,而 MVVM artitechture 它的主要活动仅用于启动器,然后MainFragment从那里我们可以ViewPagerContainerFragment使用导航组件,在那个片段中,我使用 tablayout 设置了 viewpager2,并且在 viewpager2 的每个片段中都有 recyclerview 需要从firebase加载数据,所以一切正常,但问题是当我单击recyclerview中的一个项目时,这会打开另一个片段以获取详细信息,但然后我回来我需要加载所有数据,这些数据看起来有点连线,有时是回收站视图位置已更改,因此如果从详细片段返回,则有一种方法可以保留 vipager2 状态,请参阅下面的代码以获取详细信息

ViewPager2Adapter.kt

class ViewPager2Adapter(viewPagerContainerFragment : ViewPagerContainerFragment)
: FragmentStateAdapter(viewPagerContainerFragment) {

    override fun getItemCount() = 8

    override fun createFragment(position: Int): Fragment = ItemsViewPagerFragment()

}

ItemsViewPagerFragment.kt

class ItemsViewPagerFragment : Fragment(), ItemsViewPagerFragmentListener{

    private val itemsViewPagerFragmentViewModel: ItemsViewPagerFragmentViewModel by viewModels()

    private lateinit var itemsAdapter: ItemsAdapter

    private val refreshing by lazy { itemsViewPagerFragmentViewModel.refreshing }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.itemsviewpager_fragment, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initSwipeRefreshLayout()
    }

    private fun initSwipeRefreshLayout() {

        refreshing.value = false

        refreshing.observe(viewLifecycleOwner) {
            swipeRefreshLayout.isRefreshing = it
        }

        swipeRefreshLayout.setOnRefreshListener {           
               refreshData()      
        }

    }

    override fun onResume() {
        super.onResume()
        getData()
    }

    private fun getData() {

        if (!::itemsAdapter.isInitialized) {
            refreshing.value = true
            initItemsAdapter()
        }

        showRecyclerView()

    }

    private fun initItemsAdapter() {

        itemsViewPagerFragmentViewModel.getItemsLiveData()

        itemsAdapter = ItemsAdapter(
            emptyList(),
            ItemsClickListener()
        )
    }

    private fun refreshData() {
        if (!::itemsAdapter .isInitialized) initItemsAdapter()
        else itemsViewPagerFragmentViewModel.getItemsLiveData()
    }

    private fun showRecyclerView() {
        if (isAdded) {

            recyclerView.apply {
                setHasFixedSize(true)
                layoutManager =
                    if (DeviceOrientationUtil.isLandscape(requireContext()))
                        StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
                    else LinearLayoutManager(context)

                adapter = itemsAdapter

                viewPagerFragmentViewModel.itemsLiveData.observe(viewLifecycleOwner) {

                        itemsAdapter.updateData(it)

                        refreshing.value = false
                    }

                }

            }

        }
    }

    private inner class ItemsClickListener : ItemsViewHolder.ItemsClickListener {
        override fun onItemClick(item: Item) {
            findNavController().navigate(R.id.action_itemsViewPagerFragment_to_itemDetailFragment)
        }
    }
}

ItemsViewPagerFragmentViewModel.kt

class ItemsViewPagerFragmentViewModel : ViewModel() {

    private val itemsRepository = ItemsRepository()

    val refreshing = MutableLiveData<Boolean>()

    lateinit var itemsLiveData: ItemsLiveData

    var isDataCached = false

    fun getItemsLiveData() {
        itemsLiveData = itemsRepository.getitemsLiveData()
    }

}

标签: androidandroid-recyclerviewandroid-architecture-navigationandroid-viewpager2

解决方案


推荐阅读