我制作了一个测试应用程序,以便我可以学习如何保存InstanceState
。
现在我们有一个Main Fragment Activity和两个Tab Fragments。我在主活动中有一个变量,它的值位于onCreate
方法中..我想与碎片共享它。
因此,当我需要该变量的值时,我在Main Activity中创建了一个公共方法来在片段内调用它。 ((TMainActivity) getActivity()).getTestString()
问题是当设备旋转时我得到了字符串的默认值而不是保存的值。
这显然是因为在onRestoreInstanceState
片段之后调用了onCreate
。
现在,我该如何解决这个问题?
TMainActivity.java
public class TMainActivity extends FragmentActivity {
final private static String TAG = "TMainActivity";
final private static String EXTRA_TEST = "MAIN_KEY";
private CollectionPagerAdapter mCollectionPagerAdapter;
private ViewPager mainPager;
private String test = "Default";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v(TAG, "onCreate() Before test= " + test);
if (savedInstanceState == null) {
test = "New";
} else {
test = savedInstanceState.getString(EXTRA_TEST) + " - Restored";
}
Log.v(TAG, "onCreate() After test= " + test);
mainPager = (ViewPager) findViewById(R.id.main_pager);
mCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
mainPager.setAdapter(mCollectionPagerAdapter);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.v(TAG, "onSaveInstanceState()");
outState.putString(EXTRA_TEST, test);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.v(TAG, "onRestoreInstanceState()");
Log.v(TAG, "onRestoreInstanceState() savedInstanceState=" + (savedInstanceState != null));
test = savedInstanceState.getString(EXTRA_TEST);
}
public String getTestString() {
return test;
}
private class CollectionPagerAdapter extends FragmentStatePagerAdapter {
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = null;
switch (i) {
case 0:
fragment = new Tab1Fragment();
break;
case 1:
fragment = new Tab2Fragment();
break;
}
return fragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
}
Tab1Fragment.java
public class Tab1Fragment extends Fragment {
final private static String TAG = "Tab1Fragment";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate()");
Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_tab1, container, false);
return rootView;
}
}
Tab2Fragment.java
public class Tab2Fragment extends Fragment {
final private static String TAG = "Tab2Fragment";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate()");
Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_tab2, container, false);
return rootView;
}
}
答案 0 :(得分:0)
我遇到了同样的问题。首先在Activity中调用onCreate
,在此方法中,您已经将Bundle与数据一起使用。这意味着您可以恢复活动,然后使用稍后调用的片段onCreateView
中的数据。
基本上,您不会覆盖onRestoreInstanceState()
方法,而是将其重命名并在“活动”中从onCreate
调用它。不重写该方法的原因是因为它将被onCreate
从Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());
调用2次,然后作为Activity生命周期的一部分。如果在片段中更改了值,则会重置该值。
在您的情况下,您可以移动
onCreate
从onCreateView
到onRestoreInstanceState
。
当您恢复大量数据时,这不是一个好的解决方案。您的UI线程将无法恢复活动。但在这种情况下,您可以恢复片段中所需的部分数据,并在.text()
中恢复其余部分。