如何保持应用程序片段的状态 [英] How to maintain fragment's state in the application

查看:127
本文介绍了如何保持应用程序片段的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何保持片段的状态时,它显示在FragmentTabHost?

由于该<一href="http://www.betteropts.com/fragmenttabhost-tutorial-using-fragment-as-tab-content-and-keep-navigation-history-for-each-tab/"相对=nofollow>教程,我能够实施 FragmentTabHost 在我的应用程序。

我的目的是创建一个应用程序,其主要活动包含了某些选项卡(其中粘在上面整个应用程序)。点击每个选项卡打开选项卡下面的一个新片段。

问题是,当我点击选项卡上做一些事情,然后去将打开一个新的片段花药选项卡,然后回来到第一个标签 - 我的变化在这里是不能维持

流量:

我真的需要实现这个逻辑。如果我的做法是错误的,请建议替代。

感谢

code:

主要活动

 公共类FagTabHostMain扩展FragmentActivity {
    FragmentTabHost mTab​​Host;

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_fag_tab_host_main);

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

        mTabHost.addTab(mTabHost.newTabSpec(音频)。setIndicator(音频),
                AudioContainerFragmentClass.class,NULL);
        mTabHost.addTab(mTabHost.newTabSpec(视频)。setIndicator(视频),
                VideoContainerFragmentClass.class,NULL);

    }

    @覆盖
    公共无效onBack pressed(){
        布尔isPopFragment = FALSE;
        串currentTabTag = mTab​​Host.getCurrentTabTag();
        如果(currentTabTag.equals(声音)){
            isPopFragment =((AudioContainerFragmentClass)getSupportFragmentManager()
                    .findFragmentByTag(音频))popFragment()。
        }否则,如果(currentTabTag.equals(视频)){
            isPopFragment =((VideoContainerFragmentClass)getSupportFragmentManager()
                    .findFragmentByTag(视频))popFragment()。
        }
        //完成时,没有更多的碎片在后面堆栈显示
        完();
    }
}
 

主要业务布局

 &LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直&GT;

    &LT; android.support.v4.app.FragmentTabHost
        机器人:ID =@机器人:ID / tabhost
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent&GT;

        &LT;  - !不使用本之一,现在 - &GT;
        &LT;的FrameLayout
            机器人:ID =@机器人:ID / tabcontent
            机器人:layout_width =0dip
            机器人:layout_height =0dip
            机器人:layout_weight =0/&GT;

    &LT; /android.support.v4.app.FragmentTabHost>

    &LT;的FrameLayout
        机器人:ID =@ + ID / realtabcontent
        机器人:layout_width =match_parent
        机器人:layout_height =0dip
        机器人:layout_weight =1/&GT;

&LT; / LinearLayout中&GT;
 

AudioContainerFragmentClass

 公共类AudioContainerFragmentClass扩展片段工具
        OnClickListener {

    最终的字符串变量=AudioContainerFragmentClass;
    私人布尔mIsViewInitiated = FALSE;
    私人布尔addToBackStack = TRUE;
    私人按钮bNextFragment;
    私人的LinearLayout LinearLayout中;

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
            捆绑savedInstanceState){
        尝试 {
            Log.e(AudioContainerFragmentClass,onCreateView称为);
            的LinearLayout =(的LinearLayout)inflater.inflate(
                    R.layout.audio_fragment_container,集装箱,假);
        }赶上(例外五){
            printException(e.toString());
        }
        返回的LinearLayout;
    }

    @覆盖
    公共无效onActivityCreated(包savedInstanceState){
        尝试 {
            super.onActivityCreated(savedInstanceState);
            Log.e(AudioContainerFragmentClass,onActivityCreated称为);
            如果(!mIsViewInitiated){
                mIsViewInitiated = TRUE;
                initView();
            }
        }赶上(例外五){
            printException(e.toString());
        }
    }

    私人无效initView(){
        尝试 {
            Log.e(AudioContainerFragmentClass,initView称为);
            bNextFragment =(按钮)的LinearLayout
                    .findViewById(R.id.bNextFragment);
            bNextFragment.setOnClickListener(本);
            replaceFragment(新AudioFragment(),FALSE);
        }赶上(例外五){
            printException(e.toString());
        }
    }

    私人无效replaceFragment(AudioFragment audioFragment,布尔B){
        尝试 {
            FragmentTransaction英尺= getChildFragmentManager()
                    .beginTransaction();
            如果(addToBackStack){
                ft.addToBackStack(空);
            }
            ft.replace(R.id.audio_sub_fragment,audioFragment);
            ft.commit();
            getChildFragmentManager()executePendingTransactions()。
        }赶上(例外五){
            printException(e.toString());
        }
    }

    //从FagTabHostMain活动调用
    公共布尔popFragment(){
        布尔isPop = FALSE;
        尝试 {
            Log.e(AudioContainerFragmentClass,popFragment称为);
            如果(getChildFragmentManager()getBackStackEntryCount()&GT; 0){
                isPop = TRUE;
                getChildFragmentManager()popBackStack()。
            }
        }赶上(例外五){
            printException(e.toString());
        }
        返回isPop;
    }

    @覆盖
    公共无效的onClick(查看为arg0){
        TextView的电视=(TextView中)getActivity()findViewById(R.id.tvaudioTitle)。
        tv.setText(文本改变);
    }

    私人无效printException(字符串字符串){
        Log.e(__ ERRORR__,字符串);
    }
}
 

AudioFragment

 公共类AudioFragment扩展片段{

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
            捆绑savedInstanceState){
        查看查看= inflater.inflate(R.layout.audio_sub_fragment,集装箱,
                假);
        返回查看;
    }
}
 

解决方案

有同样的事情在我的应用程序。 您将需要复制<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.2.2_r1/android/support/v4/app/FragmentTabHost.java">FragmentTabHost您的项目,请将code使用新的自定义 FragmentTabHost 键,然后更改 doTabChanged 来实现如下:

 私人FragmentTransaction doTabChanged(字符串tabId,FragmentTransaction英尺){
    TabInfo newTab = NULL;
    的for(int i = 0; I&LT; mTab​​s.size();我++){
        TabInfo标签= mTab​​s.get(我);
        如果(tab.tag.equals(tabId)){
            newTab =标签;
        }
    }
    如果(newTab == NULL){
        抛出新IllegalStateException异常(无标签闻名的标记+ tabId);
    }
    如果(mLastTab!= newTab){
        如果(英尺== NULL){
            英尺= mFragmentManager.beginTransaction();
        }
        如果(mLastTab!= NULL){
            如果(mLastTab.fragment!= NULL){
                ft.hide(mLastTab.fragment);
            }
        }
        如果(newTab!= NULL){
            如果(newTab.fragment == NULL){
                newTab.fragment = Fragment.instantiate(mContext,
                        newTab.clss.getName(),newTab.args);
                ft.add(mContainerId,newTab.fragment,newTab.tag);
                findViewById(mContainerId).setContentDescription(DEBUG片段添加到这个容器中。);
            } 其他 {
                如果(newTab.fragment.isHidden()){
                    ft.show(newTab.fragment);
                }
                其他{
                    ft.attach(newTab.fragment);
                }
            }
        }

        米previousTab = mLastTab;
        mLastTab = newTab;
    }
    返回英尺;
}
 

有人认为,这种变化是不是 deattach /附加片段,我们正在做的隐藏/显示

How to maintain fragment's state when it is shown within FragmentTabHost?

Thanks to this tutorial, I'm able to implement FragmentTabHost in my application.

My intention is to create an app whose main activity contains some tabs (which sticks on the top throughout the app). Clicking each tab opens a new fragment below the tabs.

Issue is when I click on a tab do something, then go to anther tab which opens a new fragment, then comes back to first tab - my changes here are not maintained.

Flow:

I really need to implement this logic. If my approach is wrong, please suggest alternative.

Thanks

Code:

Main Activity

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

Main activity layout

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

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

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

解决方案

Had the same thing in my app. You will need to copy the FragmentTabHost to your project, point your code to use the new custom FragmentTabHost and then change the code of doTabChanged to following implementation:

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

The change that was made is that instead of deattach/attach the fragment, we are doing hide/show

这篇关于如何保持应用程序片段的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆