Android PagerAdapter.notifyDataSetChanged不刷新片段
我的Android PagerAdapter.notifyDataSetChanged不刷新片段,android,android-viewpager,android-pageradapter,Android,Android Viewpager,Android Pageradapter,我的活动包含一个ViewPager,它是一个自定义的适配器,扩展了FragmentStatePagerAdapter查看页面包含3个片段 从ViewPager中删除片段的代码 main活动 public void deleteElement(){ final int currentItem = mViewPager.getCurrentItem(); mPagerAdapter.removeItem(currentItem); mPagerAdapter.notifyDa
活动
包含一个ViewPager
,它是一个自定义的适配器
,扩展了FragmentStatePagerAdapter
<代码>查看页面包含3个片段
从ViewPager中删除片段的代码
main活动
public void deleteElement(){
final int currentItem = mViewPager.getCurrentItem();
mPagerAdapter.removeItem(currentItem);
mPagerAdapter.notifyDataSetChanged();
}
CustomPagerAdapter
private ArrayList<Item> data;
public void removeItem(int index){
data.remove(index);
}
私有数组列表数据;
公共void removietem(int索引){
数据删除(索引);
}
删除中间的片段时(索引1):
- 从
数据中
我正在删除正确的项
李>
- 问题是,我(我猜)
Fragment
3在notifydatasetchange
之后被删除,当前的Fragment
仍然是用户看到的片段,正在加载的数据来自SavedInstance
捆绑包
因此,最终结果是用户仍然看到他试图删除的相同的片段,这对他来说有点糟糕
想法
*****编辑****
似乎可以解决此问题和许多其他问题尝试添加以下内容:
private class MyPagerAdapter extends FragmentStatePagerAdapter {
//... your existing code
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
}
您别无选择,只能实现PagerAdapter#getItemPosition
。查看源代码,这正是ViewPager确定如何在notifyDataSetChanged
之后更新其位置、添加新片段或删除死片段的方式。这应该不会太难,您只需要访问所传递片段的状态,还需要访问活动中的主状态,该状态保存您的排序
还需要实现getItemId
为每个片段返回一致的ID,因为它们可以重新排序
这就是我在照片浏览页面中处理它的方式
private inner class PhotoPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): PhotoViewFragment {
// getItem is called to instantiate the fragment for the given page.
return PhotoViewFragment.newInstance(position, this@PhotoPagerActivity.photos[position])
}
override fun getItemId(position: Int): Long {
return this@PhotoPagerActivity.photos[position].ID!!.hashCode().toLong()
}
override fun getItemPosition(`object`: Any): Int {
val frag = `object` as PhotoViewFragment
val idx = this@PhotoPagerActivity.photos.indexOfFirst { ph -> ph.ID == frag.dataBinding.photo.ID }
return if (idx >= 0) idx else PagerAdapter.POSITION_NONE
}
override fun getCount(): Int {
return this@PhotoPagerActivity.photos.size
}
}
您可以尝试使用FragmentPagerAdapter而不是FragmentStatePagerAdapter。问题是,我也遇到了这个问题,这对我很有帮助。您必须先将适配器设置为null,然后再将其设置回:
int currentPosition = mViewPager.getCurrentItem();
mPagerAdapter.notifyDataSetChanged();
mViewPager.setAdapter(null);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(currentPosition);
您可以尝试使用FragmentStatePagerAdapter而不是FragmentPagerAdapter
公开的
这是我的工作 我知道这个问题有点老了,但知道谷歌最近用它解决了这个问题可能会很有趣。参见示例
首先,在build.gradle文件中添加以下依赖项:
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
}
现在,您可以将xml文件中的ViewPager替换为:
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
为了删除数据,从集合中删除项目后,您可以调用notifyDataSetChanged()
方法,或者更具体地说,调用带有删除项目位置的notifyItemRemoved()
,但这将导致安卓重新启动所有我的片段,这是一种毫无意义的否,其他选项我知道这两个选项,我在提问之前看过这些帖子。问题是我不是在更新视图,而是在删除一个视图。我不能确定哪个视图将被删除,因此按标签调用fragment不是真正安全的(可能它已经被破坏了?我应该更新所有其他片段吗?)感谢它为我所做的工作:Extendes FragmentStatePagerAdapterI我建议切换到,由它来处理这个问题。我并不觉得奇怪,FragmentStatePagerAdapter
在这方面有问题,这就是为什么我把一些东西分开。尝试好的简单解决方案:@gnB这不是这个问题的解决方案单行解决方案应该发布在comment.int getItemPosition(Object Object){return POSITION\u NONE;}请添加一个如何删除数据的示例,我将批准您的回答。谢谢我刚刚编辑了我的答案以显示如何删除该项。我还在适配器中添加了getItemId方法,适配器可能需要它来监视更改。根据getItemId(int)
的JavaDoc,您还应该重写containsItem(long)
重写时,还应该重写{@link#containsItem(long)}。
public class TabAdapter extends FragmentStateAdapter {
private final List<Tab> tabs;
public TabAdapter(@NonNull FragmentManager fm, List<Tab> tabs, Lifecycle lifecycle) {
super(fm, lifecycle);
this.tabs = tabs;
}
@NonNull
@Override
public Fragment createFragment(int position) {
//create your fragment here
}
@Override
public int getItemCount() {
return tabs.size();
}
@Override
public long getItemId(int position) {
// use a distinct id for each item to allow the adapter to see the changes
}
}
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.OnConfigureTabCallback() {
@Override
public void onConfigureTab(@NotNull TabLayout.Tab tab, int position) {
// configure your tab here
tab.setText(tabs.get(position).getTitle());
}
});
tabLayoutMediator.attach();