Lag when switching tabs in BottomNavigationView

拜拜、爱过 提交于 2020-05-15 05:43:05

问题


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.

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


回答1:


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"



回答2:


you can use jetpack navigation for simple bottombar navigation

Simple Bottom Navigation with Jetpack Navigation:

Let’s start by including the Jetpack Navigation library in your apps by adding these lines in app’s build.gradle file:

def nav_version = "2.1.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

We start by creating a simple bottom navigation flow first. For that, you need to do first add NavHostFragment in your single activity layout file. Add this in the activity_main.xml file inside the FrameLayout tag.

<fragment
  android:id="@+id/fragNavHost"
  android:name="androidx.navigation.fragment.NavHostFragment"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:defaultNavHost="true"
  app:navGraph="@navigation/bottom_nav_graph" />

You will see an error saying “Cannot resolve symbol @navigation/bottom_nav_graph .”

    <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/bottom_nav_graph.xml"
    app:startDestination="@id/homeFragment2">

    <fragment
        android:id="@+id/homeFragment2"
        android:name="com.wajahatkarim3.bottomnavigationdemo.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/searchFragment2"
        android:name="com.wajahatkarim3.bottomnavigationdemo.SearchFragment"
        android:label="fragment_search"
        tools:layout="@layout/fragment_search" />

    <fragment
        android:id="@+id/notificationsFragment2"
        android:name="com.wajahatkarim3.bottomnavigationdemo.NotificationsFragment"
        android:label="fragment_notifications"
        tools:layout="@layout/fragment_notifications" />

    <fragment
        android:id="@+id/profileFragment2"
        android:name="com.wajahatkarim3.bottomnavigationdemo.ProfileFragment"
        android:label="fragment_profile"
        tools:layout="@layout/fragment_profile" />
</navigation>

Its time for add some code in our activity class. Open MainActivity.kt file, and create a method setupViews() in it. Call this in onCreate() of the activity. Add these lines in the setupVeiws() method.

    fun setupViews()
{
    // Finding the Navigation Controller
    var navController = findNavController(R.id.fragNavHost)

    // Setting Navigation Controller with the BottomNavigationView
    bottomNavView.setupWithNavController(navController)

    // Setting Up ActionBar with Navigation Controller
    // Pass the IDs of top-level destinations in AppBarConfiguration
    var appBarConfiguration = AppBarConfiguration(
        topLevelDestinationIds = setOf (
            R.id.homeFragment,
            R.id.searchFragment,
            R.id.notificationsFragment,
            R.id.profileFragment
        )
    )
    setupActionBarWithNavController(navController, appBarConfiguration)
}


来源:https://stackoverflow.com/questions/60403240/lag-when-switching-tabs-in-bottomnavigationview

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