活动 A 有片段。当它开始对活动 B 进行意图时,那么当B.finish()
,A执行onCreate()
again.
但这一次,尽管A.onCreate()
有一个新的PacksPagerAdapter
和一个新的ViewPager
,片段用旧数据显示。
我可以看到onCreateView()
为每个片段执行,但它仍然具有旧参数,因为static newInstance()
没有被叫到。当 FragmentPagerAdapter 的getItem(position)
叫做。
这是它的实现方式 -
public class PackActivity extends Activity {
...
PacksPagerAdapter mPacksPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPacksPagerAdapter = new MyPagerAdapter(getFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mPacksPagerAdapter);
mViewPager.setOffscreenPageLimit(PACK_PAGES - 1);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setTitle(...);
}
});
}
...
}
public class MyPagerAdapter extends FragmentPagerAdapter {
...
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class
// below).
return PackFragment.newInstance(myData);
}
...
}
public class PackFragment extends Fragment {
...
public static PackFragment newInstance(PackInfo pack) {
PackFragment fragment = new PackFragment();
Bundle bdl = new Bundle(2);
bdl.putSerializable(EXTRA_PACK, pack);
bdl.putInt(EXTRA_PACK_POSITION, pack.packNumber);
fragment.setArguments(bdl);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View packView = inflater.inflate(R.layout.pack_fragment, container, false);
// this has the old argument, since newInstance(...) wasn't called
PackInfo pack = (PackInfo) getArguments().getSerializable(EXTRA_PACK);
...
return packView;
}
...
}
知道为什么在第二次创建活动 A 时没有实例化新片段吗?
更新 - 活动片段生命周期
正如塔尔所说,答案是,活动正在恢复,因此旧的碎片被重新附加,而不是创建新的碎片。
在花了很多时间研究这个之后,我发现活动片段生命周期通常有 3 种场景。以下是场景、生命周期以及如何重新加载片段的旧数据:
新活动
生命周期: onCreate() ==> onResume() ==> 创建并附加片段
无需重新加载。
恢复活动
生命周期: onCreate() ==> 用旧数据填充并重新附加的片段 ==> onResume()
在 onResume() 中,手动或使用适配器自动删除所有片段并创建新片段 -
// Remove all fragments
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
for (int i = BuildConfig.PACK_PAGES - 1; i >= 0; i--) {
Fragment f = findFragmentByPosition(i);
if (f != null)
fragmentTransaction.remove(f);
}
fragmentTransaction.commit();
// This will force recreation of all fragments
viewPager.setAdapter(packsPagerAdapter);
恢复活动
生命周期: onResume()
与活动恢复相同,删除旧片段并重新创建。
Note:某些操作系统版本始终会恢复活动,即使打开 SettingsActivity 几秒钟也是如此,而其他(较旧的)版本将始终恢复。