FragmentTabs каждый раз создает новые объекты Fragment - PullRequest
1 голос
/ 30 марта 2012


Я хочу использовать код из: http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.html, но я вижу, что он создает и удаляет фрагменты между каждым переключателем.
Не могли бы вы сказать мне, как его изменить, чтобы каждый фрагмент создавался только один раз в начале или после первого входа в него?
Спасибо!

P.S. Я использую Fragment с TabHost, который используется для отображения одного из других фрагментов, размещенных внутри него.

Обновление: Я получаю onCreateView и onActivityCreated методы в (под) фрагментах каждый раз после переключения с одной вкладки на другую. Разве это не вызвано этими строками?

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

EDIT: Я показываю / скрываю фрагмент после нажатия на вкладку вместо того, чтобы прикреплять / отсоединять. Не знаю, если это правильно, хотя. Решение:

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 голосов
/ 30 марта 2012

Он не создает новый фрагмент каждый раз, он создается, только если фрагмент не присоединен к вкладке, т.е. newTab.fragment в методе onTabChanged имеет значение 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);
         }
...