Android系统。片段没有保存他们的状态

时间:2014-08-26 06:12:57

标签: java android android-fragments

我正在尝试创建自定义标签导航。单击每个选项卡,它将替换屏幕中的片段。在 MainActivity.java 上,我创建了每个片段的一个副本(我想,通过这种方式,我可以在每个地方使用每个片段的一个副本)。

    public static WhereRootFragment whereRootFragment;
    public static FeedRootFragment feedRootFragment;

    public static WhereMainFragment whereMainFragment;
    public static FeedMainFragment feedMainFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
.....
        whereRootFragment=new WhereRootFragment();
        feedRootFragment=new FeedRootFragment();

        whereMainFragment=new WhereMainFragment();
        feedMainFragment=new FeedMainFragment();

        ClickHandler.handleClick(MainActivity.this, llWhere);
}

单击选项卡按钮时,它会将旧片段替换为当前片段( handleClick 方法)。

        switch (tag) {
        case TAG_WHERE:
            MainActivity.ivWhere.setImageDrawable(a.getResources().getDrawable(
                    R.drawable.where_black));
//          Fragment fragment_where_root=new WhereRootFragment();
            FragmentTransaction transaction_where = ((FragmentActivity) a).getSupportFragmentManager().beginTransaction();
            transaction_where.replace(R.id.root_frame, MainActivity.whereRootFragment);
            transaction_where.addToBackStack(null);
            transaction_where.commit();
            break;
        case TAG_FEED:
            MainActivity.ivFeed.setImageDrawable(a.getResources().getDrawable(
                    R.drawable.feed_black));
//          Fragment fragment_feed_root=new FeedRootFragment();
            FragmentTransaction transaction_feed = ((FragmentActivity) a).getSupportFragmentManager().beginTransaction();
            transaction_feed.replace(R.id.root_frame,  MainActivity.feedRootFragment);
            transaction_feed.addToBackStack(null);
            transaction_feed.commit();
            break;

WhereRootFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    /* Inflate the layout for this fragment */
    View view = inflater.inflate(R.layout.fragment_where_root, container, false);

    FragmentTransaction transaction = getFragmentManager()
            .beginTransaction();
    transaction.replace(R.id.where_root_frame, MainActivity.whereMainFragment);
    transaction.addToBackStack(null);
    transaction.commit();

    return view;
}

WhereMainFragment

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_where_main,
            container, false);
    return rootView;
}

结果: enter image description here

[StartApp] - > [1. Where:显示] - > [2.Feed:显示] - > [3.Where:它没有显示] - > [4.Feed:显示已保存状态] - > [5.另一个片段:假设是空的] - > [6.Feed:not showing]

问题:如何解决这个问题?如何让片段保存其状态?

2 个答案:

答案 0 :(得分:1)

WhereRootFragment由属于该活动的片段管理器管理。问题正在发生,因为正在使用相同的片段管理器来管理WhereMainFragment的孩子WhereRootFragment

WhereMainFragment应由属于WhereRootFragment的片段管理器管理。要在片段中获取子片段管理器,请使用Fragment.getChildFragmentManager

<强> WhereRootFragment

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    /* Inflate the layout for this fragment */
    View view = inflater.inflate(R.layout.fragment_where_root, container, false);

    // Use child fragment manager to manage WhereMainFragment
    FragmentTransaction transaction = getChildFragmentManager()
            .beginTransaction();
    transaction.replace(R.id.where_root_frame, MainActivity.whereMainFragment);
    transaction.addToBackStack(null);
    transaction.commit();

    return view;
}

答案 1 :(得分:0)

有些链接可能对您有用:

- &GT;您可能必须使用FragmentTabHost | Android Developers

- &GT; Creating-and-Using-Fragments

- &GT;你可能想要这个Android Fragments

- &GT;最好的一个Android Beginner

Stackoverflow Answer says:

public final class MyFragment extends Fragment {
    private TextView vstup;
    private Bundle savedState = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.whatever, null);
        vstup = (TextView)v.findViewById(R.id.whatever);

        /* (...) */

        /* If the Fragment was destroyed inbetween (screen rotation), we need to recover the savedState first */
        /* However, if it was not, it stays in the instance from the last onDestroyView() and we don't want to overwrite it */
        if(savedInstanceState != null && savedState == null)
            savedState = savedInstanceState.getBundle(App.STAV);
        if(savedState != null)
            vstup.setText(savedState.getCharSequence(App.VSTUP));
        savedState = null;

        return v;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        savedState = saveState(); /* vstup defined here for sure */
        vstup = null;
    }

    private Bundle saveState() { /* called either from onDestroyView() or onSaveInstanceState() */
        Bundle state = new Bundle();
        state.putCharSequence(App.VSTUP, vstup.getText());
        return state;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        /* If onDestroyView() is called first, we can use the previously savedState but we can't call saveState() anymore */
        /* If onSaveInstanceState() is called first, we don't have savedState, so we need to call saveState() */
        /* => (?:) operator inevitable! */
        outState.putBundle(App.STAV, savedState != null ? savedState : saveState());
    }

    /* (...) */

}