当返回到已停止的活动时,碎片会因旧数据而膨胀

Kof*_*Kof 5 android android-fragments android-viewpager android-activity android-pageradapter

活动 A 有片段。当它启动对活动 B 的意图时B.finish(),然后当 时,AonCreate()再次执行。

但这一次,即使A.onCreate()有 newPacksPagerAdapter和 new ViewPager,片段也显示为旧数据。

我可以看到它onCreateView()为每个片段执行,但由于static newInstance()没有调用它,它仍然具有旧参数。getItem(position)调用FragmentPagerAdapter 时会创建参数。

这是它的实施方式 -

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;
    }

...
}
Run Code Online (Sandbox Code Playgroud)

知道为什么在第二次创建活动 A 时没有实例化新片段吗?

更新 - Activity-Fragments 生命周期

答案是,正如 Tal 所说,活动正在恢复,因此旧片段正在重新连接而不是创建新片段。

在花了很多时间研究这个之后,我发现活动片段生命周期通常有 3 种场景。以下是场景、生命周期以及如何重新加载片段的旧数据:

新活动

生命周期:onCreate() ==> onResume() ==> Fragments 被创建和附加

无需重新加载。

恢复活动

生命周期: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);
Run Code Online (Sandbox Code Playgroud)

恢复活动

生命周期:onResume()

与活动恢复相同,删除旧片段并重新创建。

注意:某些操作系统版本始终会恢复活动,即使打开 SettingsActivity 几秒钟也是如此,而其他(旧)版本将始终恢复。

Tal*_*nel 2

如果您发布在活动 A 中提交的片段交易,我的答案会更好。

不确定您是否知道 - 如果 Activity A 在从返回堆栈弹出时重新创建 - 这意味着它从先前的实例状态恢复

在这种情况下,您不应该再次执行事务,因为 - 它已经通过 super.onCreate() Activity 方法自动发生。事实上,如果您在这种情况下执行片段交易 - 您将导致相同的片段被添加两次(2 个实例)

通过检查参数是否为空,您可以知道当前是否onCreate() 被调用来恢复实例状态。savedInstanceState

我的假设是您没有检查savedInstanceState并执行交易。

如果我是对的,那么以下更改应该可以解决片段重复问题:

代替:

public static class ActivityA extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        performFragmentTransaction();

}
Run Code Online (Sandbox Code Playgroud)

写:

public static class ActivityA extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
           performFragmentTransaction();
        }
}
Run Code Online (Sandbox Code Playgroud)

更多信息请访问 - http://developer.android.com/guide/components/fragments.html