Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lag when switching tabs in BottomNavigationView

I have an Activity that contains a BottomNavigationView, and this bottomnav helps the activity to display three fragments. These fragments load well, and I use an AsyncTask to do every heavy operation, while in the UI thread, I show a ProgressBar until everything loads.
There is a weird behaviour with my fragment: The first time I load the fragment it takes some time to actually display it, instead of displaying it instantly with a progressbar.
This thing only happens the first time, and only in this fragment.
The fragment code only contains this:

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        new LoadData(getView(), getContext()).execute();
    }

private class LoadData extends AsyncTask<Void, Void, Void> {

        private View v;
        private Context context;

        public LoadData(View v, Context context) {
            items = new ArrayList<>();
            this.v = v;
            this.context = context;
        }

        @Override
        protected Void doInBackground(Void... voids) {
            setItems(context); //Heavy operation
            adapter = new DashAdapter(items, context);
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //shows progressbar
            progress = v.findViewById(R.id.DFProgress);
            progress.setVisibility(View.VISIBLE);
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            setPager();
            //sets viewPager and hides progressbar
            progress.setVisibility(View.GONE);
        }
    }

In the gif below, if you look at the bottomnavigationview at the bottom, you can see that it takes time to display the fragment. But after trying to load the fragment a second time, it loads as expected. enter image description here

How could I make the fragment to load the right way?

like image 616
RushedPotato Avatar asked Feb 25 '20 21:02

RushedPotato


People also ask

What is bottomnavigationview in Android?

T he BottomNavigationView is the latest design trend for Android development, as seen in several example apps below. Each of the tabs could have a stack of fragments shown, and user could swap between them. With this, we hope when we tap across the bottom navigation, the Fragments will be reloaded accordingly.

How do I Turn Off Alt-Tab lag?

Go to Settings > System > Focus Assist and toggle the switch off. You can also set a time range for it to automatically be disabled. Hopefully this helps reduce your alt-tab lag!

How to save fragment state when switch the tab in Android?

The trick to it, is having the ability to save Fragment state when we switch the tab. Android does gave us ability to get the SavedState using saveFragmentInstanceState function as below.


1 Answers

I had the same problem. I have two options.

  1. Use postdelay when you call LoadData or
  2. First add all fragments with manually. You manage navigationItemSelected yourself.

Like this:

val firstFragment: Fragment = FirstFragment()
val secondFragment: Fragment = SecondFragment()
val thirdFragment: Fragment = ThirdFragment()

val navView: BottomNavigationView = findViewById(R.id.nav_view)

var active = firstFragment
fm.beginTransaction().add(R.id.nav_host_fragment, thirdFragment, "3").hide(thirdFragment).commit()
fm.beginTransaction().add(R.id.nav_host_fragment, secondFragment, "2").hide(secondFragment).commit()
fm.beginTransaction().add(R.id.nav_host_fragment, firstFragment, "1").commit()

navView.setOnNavigationItemReselectedListener {  }
navView.setOnNavigationItemSelectedListener { item ->
       when (item.itemId) {
           R.id.navigation_first -> {
               fm.beginTransaction().hide(active).show(firstFragment).commit()
               active = firstFragment

           }
           R.id.navigation_second -> {
               fm.beginTransaction().hide(active).show(secondFragment).commit()
               active = secondFragment
           }
           R.id.navigation_third -> {
               fm.beginTransaction().hide(active).show(thirdFragment).commit()
               active = thirdFragment
           }
       }
        true
   }

And remove these lines in your nav_host_fragment:

app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation"
like image 160
Kasım Özdemir Avatar answered Oct 03 '22 01:10

Kasım Özdemir