Avoid recreating same view when perform tab switching

后端 未结 6 574
一生所求
一生所求 2021-01-30 17:43

Current, I have 2 Fragments, which is switch-able through ActionBar\'s tab.

    getSupportActionBar().setNavigationMode(ActionBar.NAVIG         


        
相关标签:
6条回答
  • 2021-01-30 17:44

    I started searching for a simple solution for this many hours ago and finally stumbled across the answer by @roger which saved me lots of hair....

    When using the ViewPager in other implementations, I could simply call:

    mViewPager.setOffscreenPageLimit(//number of pages to cache);
    

    So, I was very surprised it took me so many hours to resolve this. The example he gave wasn't entirely clear though, so for the sake of completeness, here is the code I use for the Fragments in my FragmentTabHost

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class FragmentExample extends Fragment {
    
        private View rootView;
    
        public FragmentExample() {
        }
    
        @Override
        public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
    
            if (rootView == null) {
    
                rootView = inflater.inflate(R.layout.fragment_example_layout, container, false);
    
                // Initialise your layout here
    
            } else {
                ((ViewGroup) rootView.getParent()).removeView(rootView);
            }
    
            return rootView;
        }
    }
    

    I searched for the following key phrases which I'm adding here, in the hope that I may save someone else from the frustration I've just experienced!


    FragmentTabHost save Fragment state

    FragmentTabHost views recreated

    FragmentTabHost cache Fragments

    FragmentTabHost onCreateView Fragment destroyed


    0 讨论(0)
  • 2021-01-30 17:50
    View mMyView = null;     
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)  {
             if (state == null) {
                 mMyView = new MyView(getActivity());
             } else {
                 container.removeView(mMyView);
             }
    
             return mMyView; 
        }
    
    0 讨论(0)
  • 2021-01-30 18:02

    Update

    I simply avoiding this problem, by using ViewPager instead of ActionBar's tab.

    0 讨论(0)
  • 2021-01-30 18:05

    I faced the same issue, but what I did was, before attaching or detaching the fragement inside the callbacks of ActionBar.TabListener, call

    fragmentManager.executePendingTransactions();
    

    this solves the issue for me

    @Override
    public void onTabelected(Tab tab, FragmentTransaction ft, FragmentManager fm) {
        fm.executePendingTransactions(); // **execute the pending transactions before adding another fragment.
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mContext, mFragmentName);
            ft.replace(android.R.id.tabcontent, mFragment, mTag);
        } else {
            ft.attach(mFragment);
        }
    }
    
    0 讨论(0)
  • 2021-01-30 18:07

    I had the same problem, and tried to follow the suggestion in the error message. I tried the following code, and it worked for me.

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)  {
         if (mMyView == null) {
             mMyView = new MyView(getActivity());
         } else {
             ((ViewGroup) mMyView.getParent()).removeView(mMyView);
         }
    
         return mPuzzleView; 
    }
    
    0 讨论(0)
  • 2021-01-30 18:10

    The following solution works for me. It prevents Fragment's onCreateView to be called when switching tabs.

    Activity's onCreate should add all fragments and hide all except the one for the first tab:

    ft.add(R.id.fragment_content, secondTabFragment);
    ft.hide(secondTabFragment);
    ft.add(R.id.fragment_content, firstTabFragment);
    ft.show(firstTabFragment);
    ft.commit();
    currentFragment = firstTabFragment;
    

    Activity's onTabSelected should just hide the current fragment and show the fragment corresponding to the chosen tab.

    ft.hide(currentFragment);
    ft.show(chosenFragment);
    ft.commit();
    currentFragment = chosenFragment;
    

    Beware that changing the device orientation will restart your Activity and then recreate your Fragments. You can avoid that by adding this configChanges in your Manifest:

    <activity android:configChanges="keyboardHidden|orientation" ...
    
    0 讨论(0)
提交回复
热议问题