Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android PagerAdapter.notifyDataSetChanged不刷新片段_Android_Android Viewpager_Android Pageradapter - Fatal编程技术网

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();