使用Navigation Graph+底部导航栏时Home Fragment卡顿,求解决方案
问题描述
使用Navigation组件的Navigation Graph搭配底部导航栏时,切换到Home Fragment会出现轻微卡顿,但切换到其他空白Fragment则无卡顿。尝试用Fragment Transaction切换时非常流畅,但不知道如何将其与Navigation Graph结合——因为使用Navigation组件必须保留app:defaultNavHost="true"和app:navGraph="@navigation/mobile_navigation",移除后使用Nav Graph导航会导致应用崩溃,求解决方案及建议。
相关截图
Main Activity截图

导航栏系统追踪截图

点击Home Fragment时的系统追踪截图

详细系统追踪截图

Home Fragment代码(唯一卡顿的Fragment)
package com.example.ecom.ui.home import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController import com.example.ecom.databinding.FragmentHomeBinding class HomeFragment : Fragment() { private var _binding: FragmentHomeBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val homeViewModel = ViewModelProvider(this)[HomeViewModel::class.java] _binding = FragmentHomeBinding.inflate(inflater, container, false) binding.viewModel = homeViewModel binding.lifecycleOwner = viewLifecycleOwner val popularProductsAdapter = PopularProductsAdapter() val allProductAdapter = PopularProductsAdapter() val categoryAdapter = CategoryAdapter() binding.saleProductsRecycler.adapter = allProductAdapter binding.popularProductsRecycler.adapter = popularProductsAdapter binding.categoryRecycler.adapter = categoryAdapter categoryAdapter.selectedCategory = { homeViewModel.getProductsFromRemote(it) } homeViewModel.categories.observe(viewLifecycleOwner, Observer { categoryAdapter.submitList(it) }) allProductAdapter.selectedProduct = { homeViewModel.displayProductDetails(it) } popularProductsAdapter.selectedProduct = { homeViewModel.displayProductDetails(it) } homeViewModel.navigateSelectedProduct.observe(viewLifecycleOwner, Observer { if (it!=null) { this.findNavController().navigate(HomeFragmentDirections.actionNavigationHomeToProductDetailsFragment(it)) homeViewModel.displayProductDetailsComplete() } }) return binding.root } override fun onDestroyView() { super.onDestroyView() _binding = null } }
Home ViewModel代码
package com.example.ecom.ui.home import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.example.ecom.network.ApiService import com.example.ecom.network.Product import kotlinx.coroutines.* class HomeViewModel : ViewModel() { private val _products = MutableLiveData<List<Product>>() val products: LiveData<List<Product>> get() = _products private val _popularProducts = MutableLiveData<List<Product>>() val popularProducts: LiveData<List<Product>> get() = _popularProducts private val _categories = MutableLiveData<List<String>>() val categories: LiveData<List<String>> get() = _categories private val _status = MutableLiveData<String>() val status: LiveData<String> get() = _status private val _navigateSelectedProduct = MutableLiveData<Product?>() val navigateSelectedProduct: LiveData<Product?> get() = _navigateSelectedProduct private val job = Job() private val coroutineScope = CoroutineScope(job + Dispatchers.Main) init { getCategoryFromRemote() getProductsFromRemote("All") } private fun getCategoryFromRemote() { coroutineScope.launch { val getCategoriesDeferred = ApiService.retrofitService.getCategoriesAsync() try { val listResult = getCategoriesDeferred.await() if(listResult.isNotEmpty()) { val list = mutableListOf<String>() list.add("All") list.addAll(listResult) _categories.value = list } } catch (e: java.lang.Exception) { _status.value = "Failure: ${e.message}" } } } fun getProductsFromRemote(string: String) { coroutineScope.launch { var getProductsDeferred: Deferred<List<Product>>? = null getProductsDeferred = if (string == "All") { ApiService.retrofitService.getProductsAsync() } else { ApiService.retrofitService.getProductsOfCategoryAsync(string) } try { val listResult = getProductsDeferred.await() Log.i("problem", listResult.toString()) if (listResult.isNotEmpty()) { _products.value = listResult val popularProductsList = mutableListOf<Product>() for (i in listResult) { if (i.rating.rate >= 4.0) { popularProductsList.add(i) } } _popularProducts.value = popularProductsList } } catch (e: java.lang.Exception) { _status.value = "Failure: ${e.message}" } } } fun displayProductDetails(product: Product) { _navigateSelectedProduct.value = product } fun displayProductDetailsComplete() { _navigateSelectedProduct.value = null } override fun onCleared() { super.onCleared() job.cancel() } }
内容的提问来源于stack exchange,提问作者Mickey
相关产品推荐
相关产品推荐

