FragmentTabs creating new Fragment objects every time

不羁岁月 提交于 2019-12-08 06:11:25

问题



I want to use code from : http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.html , but I see that it's creating&deleting fragments between every switch.
Could you tell me how to change it, so every fragment would be created only once at beginning or after first enter into it?
Thanks!

P.S. I am using Fragment with TabHost which is used to display one of other Fragments placed inside it.

Update: I am getting onCreateView and onActivityCreated methods in (sub)Fragments every time after switching from one tab to another. Isn't it caused by this lines?

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

Whole source code for TabManager (placed inside Fragment subclass) :

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

EDIT: I'm showing/hiding fragment after clicking on tab instead of attaching/detaching. Don't know if this is correct though. Solution:

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:


It doesn't create a new fragment every time, it only does if the fragment is not attached to the tab i.e newTab.fragment is null in the onTabChanged method

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


来源:https://stackoverflow.com/questions/9945347/fragmenttabs-creating-new-fragment-objects-every-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!