2

我有一个 FragmentPagerAdapter,它通过自定义 SurveyPage 类生成的视图进行分页。寻呼机中的最后一页由 SurveyFinishPage 生成,它尝试访问与 FragmentPagerAdapter 关联的调查并将所有调查答案拉在一起以显示它们。SurveyFinishPage 通过主 Activity 中的 getSurvey() 方法获取 Survey 对象。

通常这可以正常工作,并且 SurveyFinishPage 能够访问 FragmentPagerAdapter 正在使用的同一个调查对象。但是,如果 Activity 已被杀死并恢复,SurveyFinishPage 似乎仍在访问旧的调查(或者可能是它的副本) - 它显示在 Activity 被丢弃之前的答案,无论对新的、重建的答案的更改如何民意调查。

似乎在我的 MainActivity 中的 onRestoreInstanceState() 中恢复 aSurvey 的值应该为其他所有内容建立调查对象,因为 MainActivity 将其调查对象传递给 FragmentPagerAdapter,后者使用该对象制作片段......但似乎FragmentPagerAdapter 和 SurveyFinishPage 正在寻找两个不同的东西。

如何正确恢复 FragmentPagerAdapter 中片段的状态,以便它们都引用同一个 Survey 对象?

MainActivity.java

public class MainActivity extends FragmentActivity {
    SurveyPagerAdapter mSurveyPagerAdapter;
    ViewPager mViewPager;
    Survey aSurvey;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_poll);

        if(savedInstanceState != null) {
            testSurvey = savedInstanceState.getParcelable("survey");
        }
        else {
            testSurvey = new Survey();
        }
        mSurveyPagerAdapter = new SurveyPagerAdapter(getSupportFragmentManager(), aSurvey);
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSurveyPagerAdapter);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("survey", aSurvey);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        aSurvey = (Survey)savedInstanceState.getParcelable("survey");
    }
    [...]
}

SurveyPagerAdapter.java

public class SurveyPagerAdapter extends FragmentPagerAdapter {
    private Survey survey;
    [...]

    @Override
    public Fragment getItem(int i) {
        Fragment fragment;
        Bundle args = new Bundle();

        // index 0 is the title page
        if(i == 0) {
            fragment = new SurveyTitlePage();
        }
        // final index is the finish page
        else if(i == getCount()-1) {
            fragment = new SurveyFinishPage();
        }
        // all other indices are regular poll pages
        else {
            args.putParcelable("question", survey.getQuestion(i-1));
            fragment = new SurveyPage();
            fragment.setArguments(args);
        }

        return fragment;
    }
    [...]
}

调查完成页面.java

public class SurveyFinishPage extends Fragment {
    private Survey survey;
    [...]

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    setSurvey(((MainPoll)getActivity()).getSurvey());
    LinearLayout view = new LinearLayout(getActivity());
    view.setOrientation(LinearLayout.VERTICAL);

    Button finishButton = new Button(getActivity());
    finishButton.setText("FINISH");

        final TextView textView = new TextView(getActivity());
        finishButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                String output = "";

                for(int i=0; i<survey.getSize(); i++) {
                    try {
                        output += survey.getQuestion(i).getPrompt() + " - " + survey.getQuestion(i).getAnswer() + "\n";
                    } catch (Exception e) {
                        output += survey.getQuestion(i).getPrompt() + " - " + "no answer\n";
                    }
                }
                textView.setText(output);
            }
        });

        view.addView(finishButton);
        view.addView(textView);

        return view;
    }
}

调查页面.java

public class SurveyPage extends Fragment {
        [...]

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Bundle args = getArguments();
            Question question = args.getParcelable("question");
            View pageView = question.getQuestionView(getActivity(), container);
        return pageView;
    }
}
4

1 回答 1

1

您可以将 Survey 对象提升到 Android 应用程序类并将其作为单例引用。该答案可能会引起一些争论,但它是您问题的合理解决方案。Android 保证您的应用程序只会有 1 个实例,因此您可以确定(在合理范围内)您将只有 1 个 Survey 实例。

http://developer.android.com/guide/faq/framework.html

单例类

您可以通过使用单例来利用您的应用程序组件在同一进程中运行这一事实。这是一个设计为只有一个实例的类。它有一个名为 getInstance() 的静态方法,它返回实例;第一次调用此方法时,它会创建全局实例。因为所有调用者都获得相同的实例,所以他们可以将其用作交互点。例如,活动 A 可以检索实例并调用 setValue(3);稍后的活动 B 可能会检索实例并调用 getValue() 以检索最后设置的值。

于 2012-08-31T03:20:08.313 回答