我正在考虑使用哪种PagerAdapter的实现方式。我对它们都有些疑虑,让我向您展示一下。
1# FragmentPagerAdapter 运行良好,当没有先前的实例可用时,它会创建新的片段实例,并在有机会时检索先前的片段。
我最近在StackOverflow上读到,只有在需要创建片段时才会调用PagerAdapter的getItem()方法,但是-它会一遍又一遍地调用,我必须在此方法的主体中处理创建新实例和检索旧实例。
但是-只有少数回调和生命周期方法被调用。例如,我无法管理onSaveInstanceState的调用。因此,无法保存片段的状态-当然,我可以使用SharedPreferences或其他东西,但我想使用回调方法。有什么办法可以做到这一点吗?
2# FragmentStatePagerAdapter 完美运行,保存ViewPager持有的每个片段的状态。
但是-这个PagerAdapter总是创建新的片段。我在构造函数中进行了检查。
那不是很低效吗?我在Google I/O材料上看到Romain Guy说,创建新视图并不高效,特别是当我们像在ListView中一样创建大量视图时,我们使用convertView来检索现有视图并将其更改为我们的目的,而且可以根据需要多次执行此操作。因此,在页面之间翻转时非常相似-许多新视图-因为片段是某种视图
在两个PagerAdapters中,我尝试了覆盖destroyItem()方法的技巧,但它根本不起作用。
这是我的问题。
我该怎么做?
我应该使用SharedPreferences和选项#1与FragmentPagerAdapter还是选项#2与FragmentStatePagerAdapter?
有没有可能我在这些适配器中做错了什么,它们的行为不像我们期望的那样?
下面是我的代码分成“可读”部分
PagerAdapter部分#1:
1# FragmentPagerAdapter 运行良好,当没有先前的实例可用时,它会创建新的片段实例,并在有机会时检索先前的片段。
我最近在StackOverflow上读到,只有在需要创建片段时才会调用PagerAdapter的getItem()方法,但是-它会一遍又一遍地调用,我必须在此方法的主体中处理创建新实例和检索旧实例。
但是-只有少数回调和生命周期方法被调用。例如,我无法管理onSaveInstanceState的调用。因此,无法保存片段的状态-当然,我可以使用SharedPreferences或其他东西,但我想使用回调方法。有什么办法可以做到这一点吗?
2# FragmentStatePagerAdapter 完美运行,保存ViewPager持有的每个片段的状态。
但是-这个PagerAdapter总是创建新的片段。我在构造函数中进行了检查。
那不是很低效吗?我在Google I/O材料上看到Romain Guy说,创建新视图并不高效,特别是当我们像在ListView中一样创建大量视图时,我们使用convertView来检索现有视图并将其更改为我们的目的,而且可以根据需要多次执行此操作。因此,在页面之间翻转时非常相似-许多新视图-因为片段是某种视图
在两个PagerAdapters中,我尝试了覆盖destroyItem()方法的技巧,但它根本不起作用。
这是我的问题。
我该怎么做?
我应该使用SharedPreferences和选项#1与FragmentPagerAdapter还是选项#2与FragmentStatePagerAdapter?
有没有可能我在这些适配器中做错了什么,它们的行为不像我们期望的那样?
下面是我的代码分成“可读”部分
PagerAdapter部分#1:
/**
* Adapter class to {@link WizardPager}
*/
public static class WizardCrazyAdapter extends FragmentStatePagerAdapter
implements OnPageChangeListener{
public static final String tag = "android:switcher:"+R.id.pager_w+":";
/**
* Refernece to root activity
*/
WizardActivity wizardActivity;
/**
* list of fragments
*/
private final ArrayList<FragmentInfo> fInfos = new ArrayList<FragmentInfo>();
private short prevPageNumber = 0;
/**
* Constructor of adapter
* @param wizardActivity
* {@link WizardActivity} as reference to activity root
*/
public WizardCrazyAdapter(WizardActivity wizardActivity) {
super(wizardActivity.getSupportFragmentManager());
this.wizardActivity = wizardActivity;
}
static final class FragmentInfo {
private final Class<?> _clss;
private Bundle _args;
public FragmentInfo(Class<?> clss, Bundle args) {
_clss =clss;
_args =args;
}
}
public void addPage(Class<?> clss, Bundle args){
FragmentInfo fi = new FragmentInfo(clss, args);
fInfos.add(fi);
}
/**
* Return number of pages
*/
public int getCount() {
return fInfos.size();
}
PagerAdapter第二部分:
/**
* Searches in {@link FragmentManager} for {@link Fragment} at specified position
* @param position
* @return
*/
private AbstractWizardFragment getFragmentAt(int position){
FragmentManager fm = wizardActivity.getSupportFragmentManager();
AbstractWizardFragment awf = (AbstractWizardFragment) fm.findFragmentByTag(tag+position);
return awf;
}
/**
* Return page of view pager
*/
@Override
public Fragment getItem(int position) {
/*finding existing instance of fragment*/
AbstractWizardFragment awf = getFragmentAt(position);
if(awf == null){
/*creating new instance if no instance exist*/
Log.v("WizardActivity", "creating new Fragment");
FragmentInfo fi = fInfos.get(position);
awf = (AbstractWizardFragment) Fragment.instantiate(wizardActivity, fi._clss.getName());
}else{
Log.v("WizardActivity", "found existing Fragment");
}
return awf;
}
PagerAdapter第三部分:
@Override
public void onPageSelected(int pageNumber) {
wizardActivity.stepFragment.setCurrentStepAndChangeText(pageNumber);
if(pageNumber != prevPageNumber){
AbstractWizardFragment prevFragment = (AbstractWizardFragment) getItem(prevPageNumber);//TODO change if any problems
prevFragment.onDetachedFromViewPager(wizardActivity.mForm);
}
AbstractWizardFragment currFragment = (AbstractWizardFragment) getItem(pageNumber);//TODO change if any problems
currFragment.onAttachedToViewPager(wizardActivity.mForm);
prevPageNumber = (short) pageNumber;
Log.d("WizardActivity", "onPageSelected");
}
@Override
public Object instantiateItem(ViewGroup arg0, int arg1) {
Log.d("WizardActivity", "instantiateItem "+arg1);
return super.instantiateItem(arg0, arg1);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
Log.v("WizardActivity", "that would be destroy");
}
}
ViewPager 代码:
public class WizardPager extends ViewPager{
/**
* Flag to check if view pager must be scrolled
*/
protected boolean isScrollable;
/**
* Default constructor
* @param context {@link Context}
*/
public WizardPager(Context context) {
super(context);
isScrollable = true;
}
/**
* Standard constructor
* @param context {@link Context}
* @param attrs {@link AttributeSet}
*/
public WizardPager(Context context, AttributeSet attrs) {
super(context, attrs);
isScrollable = true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.isScrollable) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.isScrollable) {
return super.onInterceptTouchEvent(event);
}
return false;
}
/**
* Enable scroll of pages
*/
public void enableScroll(){
this.isScrollable = true;
}
/**
* Disable scroll of pages
*/
public void disableScroll(){
this.isScrollable = false;
}
/**
* Check if pages can be scrolled
* @return
*/
public boolean isScrollable(){
return isScrollable;
}
}