Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android FragmentPagerAdapter和FragmentStatePagerAdapter_Android_Performance_Android Viewpager_Fragmentpageradapter_Fragmentstatepageradapter - Fatal编程技术网

Android FragmentPagerAdapter和FragmentStatePagerAdapter

Android FragmentPagerAdapter和FragmentStatePagerAdapter,android,performance,android-viewpager,fragmentpageradapter,fragmentstatepageradapter,Android,Performance,Android Viewpager,Fragmentpageradapter,Fragmentstatepageradapter,我目前正在考虑应该使用PagerAdapter的哪个实现。 他们两人都面临困境。让我给你看看这些是什么 1#碎片页雷达 工作正常,当以前的实例不可用时,它创建新的片段实例,并在有机会时检索以前的片段 我最近在StackOverflow上读到,方法PagerAdapter的getItem()方法仅在需要创建片段时才被调用,但是-它被反复调用,我必须在该方法的主体中创建新实例并检索旧实例 但是,只调用了很少的回调和生命周期方法。例如,我无法设法调用onSaveInstanceState。所以无法保存

我目前正在考虑应该使用PagerAdapter的哪个实现。 他们两人都面临困境。让我给你看看这些是什么

1#碎片页雷达

工作正常,当以前的实例不可用时,它创建新的片段实例,并在有机会时检索以前的片段

我最近在StackOverflow上读到,方法
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");
}