尽管适配器包含数据,但仍未填充ViewPager中的RecyclerView

时间:2018-09-09 03:08:26

标签: android android-fragments android-recyclerview kotlin android-viewpager

我目前正在将ViewPagerTabLayout用于几个类似的片段。 ViewPager中托管的片段都有一个RecyclerView。当我在一页上滑动时,碎片(我认为?)被破坏了。当我向后滑动时,它已重新创建。

在调试时,我发现Fragment中的适配器为非null,并填充了之前的数据。但是,一旦该片段可见,它将不再显示任何条目。

以下是发生的事情的视频。 enter image description here

这是ViewPager中的片段

class ArtistListFragment : Fragment(), ListView {

    override val title: String
        get() = "Artists"

    private val artistList: RecyclerView by lazy { artist_list }
    @Inject lateinit var api: SaddleAPIManager

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

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

        artistList.apply {
            setHasFixedSize(true)
            if (adapter == null) {
                adapter = ViewTypeAdapter(mapOf(AdapterConstants.ARTIST to ArtistDelegateAdapter()))
            }
            layoutManager = LinearLayoutManager(context)
            if (savedInstanceState != null && savedInstanceState.containsKey("artist")) {
                (adapter as ViewTypeAdapter).setItems(savedInstanceState.getParcelableArrayList<Artist>("artists"))
            }
        }

        (activity?.application as SaddleApplication).apiComponent.inject(this)
        refreshData()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putParcelableArrayList(
                "artists",
                (artistList.adapter as ViewTypeAdapter).items as ArrayList<out Parcelable>
        )
    }

    private fun refreshData() = launch(UI) {
        val result = withContext(CommonPool) { api.getArtists() }
        when(result) {
            is Success -> (artistList.adapter as ViewTypeAdapter).setItems(result.data.results)
            is Failure -> Snackbar.make(artistList, result.error.message ?: "Error", Snackbar.LENGTH_LONG).show()
        }
    }

}

这是托管ViewPager的片段

class NavigationFragment : Fragment() {

    private val viewPager: ViewPager by lazy { pager }
    private val tabLayout: TabLayout by lazy { tab_layout }

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewPager.apply {
            adapter = NavigationPageAdapter(childFragmentManager)
        }

        tabLayout.apply {
            setupWithViewPager(viewPager)
        }
    }
}

我用于分页的适配器

class NavigationPageAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {

    companion object {
        const val NUM_PAGES = 4
    }

    private val pages: List<Fragment> = (0 until NUM_PAGES).map {
        when (it) {
            0 -> ArtistListFragment()
            1 -> AlbumListFragment()
            2 -> TrackListFragment()
            else -> PlaylistListFragment()
        } as Fragment
    }

    override fun getItem(position: Int): Fragment = pages[position]

    override fun getCount(): Int = NUM_PAGES

    override fun getPageTitle(position: Int): CharSequence? = (pages[position] as ListView).title
}

我尝试覆盖onSaveInstanceState并从包中读取信息。它似乎什么也没做。问题似乎实际上是RecyclerView显示的?它填充了数据,这就是为什么我很困惑。

2 个答案:

答案 0 :(得分:1)

尝试对setOffscreenPageLimit使用ViewPager来保持包含以下片段:

viewPager.setOffscreenPageLimit(NavigationPageAdapter.NUM_PAGES)

答案 1 :(得分:0)

我已经解决了问题。尽管setOffScreenPageLimit(NavigationAdapter.NUM_PAGES)可以正常工作,但出于对内存消耗的考虑,我谨慎使用它。

事实证明,使用lazy存储对视图的引用是不好的做法。由于onCreateViewArtistListFragment的生命周期中被调用过多次,因此未引用同一视图,该视图当前在屏幕上膨胀。

删除所有lazy实例化视图并使用Android扩展程序直接访问它们解决了我的问题。