RecyclerView в ViewPager не заполнен, несмотря на то, что адаптер содержит данные - PullRequest
0 голосов
/ 09 сентября 2018

В настоящее время я использую ViewPager и TabLayout для пары похожих фрагментов. Все фрагменты, размещенные в ViewPager, имеют RecyclerView. Когда я пролистываю более одной страницы, фрагмент (я думаю?) Уничтожается. Когда я провожу назад, это воссоздано.

После отладки я обнаружил, что адаптер во фрагменте не равен нулю и заполнен данными из ранее. Однако, как только фрагмент виден, он больше не отображает записи.

Вот видео того, что происходит. 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 голосов
/ 09 сентября 2018

Я понял проблему. Хотя setOffScreenPageLimit(NavigationAdapter.NUM_PAGES) сработало, я осторожно его использую из-за проблем с использованием памяти.

Оказывается, хранение ссылок на представления с использованием lazy - плохая практика. Поскольку onCreateView вызывается много раз в жизненном цикле ArtistListFragment, на него не ссылалась та же самая точка зрения, которая в настоящее время раздувалась на экране.

Удаление всех lazy созданных экземпляров представлений и прямой доступ к ним с помощью расширений Android решило мою проблему.

0 голосов
/ 09 сентября 2018

Попробуйте использовать setOffscreenPageLimit для ViewPager, чтобы сохранить фрагменты, как показано ниже:

viewPager.setOffscreenPageLimit(NavigationPageAdapter.NUM_PAGES)
...