如何在应用程序中维护片段的状态

rei*_*ley 7 android android-layout android-fragments fragment-tab-host

如何在FragmentTabHost中显示片段的状态?

感谢本教程,我能够FragmentTabHost在我的应用程序中实现.

我的目的是创建一个应用程序,其主要活动包含一些选项卡(在整个应用程序的顶部).单击每个选项卡将在选项卡下方打开一个新片段.

问题是当我单击选项卡时执行某些操作,然后转到另一个选项卡,该选项卡将打开一个新的片段,然后返回到第一个选项卡 - 此处的更改不会保留.

流:

在此输入图像描述

我真的需要实现这个逻辑.如果我的方法有误,请建议替代方案.

谢谢

码:

主要活动

public class FagTabHostMain extends FragmentActivity {
    FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fag_tab_host_main);

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

        mTabHost.addTab(mTabHost.newTabSpec("audio").setIndicator("Audio"),
                AudioContainerFragmentClass.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("video").setIndicator("Video"),
                VideoContainerFragmentClass.class, null);

    }

    @Override
    public void onBackPressed() {
        boolean isPopFragment = false;
        String currentTabTag = mTabHost.getCurrentTabTag();
        if (currentTabTag.equals("audio")) {
            isPopFragment = ((AudioContainerFragmentClass) getSupportFragmentManager()
                    .findFragmentByTag("audio")).popFragment();
        } else if (currentTabTag.equals("video")) {
            isPopFragment = ((VideoContainerFragmentClass) getSupportFragmentManager()
                    .findFragmentByTag("video")).popFragment();
        }
        // Finish when no more fragments to show in back stack
        finish();
    }
}
Run Code Online (Sandbox Code Playgroud)

主要活动布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <!-- Not Using this one right now -->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dip"
            android:layout_height="0dip"
            android:layout_weight="0" />

    </android.support.v4.app.FragmentTabHost>

    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

AudioContainerFragmentClass

public class AudioContainerFragmentClass extends Fragment implements
        OnClickListener {

    final String TAG = "AudioContainerFragmentClass";
    private Boolean mIsViewInitiated = false;
    private boolean addToBackStack = true;
    private Button bNextFragment;
    private LinearLayout linearLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        try {
            Log.e("AudioContainerFragmentClass", "onCreateView called");
            linearLayout = (LinearLayout) inflater.inflate(
                    R.layout.audio_fragment_container, container, false);
        } catch (Exception e) {
            printException(e.toString());
        }
        return linearLayout;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        try {
            super.onActivityCreated(savedInstanceState);
            Log.e("AudioContainerFragmentClass", "onActivityCreated called");
            if (!mIsViewInitiated) {
                mIsViewInitiated = true;
                initView();
            }
        } catch (Exception e) {
            printException(e.toString());
        }
    }

    private void initView() {
        try {
            Log.e("AudioContainerFragmentClass", "initView called");
            bNextFragment = (Button) linearLayout
                    .findViewById(R.id.bNextFragment);
            bNextFragment.setOnClickListener(this);
            replaceFragment(new AudioFragment(), false);
        } catch (Exception e) {
            printException(e.toString());
        }
    }

    private void replaceFragment(AudioFragment audioFragment, boolean b) {
        try {
            FragmentTransaction ft = getChildFragmentManager()
                    .beginTransaction();
            if (addToBackStack) {
                ft.addToBackStack(null);
            }
            ft.replace(R.id.audio_sub_fragment, audioFragment);
            ft.commit();
            getChildFragmentManager().executePendingTransactions();
        } catch (Exception e) {
            printException(e.toString());
        }
    }

    // Called from FagTabHostMain Activity
    public boolean popFragment() {
        boolean isPop = false;
        try {
            Log.e("AudioContainerFragmentClass", "popFragment called");
            if (getChildFragmentManager().getBackStackEntryCount() > 0) {
                isPop = true;
                getChildFragmentManager().popBackStack();
            }
        } catch (Exception e) {
            printException(e.toString());
        }
        return isPop;
    }

    @Override
    public void onClick(View arg0) {
        TextView tv  = (TextView)getActivity().findViewById(R.id.tvaudioTitle);
        tv.setText("Text changed");
    }

    private void printException(String string) {
        Log.e("__ERRORR__", string);
    }
}
Run Code Online (Sandbox Code Playgroud)

AudioFragment

public class AudioFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.audio_sub_fragment, container,
                false);
        return view;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sea*_*ean 19

在我的应用程序中有同样的事情.您需要将FragmentTabHost复制到项目中,指向您的代码以使用新的自定义FragmentTabHost,然后将代码更改doTabChanged为以下实现:

    private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
    TabInfo newTab = null;
    for (int i=0; i<mTabs.size(); i++) {
        TabInfo tab = mTabs.get(i);
        if (tab.tag.equals(tabId)) {
            newTab = tab;
        }
    }
    if (newTab == null) {
        throw new IllegalStateException("No tab known for tag " + tabId);
    }
    if (mLastTab != newTab) {
        if (ft == null) {
            ft = mFragmentManager.beginTransaction();
        }
        if (mLastTab != null) {
            if (mLastTab.fragment != null) {
                ft.hide(mLastTab.fragment);
            }
        }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(mContext,
                        newTab.clss.getName(), newTab.args);
                ft.add(mContainerId, newTab.fragment, newTab.tag);
                findViewById(mContainerId).setContentDescription("DEBUG. add fragment to this container");
            } else {
                if (newTab.fragment.isHidden()){
                    ft.show(newTab.fragment);
                }
                else{
                    ft.attach(newTab.fragment); 
                }
            }
        }

        mPreviousTab = mLastTab;
        mLastTab = newTab;
    }
    return ft;
}
Run Code Online (Sandbox Code Playgroud)

所做的改变是,而不是deattach/attach片段,我们正在做hide/show