我的activity
包含一个ViewPager
和它的自定义适配器
,该适配器扩展了FragmentStatePagerAdapter
。ViewPager
包含3个片段
从ViewPager中删除片段的代码
MainActivity
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);
}
删除中间的片段
(索引1)时:
数据
中删除正确的项
。NotifyDataSetChanged
之后,我(我猜)fragment
3被删除,当前的片段
仍然是用户看到的片段,并且正在加载的数据来自SavedInstance
包所以最终结果是,用户仍然看到他试图删除的相同的片段
,这对他来说有点糟糕。
想法?
*****编辑******
似乎ViewPager2的特性可以解决这个问题以及许多其他问题
我知道这个问题有点老了,但是知道Google最近用ViewPager2解决了这个问题可能会很有趣。请参阅此处的示例
首先,在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" />
则需要在activity中将ViewPager替换为ViewPager2
ViewPager2需要RecycleView.Adapter或FragmentStateAdapter:
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
}
}
在使用TabLayout的情况下,可以使用TabLayoutMediator:
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();
为了移除数据,从集合中移除项后,您可以调用NotifyDataSetChanged()
方法,或者更具体地说,调用具有移除项位置的NotifyItemRemoved()
尝试添加以下内容:
private class MyPagerAdapter extends FragmentStatePagerAdapter {
//... your existing code
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
}
您别无选择,只能实现PagerAdapter#GetItemposition
。查看源代码,这正是ViewPager确定如何在NotifyDataSetChanged
之后更新其位置,添加新片段或删除已死亡片段的方式。这应该不会太难,您只需要访问传递的片段的状态,并且您还需要访问保存您的排序的activity中的主状态。
还需要实现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
}
}