Android FragmentPagerAdapter和FragmentStatePagerAdapter
我目前正在考虑应该使用PagerAdapter的哪个实现。 他们两人都面临困境。让我给你看看这些是什么 1#碎片页雷达 工作正常,当以前的实例不可用时,它创建新的片段实例,并在有机会时检索以前的片段 我最近在StackOverflow上读到,方法Android FragmentPagerAdapter和FragmentStatePagerAdapter,android,performance,android-viewpager,fragmentpageradapter,fragmentstatepageradapter,Android,Performance,Android Viewpager,Fragmentpageradapter,Fragmentstatepageradapter,我目前正在考虑应该使用PagerAdapter的哪个实现。 他们两人都面临困境。让我给你看看这些是什么 1#碎片页雷达 工作正常,当以前的实例不可用时,它创建新的片段实例,并在有机会时检索以前的片段 我最近在StackOverflow上读到,方法PagerAdapter的getItem()方法仅在需要创建片段时才被调用,但是-它被反复调用,我必须在该方法的主体中创建新实例并检索旧实例 但是,只调用了很少的回调和生命周期方法。例如,我无法设法调用onSaveInstanceState。所以无法保存
PagerAdapter的
getItem()
方法仅在需要创建片段时才被调用,但是-它被反复调用,我必须在该方法的主体中创建新实例并检索旧实例
但是,只调用了很少的回调和生命周期方法。例如,我无法设法调用onSaveInstanceState
。所以无法保存片段的状态-当然我可以使用SharedReferences
或其他方法,但我想使用回调方法。有没有办法做到这一点
2#碎片状态页雷达
工作正常,保存ViewPager
保存的每个片段的状态
但是-这个PagerAdapter
总是创建新的片段。我在里面检查过了
这不是效率低下吗?我在Google I/O materials上看到Romain Guy说,创建新的视图
是没有效率的,特别是当我们在列表视图
中创建大量的视图时,所以我们使用转换视图
检索现有的视图
,并根据我们的需要多次更改它。所以页面之间的翻转非常相似——许多新的视图
——因为片段是某种视图
在这两个PagerAdapters
中,我尝试了覆盖destroyItem()
方法的技巧,但根本不起作用
这是我的问题
我该怎么办
我应该将SharedReferences
和选项1与FragmentPagerAdapter
一起使用,还是将选项2与FragmentStatePagerAdapter
一起使用
有没有可能,我在这些适配器中做错了什么,导致它们的行为不符合我们的预期
下面是我的代码,分为“可读”部分
PagerAdapter第1部分:
PagerAdapter第3部分:
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;
}
}
我在onPageSelectedMethod
中出错-我强制FragmentStatePagerAdapter调用getItem
-每当页面更改时,该方法至少实例化一次片段-方法。这就是为什么我抱怨每次页面更改时都要实例化片段:)
我应该在那里调用我的getFragmentAt()
方法,而不是getItem()
,整个回调应该是这样的
@Override
public void onPageSelected(int pageNumber) {
wizardActivity.stepFragment.setCurrentStepAndChangeText(pageNumber);
if(pageNumber != prevPageNumber){
AbstractWizardFragment prevFragment = (AbstractWizardFragment) getFragmentAt(prevPageNumber);
prevFragment.onDetachedFromViewPager(wizardActivity.mForm);
}
AbstractWizardFragment currFragment = (AbstractWizardFragment) getFragmentAt(pageNumber);
currFragment.onAttachedToViewPager(wizardActivity.mForm);
prevPageNumber = (short) pageNumber;
Log.d("WizardActivity", "onPageSelected");
}
虽然它很好用。仍然可能存在这样的风险,即找不到片段
,并且该方法将返回null,然后将抛出NPE
@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");
}
}
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;
}
}
@Override
public void onPageSelected(int pageNumber) {
wizardActivity.stepFragment.setCurrentStepAndChangeText(pageNumber);
if(pageNumber != prevPageNumber){
AbstractWizardFragment prevFragment = (AbstractWizardFragment) getFragmentAt(prevPageNumber);
prevFragment.onDetachedFromViewPager(wizardActivity.mForm);
}
AbstractWizardFragment currFragment = (AbstractWizardFragment) getFragmentAt(pageNumber);
currFragment.onAttachedToViewPager(wizardActivity.mForm);
prevPageNumber = (short) pageNumber;
Log.d("WizardActivity", "onPageSelected");
}