我的Android 4+应用的MainActivity使用ViewPager
在5个不同的片段之间切换。活动和片段都必须知道当前选择/显示哪个片段。 MainActivity使用ViewPagers
OnPageChangeListener
跟踪此信息。 MainActivity还保留对FragmentPagerAdapter
创建的片段的引用,以便在选择片段时能够通知片段。
问题是,MainActivty(当然)在重新创建片段时会丢失对片段的引用,例如:旋转设备时。如果重新创建的MainActivity会重新获取FragmentPagerAdapter
,中的信息,这不会是一个大问题,但事实并非如此。
似乎ViewPager会在调用super.onCreate(savedInstanceState)
时自动重新创建Framgent,而不会询问FragmentPagerAdapter
。这是一个问题,因为这样MainActivty没有获得有关创建的片段的任何信息,也无法保存对它的引用。
如何解决这个问题?
// MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
// When the activity is re-creates, e.g. on rotation, the viewPager
// Fragments are created here without knowledge of the MainActivity.
super.onCreate(savedInstanceState);
...
ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
viewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));
currentPageIndex = -1;
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
updateCurrentPageIndex(position);
}
});
@Override
protected void onResume () {
super.onResume();
updateCurrentPageIndex(currentPageIndex);
}
private void updateCurrentPageIndex(int index) {
currentPageIndex = position;
if (pageOneFragment != null && position == 0)
pageOneFragment.onSelectedInViewPager();
if (pageTwoFragment != null && position == 0)
pageTwoFragment.onSelectedInViewPager();
...
}
Fragment pageOnFragment;
Fragment pageTwoFragment;
...
private class SectionsPagerAdapter extends FragmentPagerAdapter {
...
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
pageOneFragment = PageOneFragmet.newInstance();
fragment = pageOneFragment;
}
if (position == 1) {
pageTwoFragment= PageTwoFragmet.newInstance();
fragment = pageTwoFragment;
}
...
return fragment;
}
}
}
编辑:感谢您的回答,但(我认为)保存实例状态并不能解决问题。当然我知道将Date保存到实例状态的可能性。因此,获取有关当前索引的信息不是一个大问题。问题是,MainActivity无法通知所选的Fragment,因为它没有引用它。片段不是在适配器中创建的,而是由ViewPager自动创建的。因此,活动不会获得有关片段的任何信息,也无法通知它有关活动的信息......
答案 0 :(得分:2)
创建界面
public interface FragmentListener {
void onFragmentActivated(Fragment f);
}
在您的活动中实施此界面。然后在你的片段中:
@Override
public void onResume() {
super.onResume();
((FragmentListener)getActivity()).onFragmentActivated(this);
}
现在,当您在活动中调用此回调时,您知道哪个片段已激活
答案 1 :(得分:0)
在onSaveInstanceState()中,您应该“放置”您想要跟踪的任何内容。在onCreate()中,您可以“获取”这些项目。
private static final String KEY_BUNDLE_CURRENT_PAGE_STATE = "current_page_state";
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_BUNDLE_CURRENT_PAGE_STATE, currentPageIndex);
}
@Override
public void onCreate(Bundle savedInstanceState){
// ...
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_BUNDLE_CURRENT_PAGE_STATE) {
currentPageIndex = savedInstanceState.getInt(KEY_BUNDLE_CURRENT_PAGE_STATE);
}
// ...
}
答案 2 :(得分:0)
试试这个
private static final String INDEX = "f_index";
private int mCurrentIndex ; // the current index will be updated thru position
// orientation change occurs
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current index state
savedInstanceState.putInt(INDEX, mCurrentIndex);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
...
// this is where we get the data back if we are recreated
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentIndex= savedInstanceState.getInt(INDEX);
} else {
// Probably initialize members with default values for a new instance
}
...
}
这里有一个很好的生命周期图。
修改强>
如果上述内容对您不起作用,我建议您尝试使用此功能。
希望它有所帮助:)