android – 当返回到已停止的活动时,碎片会被旧数据夸大
作者:互联网
活动A有片段.当它开始对活动B的意图时,那么当B.finish()时,A再次执行onCreate().
但这一次,即使A.onCreate()有一个新的PacksPagerAdapter和一个新的ViewPager,片段也会显示旧数据.
我可以看到onCreateView()是为每个片段执行的,但它仍然有旧的参数,因为没有调用静态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()
与活动还原相同,删除旧片段并重新创建.
注意:某些操作系统版本始终会恢复活动,即使在几秒钟内打开SettingsActivity,其他(较旧)版本也将始终恢复.
解决方法:
如果你发布你在活动A中提交的片段事务,我的答案会更好.
不确定你是否知道 – 如果活动A在从后面堆栈弹回时被重新创建 – 这意味着它是restored from previous instance state.
在这种情况下,您不应再次执行该事务,因为 – 它已经通过super.onCreate()Activity方法自动发生.事实上,如果你在这种情况下执行片段trasaction – 你将导致相同的片段被添加两次(2个实例)
您可以通过检查savedInstanceState参数是否为null来了解当前是否已通过恢复实例状态调用onCreate().
我的假设是你没有检查savedInstanceState,并且无论如何都要执行事务.
如果我是对的,那么以下更改应修复片段重复问题:
代替:
public static class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
performFragmentTransaction();
}
写:
public static class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
performFragmentTransaction();
}
}
更多信息在 – http://developer.android.com/guide/components/fragments.html
标签:android,android-activity,android-fragments,android-viewpager,android-pageradapte 来源: https://codeday.me/bug/20190628/1320387.html