我的Activity
包含ViewPager
及其自定义Adapter
,其中包含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);
}
删除中间Fragment
(索引1)时:
data
我删除了正确的item
。 Fragment
3在notifyDataSetChanged
之后删除,当前Fragment
仍然是用户看到的片段,正在加载的数据来自SavedInstance
捆绑包因此,最终结果是用户仍然看到他试图删除的Fragment
,这对他来说有点糟糕。
想法?
答案 0 :(得分:26)
尝试添加此内容:
private class MyPagerAdapter extends FragmentStatePagerAdapter {
//... your existing code
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
}
答案 1 :(得分:4)
您别无选择,只能实施PagerAdapter#getItemPosition
。查看ViewPager确定如何更新其位置的来源,在notifyDataSetChanged
之后添加新片段或删除死片段。它不应该太难,你只需要访问传递的片段的状态,你还需要访问活动中的主状态,它保存你的订单。
它还要求您实现getItemId
以返回每个片段的一致ID,因为它们可以重新排序。
这是我在ViewPager照片中处理它的方式。
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
}
}
答案 2 :(得分:1)
我知道这个问题有点老了,但是知道Google最近用ViewPager2解决了这个问题可能会很有趣。查看示例here
首先,在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" />
然后您需要在活动中将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()
并指定已删除项目的位置
答案 3 :(得分:0)
您可以尝试使用FragmentPagerAdapter而不是FragmentStatePagerAdapter。问题是,我也遇到过这个问题,它帮助了我。
答案 4 :(得分:0)
您必须首先将适配器设置为null,然后再将其重新设置:
Processed Vade Retro 01.394.21 AS+AV+AP+RT Profile: OVH; Bailout: 300; ^ForbiddenHdr (500)
答案 5 :(得分:0)
区分Fragment,然后android系统会负责回收这些Fragment。
例如 - 覆盖 getItemId 提供唯一 ID。
FragmentStateAdapter (ViewPager2) - Kotlin 版本。
class HomeViewPagerAdapter(
fa: FragmentActivity
) : FragmentStateAdapter(fa) {
lateinit var fragments: ArrayList<Fragments>
override fun getItemCount(): Int {
return fragments.size
}
override fun getItemId(position: Int): Long {
return fragments[position].id.ordinal.toLong()
}
override fun createFragment(position: Int): Fragment {
return fragments[position].fragment
}
}
data class Fragments (val id: FragmentId, val fragment: Fragment)
enum class FragmentId {
PageOne,
PageTwo,
PageThree
}
更新适配器
private fun setupAdapter(fragments: ArrayList<Fragments>) {
if (adapter != null) {
adapter?.fragments = fragments
adapter?.notifyDataSetChanged()
} else {
adapter = HomeViewPagerAdapter(requireActivity())
adapter?.fragments = fragments
binding.homeViewPager.adapter = adapter
binding.locationDisabledLl.setOnClickListener {
findNavController().navigate(HomeFragmentDirections.actionHomeToPermission())
}
}
}
答案 6 :(得分:-1)
您可以尝试使用FragmentStatePagerAdapter代替FragmentPagerAdapter public
它对我有用..!