最近在重写 Kirby Assistant 过程中又遇到了需要动态替换 ViewPager 的某个 Fragment 的需求,因为之前的是直接在同一个布局里暴力替换的,但是这次因为是用其他方法实现的,当然不能用以前的方法了,摸索了一段时间后终于搞定了,现在把可以用的方法放在下面
准备过程
首先需要在布局中添加 ViewPager
1 2 3 4
| <androidx.viewpager.widget.ViewPager android:id="@+id/main_fragment_viewpager" android:layout_width="match_parent" android:layout_height="match_parent"/>
|
然后给 ViewPager 写一个 ViewPagerAdapter 并且继承自 FragmentPagerAdapter
1 2 3
| public class ViewPagerAdapter extends FragmentPagerAdapter {
}
|
具体看代码的注释,有注释的都是需要注意的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| public class ViewPagerAdapter extends FragmentPagerAdapter {
private FragmentManager fm; private List<Fragment> fragments; private List<String> page_title;
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments,List<String> page_title){ super(fm); this.fm=fm; this.fragments=fragments; this.page_title=page_title; }
@NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { if (position == 2||position == 3) removeFragment(container,position); return super.instantiateItem(container, position); }
private void removeFragment(ViewGroup container,int index) { String tag = getFragmentTag(container.getId(), index); Fragment fragment = fm.findFragmentByTag(tag); if (fragment == null) return; FragmentTransaction ft = fm.beginTransaction(); ft.remove(fragment); ft.commit(); ft = null; fm.executePendingTransactions(); }
@NonNull @Override public Fragment getItem(int position) { return fragments.get(position); }
@Override public int getCount() { return fragments.size(); }
@Override public int getItemPosition(@NonNull Object object) { return PagerAdapter.POSITION_NONE; }
@Override public CharSequence getPageTitle(int position) { return page_title.get(position); }
@Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {} private String getFragmentTag(int viewId, int index) { try { Class<FragmentPagerAdapter> cls = FragmentPagerAdapter.class; Class<?>[] parameterTypes = { int.class, long.class }; Method method = cls.getDeclaredMethod("makeFragmentName", parameterTypes); method.setAccessible(true); String tag = (String) method.invoke(this, viewId, index); return tag; } catch (Exception e) { e.printStackTrace(); return ""; } } }
|
注意问题
如果出现替换后出现某个碎片的布局空白了,那就设置一个 ViewPager 的缓存属性
1
| main_fragment_viewpager.setOffscreenPageLimit(4);
|
结尾
如果有代码什么问题可以向我提出