我有一个FragmentPagerAdapter,它通过自定义SurveyPage类生成的视图进行分页。寻呼机中的最后一页由SurveyFinishPage生成,它尝试访问与FragmentPagerAdapter关联的调查,并将所有调查答案拉到一起以显示它们。SurveyFinishPage通过主"活动"中的getSurvey()方法获取Survey对象。
通常情况下,这很好,SurveyFinishPage能够访问FragmentPagerAdapter正在使用的同一个Survey对象。但是,如果"活动"已被终止并恢复,则SurveyFinishPage似乎仍在访问旧的"调查"(或者可能是其副本)-它显示"活动"被丢弃之前的答案,而不管对新的、重建的"调查的答案有何更改。
在我的MainActivity中的onRestoreInstanceState()中恢复survey的值似乎应该为其他一切建立调查对象,因为MainActivity将其survey对象传递给FragmentPagerAdapter,后者使用该对象生成Fragments。。。但FragmentPagerAdapter和SurveyFinishPage似乎在关注两个不同的东西。
如何正确恢复FragmentPagerAdapter中片段的状态,使它们都引用同一个调查对象?
主活动.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");
}
[...]
}
调查页面适配器.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 answern";
}
}
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;
}
}
您可以将Survey对象提升到Android应用程序类,并将其作为单例引用。这个答案可能会引起一些争论,但它是解决你问题的合理方法。Android保证你的应用程序只有一个实例,所以你可以确定(在合理的范围内)你只有一个Survey实例。
http://developer.android.com/guide/faq/framework.html
辛格尔顿级
您可以通过使用singleton来利用应用程序组件在同一进程中运行的事实。这是一个设计为只有一个实例的类。它有一个静态方法,名称为getInstance(),返回实例;第一次调用此方法时,它会创建全局实例。因为所有调用方都获得相同的实例,所以他们可以将其用作交互点。例如,活动A可以检索实例并调用setValue(3);稍后的活动B可以检索实例并调用getValue()来检索最后一个设置的值。