我有一个FragmentPagerAdapter,可以浏览自定义SurveyPage类生成的视图。寻呼机的最后一页由SurveyFinishPage生成,它试图访问与FragmentPagerAdapter相关的调查,并将所有调查答案一起拉出来显示它们。 SurveyFinishPage通过主Activity中的getSurvey()方法获取Survey对象。
通常这样可以正常工作,并且SurveyFinishPage能够访问FragmentPagerAdapter正在使用的相同Survey对象。但是,如果活动已经被杀死并恢复,则SurveyFinishPage似乎仍然在访问旧的Survey(或者可能是它的副本) - 它显示了在放弃Activity之前的答案,无论对新的,已重建的答案的更改如何调查。
似乎在我的MainActivity中恢复onRestoreInstanceState()中aSurvey的值应该为其他所有内容建立调查对象,因为MainActivity将其Survey对象传递给FragmentPagerAdapter,后者使用该对象制作片段......但是它似乎FragmentPagerAdapter和SurveyFinishPage正在研究两种不同的东西。
如何正确恢复FragmentPagerAdapter中片段的状态,以便它们都引用相同的Survey对象?
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");
}
[...]
}
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;
}
[...]
}
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;
}
}
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;
}
}
答案 0 :(得分:1)
您可以将Survey对象提升到Android应用程序类并将其作为单例引用。这个答案可能会产生一些争议,但它是解决问题的合理方法。 Android保证只有1个应用程序实例,因此您可以确定(在合理范围内)您只有1个调查实例。
http://developer.android.com/guide/faq/framework.html
Singleton类
您可以通过使用单例来利用应用程序组件在同一进程中运行的事实。这是一个只有一个实例的类。它有一个静态方法,其名称如getInstance()可返回实例;第一次调用此方法时,它会创建全局实例。因为所有调用者都获得相同的实例,所以他们可以将其用作交互点。例如,活动A可以检索实例并调用setValue(3);稍后的活动B可以检索实例并调用getValue()来检索最后一个设置值。