Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restoring fragment state when changing fragments through bottom navigation bar

Tags:

I have bottom navigation bar on click of item in navigation bar i am replacing fragments. I have 3 fragments A,B,C so on click of b item B fragment is loaded and in B i am calling 3-4 APIs. So now if i go to C and then again come to B a new instance of B Fragment is created and again those APIs are called how can i save the fragment instance state and not call APIs again while changing fragments. This is my code.

mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {         @Override         public boolean onNavigationItemSelected(@NonNull MenuItem item) {             int id = item.getItemId();             Fragment currentLoaded = fgMan.findFragmentById(R.id.container_body);             switch (id) {                 case R.id.nearby_fragment:                     if (!(currentLoaded instanceof SpotFeedMapFragment)) {                         removeScroll();                         mNearByFragment = fgMan.findFragmentByTag(NEARBY_FRAGMENT_TAG) != null ? fgMan.findFragmentByTag(NEARBY_FRAGMENT_TAG) : mNearByFragment;                         fgMan.beginTransaction().setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);                         fgMan.beginTransaction().replace(R.id.container_body, mNearByFragment, NEARBY_FRAGMENT_TAG).commit();                         fgMan.executePendingTransactions();                         getSupportActionBar().setTitle(getString(R.string.nearby_fragment));                     }                     break;                 case R.id.route_fragment:                     if (!(currentLoaded instanceof BusLocationsFragment)) {                         if (!inParent) {                             mRl.removeView(fixLayout);                             p.addRule(RelativeLayout.BELOW, toolbar.getId());                             scrollView.setLayoutParams(p);                             scrollView.addView(fixLayout);                             mRl.addView(scrollView);                             inParent = true;                         }                         //mFragment = new BusLocationsFragment();                         mBusLocFragment = fgMan.findFragmentByTag(BUS_LOC_FRAGMENT_TAG) != null ? fgMan.findFragmentByTag(BUS_LOC_FRAGMENT_TAG) : mBusLocFragment;                         fgMan.beginTransaction().setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);                         fgMan.beginTransaction().replace(R.id.container_body, mBusLocFragment, BUS_LOC_FRAGMENT_TAG).commit();                         fgMan.executePendingTransactions();                         getSupportActionBar().setTitle(getString(R.string.app_name));                     }                     break;                 case R.id.newsfeed_activity:                     if (!(currentLoaded instanceof NewsFeedActivity)) {                         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {                             removeScroll();                         }                         mNewsFeedFragment = fgMan.findFragmentByTag(NEWSFEED_FRAGMENT_TAG) != null ? fgMan.findFragmentByTag(NEWSFEED_FRAGMENT_TAG) : mNewsFeedFragment;                         fgMan.beginTransaction().setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);                         fgMan.beginTransaction().replace(R.id.container_body, mNewsFeedFragment, NEWSFEED_FRAGMENT_TAG).commit();                         fgMan.executePendingTransactions();                         getSupportActionBar().setTitle(getString(R.string.news));                     }                     break;             }             return true;         }     }); 

I have already initialized fragments member variables above in onCreateof MainActivity

like image 640
user007 Avatar asked Mar 14 '17 08:03

user007


1 Answers

You should use a FragmentPagerAdapter to initiate the fragments so when you want to switch in between them, the state of the fragments will be saved.

CutomViewPager viewPager = (CustomViewPager) findViewById(R.id.viewpager1); ViewPagerAdapter adapter = new ViewPagerAdapter (MainActivity.this.getSupportFragmentManager()); adapter.addFragment(new SpotFeedMapFragment(), "title"); adapter.addFragment(new BusLocationsFragment(), "title"); adapter.addFragment(new NewsFeedActivity(), "title"); viewPager.setAdapter(adapter); 

then in the bottom navigation selected you can set fragment by simple command

viewPager.setCurrentItem(n); 

my viewpager class is as follows:

public class CustomViewPager extends ViewPager {  private boolean isPagingEnabled;  public CustomViewPager(Context context) {     super(context);     this.isPagingEnabled = true; }  public CustomViewPager(Context context, AttributeSet attrs) {     super(context, attrs);     this.isPagingEnabled = true; }  @Override public boolean onTouchEvent(MotionEvent event) {     return this.isPagingEnabled && super.onTouchEvent(event); }  //for samsung phones to prevent tab switching keys to show on keyboard @Override public boolean executeKeyEvent(KeyEvent event) {     return isPagingEnabled && super.executeKeyEvent(event); }  @Override public boolean onInterceptTouchEvent(MotionEvent event) {     return this.isPagingEnabled && super.onInterceptTouchEvent(event); }  public void setPagingEnabled(boolean enabled) {     this.isPagingEnabled = enabled; } } 

in the xml instead of a empty layout for fragemnt u need:

<com.package.util.CustomViewPager     android:id="@+id/viewpager1"     android:layout_width="match_parent"     android:layout_height="match_parent" /> 

Code for custom FragmentPagerAdapter:

private class ViewPagerAdapter extends FragmentPagerAdapter {     private final SparseArray<WeakReference<Fragment>> instantiatedFragments = new SparseArray<>();     private final List<Fragment> mFragmentList = new ArrayList<>();     private final List<String> mFragmentTitleList = new ArrayList<>();      ViewPagerAdapter(FragmentManager manager) {         super(manager);     }      @Override     public Fragment getItem(int position) {         return mFragmentList.get(position);     }      @Override     public int getCount() {         return mFragmentList.size();     }      void addFragment(Fragment fragment, String title) {         mFragmentList.add(fragment);         mFragmentTitleList.add(title);     }      @Override     public Object instantiateItem(ViewGroup container, int position) {         final Fragment fragment = (Fragment) super.instantiateItem(container, position);         instantiatedFragments.put(position, new WeakReference<>(fragment));         return fragment;     }      @Override     public void destroyItem(ViewGroup container, int position, Object object) {         instantiatedFragments.remove(position);         super.destroyItem(container, position, object);     }      @Nullable     Fragment getFragment(final int position) {         final WeakReference<Fragment> wr = instantiatedFragments.get(position);         if (wr != null) {             return wr.get();         } else {             return null;         }     }      @Override     public CharSequence getPageTitle(int position) {         return mFragmentTitleList.get(position);     } } 
like image 142
Harsh Ganatra Avatar answered Sep 17 '22 19:09

Harsh Ganatra