我目前正在将ViewPager
和TabLayout
用于几个类似的片段。 ViewPager中托管的片段都有一个RecyclerView
。当我在一页上滑动时,碎片(我认为?)被破坏了。当我向后滑动时,它已重新创建。
在调试时,我发现Fragment中的适配器为非null,并填充了之前的数据。但是,一旦该片段可见,它将不再显示任何条目。
这是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显示的?它填充了数据,这就是为什么我很困惑。
答案 0 :(得分:1)
尝试对setOffscreenPageLimit
使用ViewPager
来保持包含以下片段:
viewPager.setOffscreenPageLimit(NavigationPageAdapter.NUM_PAGES)
答案 1 :(得分:0)
我已经解决了问题。尽管setOffScreenPageLimit(NavigationAdapter.NUM_PAGES)
可以正常工作,但出于对内存消耗的考虑,我谨慎使用它。
事实证明,使用lazy
存储对视图的引用是不好的做法。由于onCreateView
在ArtistListFragment
的生命周期中被调用过多次,因此未引用同一视图,该视图当前在屏幕上膨胀。
删除所有lazy
实例化视图并使用Android扩展程序直接访问它们解决了我的问题。