避免在Android的重建FragmentTabHost的标签onTabChnage [英] Avoid recreating tabs onTabChnage of FragmentTabHost in android

查看:641
本文介绍了避免在Android的重建FragmentTabHost的标签onTabChnage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是FragmentTabHost用于简单的两片设置。然而,当我从一个切换到另一个标签得到重建。如何避免这种情况。虽然我试图隐藏/显示,没有工作见下文updateTab方法。

  @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
        捆绑savedInstanceState)
   {    mTabHost =新FragmentTabHost(getActivity());
    mTabHost.setup(getActivity(),getChildFragmentManager(),R.id.tabhost);    mTabHost.addTab(
            mTabHost.newTabSpec(tabAchievements)。setIndicator(
                    getResources()。的getString(R.string.tab_achievements)
                    getResources()。getDrawable(R.drawable.location))
            CompleteFragment.class,NULL);
    mTabHost.addTab(
            mTabHost.newTabSpec(tabIncomplete)。setIndicator(
                    getResources()。的getString(R.string.tab_incomplete)
                    getResources()。getDrawable(R.drawable.eye))
            IncompleteFragment.class,NULL);    myLastTag =tabAchievements;
    mTabHost.setOnTabChangedListener(新OnTabChangeListener(){        公共无效onTabChanged(字符串tabId){
            如果(tabId.equals(tabAchievements)){                updateTab(tabId,R.string.tab_achievements);
                返回;
            }
            如果(tabId.equals(tabIncomplete)){
                updateTab(tabId,R.string.tab_incomplete);
                返回;
            }
        }
    });
    返回mTabHost;
}私人无效updateTab(字符串tabId,诠释占位符){
    片段newTab = getChildFragmentManager()findFragmentByTag(tabId)。
    片段mLastTab = getChildFragmentManager()。findFragmentByTag(
            myLastTag);
    myLastTag = tabId;
    如果(mLastTab!= newTab){
        FragmentTransaction英尺= activity.getSupportFragmentManager()
                .beginTransaction();
        如果(mLastTab!= NULL){
            如果(mLastTab!= NULL){
                ft.hide(mLastTab);
            }
        }
        如果(newTab == NULL){
            如果(tabId ==tabAchievements)
                newTab = Fragment.instantiate(活动,
                        CompleteFragment.class.getName(),NULL);
            其他
                newTab = Fragment.instantiate(活动,
                        IncompleteFragment.class.getName(),NULL);
            ft.add(android.R.id.tabcontent,newTab,NULL);        }其他{
            ft.show(newTab);
        }
        ft.commit();
    }
}


解决方案

我有同样的问题,终于得到它解决。这是不够的,覆盖OnTabChangeListener作为FragmentTabHost内部不先调用一个侦听器之前,连接或dettach片段,所以从OnCreateView生命周期仍称。看看这个解决方案,<一个href=\"http://stackoverflow.com/questions/19331492/how-to-maintain-fragments-state-in-the-application\">How以保持应用程序片段的状态,它为我工作。下载最后FragmentTabHost.java code和替换为doTabChanged(我还添加了调用的onPause演出后隐藏和onResume之前,否则他们不会被调用):

 私人FragmentTransaction doTabChanged(字符串tabId,FragmentTransaction英尺){
    TabInfo newTab = NULL;
    的for(int i = 0; I&LT; mTab​​s.size();我++){
        TabInfo标签= mTab​​s.get(I)
        如果(tab.tag.equals(tabId)){
            newTab =标签;
        }
    }
    如果(newTab == NULL){
        抛出新IllegalStateException异常(无标签闻名标签+ tabId);
    }
    如果(mLastTab!= newTab){
        如果(英尺== NULL){
            英尺= mFragmentManager.beginTransaction();
        }
        如果(mLastTab!= NULL){
            如果(mLastTab.fragment!= NULL){
                mLastTab.fragment.onPause();
                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);
                    newTab.fragment.onResume();
                }
                其他{
                    ft.attach(newTab.fragment);
                }
            }
        }        //米previousTab = mLastTab;
        mLastTab = newTab;
    }
    返回英尺;}

和不覆盖OnTabChangedListener。你当然有改变你的包路径android.support.v4.app.FragmentTabHost的参考文献,并做到这一点也是在布局文件...

I am using a FragmentTabHost for simple two tab setting. However tabs get recreated when I switch from one to another. How to avoid this. Although I tried to hide/show, that didnt work see updateTab method below.

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
   {

    mTabHost = new FragmentTabHost(getActivity());
    mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.tabhost);

    mTabHost.addTab(
            mTabHost.newTabSpec("tabAchievements").setIndicator(
                    getResources().getString(R.string.tab_achievements),
                    getResources().getDrawable(R.drawable.location)),
            CompleteFragment.class, null);
    mTabHost.addTab(
            mTabHost.newTabSpec("tabIncomplete").setIndicator(
                    getResources().getString(R.string.tab_incomplete),
                    getResources().getDrawable(R.drawable.eye)),
            IncompleteFragment.class, null);

    myLastTag = "tabAchievements";
    mTabHost.setOnTabChangedListener(new OnTabChangeListener() {

        public void onTabChanged(String tabId) {
            if (tabId.equals("tabAchievements")) {

                updateTab(tabId, R.string.tab_achievements);
                return;
            }
            if (tabId.equals("tabIncomplete")) {
                updateTab(tabId, R.string.tab_incomplete);
                return;
            }
        }
    });
    return mTabHost;
}

private void updateTab(String tabId, int placeholder) {
    Fragment newTab = getChildFragmentManager().findFragmentByTag(tabId);
    Fragment mLastTab = getChildFragmentManager().findFragmentByTag(
            myLastTag);
    myLastTag = tabId;
    if (mLastTab != newTab) {
        FragmentTransaction ft = activity.getSupportFragmentManager()
                .beginTransaction();
        if (mLastTab != null) {
            if (mLastTab != null) {
                ft.hide(mLastTab);
            }
        }
        if (newTab == null) {
            if (tabId == "tabAchievements")
                newTab = Fragment.instantiate(activity,
                        CompleteFragment.class.getName(), null);
            else
                newTab = Fragment.instantiate(activity,
                        IncompleteFragment.class.getName(), null);
            ft.add(android.R.id.tabcontent, newTab, null);

        } else {
            ft.show(newTab);
        }
        ft.commit();
    }
}

解决方案

I had the same issue, and finally got it solved. It's not enough to override OnTabChangeListener as the FragmentTabHost internally does first an attach or dettach of the fragments before calling your listener, so the lifecycle from OnCreateView is still called. Look at this solution, How to maintain fragment's state in the application, it worked for me. Download the last FragmentTabHost.java code and replace the doTabChanged with (I've also added the call to onPause before hide and onResume after show, otherwise they don't get called):

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) {
                mLastTab.fragment.onPause();
                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);
                    newTab.fragment.onResume();
                }
                else{
                    ft.attach(newTab.fragment);
                }
            }
        }

        //mPreviousTab = mLastTab;
        mLastTab = newTab;
    }
    return ft;

}

and don't override OnTabChangedListener. You have of course to change the references to android.support.v4.app.FragmentTabHost with your package path, and do it also in your Layout file...

这篇关于避免在Android的重建FragmentTabHost的标签onTabChnage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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