一、前言
经常需要自定义FragmentPagerAdapter,发现代码大同小异,只是实例化了不同的 fragment。所以写了这样一个类,以 fragment 的类(.class)为参数,用反射去实例化 fragment。这样一来,不需要每次都自定义一个 FragmentPagerAdapter,只需一条语句。
二、源码
public class CommonFragmentAdapter extends FragmentPagerAdapter{
private List<Class<? extends Fragment>> fragmentClasses;
private List<Fragment> fragments;
public CommonFragmentAdapter(FragmentManager fm, List<Class<? extends Fragment>> fragmentClasses) {
super(fm);
this.fragmentClasses = fragmentClasses;
this.fragments = new ArrayList<Fragment>(Collections.<Fragment>nCopies(fragmentClasses.size(), null));
}
@Override
public Fragment getItem(int position) {
if (fragments.get(position) == null){
Fragment newlyCreateFragment = null;
try {
newlyCreateFragment = fragmentClasses.get(position).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
fragments.set(position, newlyCreateFragment);
}
return fragments.get(position);
}
@Override
public int getCount() {
return fragmentClasses.size();
}
}
三、sample
ViewPager obtainImgViewPager = (ViewPager) findViewById(R.id.vp_obtain_img);
List<Class<? extends Fragment>> fragmentClasses = new ArrayList<Class<? extends Fragment>>();
fragmentClasses.add(CameraFragment.class);
fragmentClasses.add(GalleryFragment.class);
FragmentPagerAdapter obtainImgFragmentAdapter = new CommonFragmentAdapter(getSupportFragmentManager(), fragmentClasses);
obtainImgViewPager.setAdapter(obtainImgFragmentAdapter);
四、弯路
想当然的以为 new ArrayList(int initialCapacity)可以创建一个大小为 initialCapacity,各个元素为默认值的 ArrayList。事实上,它只创建了一个空的 ArrayList。(更别提把各个元素设为默认值了)后来,我这样做了。
for (int i = 0; i < fragmentClasses.size(); i++) {
fragments.add(null);
}
后来,我发现,我做繁了。Java 容器有个好用的 API,如下。
public static <T> List<T> nCopies(int n, T o) Returns an immutable list consisting of n copies of the specified object. The newly allocated data object is tiny (it contains a single reference to the data object). This method is useful in combination with the List.addAll method to grow lists. The returned list is serializable.