【发布时间】:2020-05-26 09:21:59
【问题描述】:
我有自定义的ViewPager 和PagerAdapter,它们在instantiateItem 中加载项目。如果我第一次使用设置的项目列表初始化它,它工作正常。
但是当我在列表上调用刷新并且我想用新的(完全不同的)列表填充适配器时,在调用 viewPager.adapter?.notifyDataSetChanged() 之后,PagerAdapter 停止正常工作并且这些项目是没有内容的空白页面,我可以在它们中滑动用户界面。
PageScreen 不是Fragment。它只是 ViewGroup 容器,它正在膨胀布局并设置特定项目的值。类似于RecyclerView中的ViewHolder + Binder。
当我添加新列表并调用notifyDataSetChanged() 时,instatiateItem() 也只被调用一次。开始时它被称为 3 个项目,即第一个列表中 PageScreen 个项目的数量。
//init
val pages = mutableListOf<PageScreen>()
pages.add(PageScreen(activity, app, itemJs1, onClick = {onItemClicked(itemJs1.id)}))
pages.add(PageScreen(activity, app, itemJs2, onClick = {onItemClicked(itemJs2.id)}))
pages.add(PageScreen(activity, app, itemJs3, onClick = {onItemClicked(itemJs3.id)}))
swipePager.adapter = CustomPagerAdapter(pages).also { it.notifyDataSetChanged() }
...
//on refresh after API call
pages.clear()
contentList.forEach{item-> pages.add(PageScreen(activity, app, item, onClick = {onItemClicked(item.id)}))}
(swipePager.adapter as? CustomPagerAdapter)?.notifyDataSetChanged()
也试过这个(结果相同):
//on refresh after API call
val newPages = mutableListOf<PageScreen>()
contentList.forEach{item-> newPages.add(PageScreen(activity, app, item, onClick = {onItemClicked(item.id)}))}
swipePager.adapter = CustomPagerAdapter(newPages).also { it.notifyDataSetChanged() }
适配器:
class CustomPagerAdapter(private var pageList: MutableList<PageScreen>) : PagerAdapter() {
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
override fun getCount(): Int {
return pageList.size
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
override fun instantiateItem(container: ViewGroup, position: Int): View {
val layout = pageList[position].getScreen(container)
container.addView(layout)
return layout
}
}
我还尝试通过从 ViewPager contentView 中删除它们并为每个项目调用 instantiateItem() 来正确刷新项目(我希望这是由 PagerAdapter 和 ViewPager 在我调用 notifyDataSetChanged() 时在内部完成的)。但是结果和上面一样。现在每一页都是空白的。 CustomPagerAdapter添加以下功能。
fun refreshItems(vp: ViewPager, data: MutableList<PageScreen>){
pageList.apply {
forEachIndexed{pos, item->
item.screenView?.let { sv->
destroyItem(vp, pos, sv)
}
}
clear()
addAll(data)
forEachIndexed { pos, _ -> instantiateItem(vp, pos) }
}
notifyDataSetChanged()
}
更新:
我设法通过将 ViewPager 高度设置为固定值而不是 WRAP_CONTENT 来“解决”这个问题,但这不是解决方案。我想要具有动态高度的 ViewPager,因为它的一些子级可以有不同的高度 + 将某些东西设置为静态在 Android 中不是好方法。一些带有方形显示屏的手机可能会裁剪页面。
发生的事情是,当我替换所有项目时,那些“空白”页面是具有 0px 高度和 0px 宽度的项目,原因不明。
如果我将 ViewPager 高度替换为 dp 值,它“有效”。但是当我替换那些视图时,第一项总是空白。但是当我滚动到第三个并返回到第一个时,项目出于某种原因在那里。
我也不知道身高问题。我在 ViewPager 中有函数,它根据列表中最高的孩子设置它的高度。如果列表是静态的,它可以工作,但是当我刷新它时它现在不起作用。
【问题讨论】:
标签: android kotlin android-viewpager android-pageradapter