FragmentTabs每次都创建新的Fragment对象

时间:2012-03-30 14:52:44

标签: android android-tabhost fragment


我想使用以下代码: http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.html,但我发现它正在创建和删除每个交换机之间的片段。
你能告诉我如何更改它,所以每个片段只能在开始时或首次进入后创建一次吗?
感谢!

P.S。我正在使用带有TabHost的Fragment,它用于显示放置在其中的其他片段之一。

更新: 每次从一个标签切换到另一个标签后,我会在(子)片段中获得onCreateViewonActivityCreated个方法。这不是由这条线引起的吗?

if (mLastTab != null)
{
 if (mLastTab.fragment != null)
 {
  ft.detach(mLastTab.fragment);
 }
}

TabManager的整个源代码(放在Fragment子类中):

public class TabManager implements TabHost.OnTabChangeListener
  {
    private final TabHost mTabHost;
    private final int mContainerId;
    private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
    TabInfo mLastTab;

    final class TabInfo
    {
      private final String tag;
      private final Class<?> clss;
      private final Bundle args;
      private Fragment fragment;

      TabInfo(String _tag, Class<?> _class, Bundle _args)
      {
        tag = _tag;
        clss = _class;
        args = _args;
      }
    }

    class DummyTabFactory implements TabHost.TabContentFactory
    {
      private final Context mContext;

      public DummyTabFactory(Context context)
      {
        mContext = context;
      }

      @Override
      public View createTabContent(String tag)
      {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
      }
    }

    public TabManager(TabHost tabHost, int containerId)
    {
      mTabHost = tabHost;
      mContainerId = containerId;
      mTabHost.setOnTabChangedListener(this);
    }

    public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
    {
      tabSpec.setContent(new DummyTabFactory(getActivity()));
      String tag = tabSpec.getTag();

      TabInfo info = new TabInfo(tag, clss, args);

      // Check to see if we already have a fragment for this tab, probably
      // from a previously saved state. If so, deactivate it, because our
      // initial state is that a tab isn't shown.
      info.fragment = getFragmentManager().findFragmentByTag(tag);
      if (info.fragment != null && !info.fragment.isDetached())
      {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.detach(info.fragment);
        ft.commit();
      }

      mTabs.put(tag, info);
      mTabHost.addTab(tabSpec);
    }

    @Override
    public void onTabChanged(String tabId)
    {
      TabInfo newTab = mTabs.get(tabId);
      if (mLastTab != newTab)
      {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        if (mLastTab != null)
        {
          if (mLastTab.fragment != null)
          {
            ft.detach(mLastTab.fragment);
          }
        }
        if (newTab != null)
        {
          if (newTab.fragment == null)
          {
            newTab.fragment = Fragment.instantiate(getActivity(), newTab.clss.getName(), newTab.args);
            ft.add(mContainerId, newTab.fragment, newTab.tag);
          } else
          {
            ft.attach(newTab.fragment);
          }
        }

        mLastTab = newTab;
        ft.commit();
        getFragmentManager().executePendingTransactions();
      }
    }
  }

修改 我在点击标签后显示/隐藏片段而不是附加/分离。不知道这是否正确。 解决方案:

public class TabManager implements TabHost.OnTabChangeListener
    {
        private final TabHost mTabHost;
        private final int mContainerId;
        private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
        TabInfo mLastTab;

        final class TabInfo
        {
            private final String tag;
            private final Class<?> clss;
            private final Bundle args;
            private Fragment fragment;

            TabInfo(String _tag, Class<?> _class, Bundle _args)
            {
                tag = _tag;
                clss = _class;
                args = _args;
            }
        }

        class DummyTabFactory implements TabHost.TabContentFactory
        {
            private final Context mContext;

            public DummyTabFactory(Context context)
            {
                mContext = context;
            }

            @Override
            public View createTabContent(String tag)
            {
                View v = new View(mContext);
                v.setMinimumWidth(0);
                v.setMinimumHeight(0);
                return v;
            }
        }

        public TabManager(TabHost tabHost, int containerId)
        {
            mTabHost = tabHost;
            mContainerId = containerId;
            mTabHost.setOnTabChangedListener(this);
        }

        public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
        {
            tabSpec.setContent(new DummyTabFactory(getActivity()));
            String tag = tabSpec.getTag();

            TabInfo info = new TabInfo(tag, clss, args);

            // Check to see if we already have a fragment for this tab, probably
            // from a previously saved state. If so, deactivate it, because our
            // initial state is that a tab isn't shown.
            info.fragment = getFragmentManager().findFragmentByTag(tag);
            if (info.fragment != null && !info.fragment.isDetached())
            {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.detach(info.fragment);
                ft.commit();
            }

            mTabs.put(tag, info);
            mTabHost.addTab(tabSpec);
        }

        @Override
        public void onTabChanged(String tabId)
        {
            TabInfo newTab = mTabs.get(tabId);
            if (mLastTab != newTab)
            {
                android.support.v4.app.FragmentTransaction ft = ((FragmentActivity) getActivity()).getSupportFragmentManager().beginTransaction();
                if (mLastTab != null)
                {
                    if (mLastTab.fragment != null)
                    {
                        ft.hide(mLastTab.fragment);

                    }
                }
                if (newTab != null)
                {
                    if (newTab.fragment == null)
                    {
                        newTab.fragment = Fragment.instantiate(getActivity(), newTab.clss.getName(), newTab.args);
                        ft.add(mContainerId, newTab.fragment, newTab.tag);
                    } else
                    {
                        ft.show(newTab.fragment);
                    }
                }

                mLastTab = newTab;
                ft.commit();
                getFragmentManager().executePendingTransactions();
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

它不会每次都创建一个新的片段,只有当片段没有附加到选项卡时才会这样做,即onTabChanged方法中newTab.fragment为null

         if (newTab.fragment == null) {
             newTab.fragment = Fragment.instantiate(mActivity,
             newTab.clss.getName(), newTab.args);
             ft.add(mContainerId, newTab.fragment, newTab.tag);
         } else {
             ft.attach(newTab.fragment);
         }