如何在 Android 电子商务应用程序中同步数据检索和 UI 更新?

问题描述 投票:0回答:1

我正在开发一个用于电子商务的 Android 应用程序,我面临着一个挑战,即在完全检索所需数据之前创建用户界面。因此,在检索过程完成之前,应用程序无法正确显示数据。

这是我目前遵循的工作流程:

  1. 用户导航到从远程服务器或数据库获取数据(例如产品详细信息、类别等)的屏幕。

  2. 布局立即膨胀,像

    TextView
    RecyclerView
    这样的视图显示为空或不正确,因为数据尚未准备好。

  3. 最终检索数据时(使用协程或类似的异步方法),我手动更新 UI。

这种方法会造成令人不满意的用户体验,因为在数据到达之前屏幕看起来不完整。

片段类

class HomePageFragment : Fragment() {



    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        checkCategoryCallBack()
        checkDealOfTheDayCallBack()
        onClick()
    }

    private fun checkDealOfTheDayCallBack() {
        homePageViewModel.gotDealOfTheDaySuccess.observe(viewLifecycleOwner) {
            if (it == true) {
                getDealOfTheDay()
            } else {
                homePageViewModel.getDealOfTheDay()
            }
        }
    }

    private fun checkCategoryCallBack() {
        homePageViewModel.gotCategorySuccess.observe(requireActivity()) {
            if (it == true) {
                getCategories()
            } else {
                homePageViewModel.getCategories()
            }
        }
    }

    private fun getCategories() {

        homePageViewModel.categoriesList.observe(requireActivity()) {
            categoryAdapter = CategoryAdapter(it)
        }
        binding.rvCatefory.adapter = categoryAdapter
    }

    private fun getDealOfTheDay() {
        homePageViewModel.dealOfTheDayList.observe(requireActivity()) {
            productAdapter = ProductAdapter(it)
        }
        binding.rvDealOfTheDay.adapter = productAdapter
    }


 

}

视图模型

class HomePageViewModel : ViewModel() {


    fun getCategories() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                _categoriesList.postValue(HomePageRepository.getCategories())
                _gotCategorySuccess.postValue(true)

            } catch (e: Exception) {
                _gotCategorySuccess.postValue(false)
            }
        }
    }


    fun getDealOfTheDay() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                _dealOfTheDayList.postValue(HomePageRepository.getDealOfTheDayProduct())
                _gotDealOfTheDaySuccess.postValue(true)
            } catch (e: Exception) {
                _gotDealOfTheDaySuccess.postValue(false)
            }
        }
    }
}

在 Android 中同步 UI 更新和异步数据检索的最佳实践是什么?具体来说,我正在寻找以下解决方案:

  1. 确保数据到达时 UI 动态更新。

  2. 改善数据检索期间的用户体验(例如占位符、加载指示器等)。

  3. 处理数据检索失败的场景(例如,没有互联网连接或 API 错误)。

我想知道可以解决这个问题的推荐方法或设计模式(例如,MVVM、StateFlow、LiveData 等)。如果有工具、库或技术可以使此过程更加顺利,请告诉我。

android multithreading kotlin mvvm kotlin-coroutines
1个回答
0
投票
  1. 你的实现是不正确的,因为每次new数据到达时,它都会创建一个新的Adapter对象。因此,它不会利用View重用。您需要将新项目添加到列表中并调用NotifiDataItemChange()。但是,还有另一种方法可以使用 ListAdapter 作为 recyclerView 的适配器。当有任何变化时它会自动更新视图并且具有更好的性能

  2. 处理recyclerView页面分页,加载时有很好的UI效果,处理错误。您可以使用分页库。

  3. 您应该使用的设计模式。使用 MVVM + livedataMVVM + StateFlow 。您应该只使用两者之一(而不是两者)以使维护更容易。

以下是为了满足该需求而对代码进行的编辑:

主页片段

class HomePageFragment : Fragment() {
    private val categoryAdapter: CategoryAdapter by lazy {
        CategoryAdapter(listOf<Any>())
    }
    private val productAdapter : ProductAdapter by lazy {
        ProductAdapter(listOf<Any>())
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        setupCategoryRecyclerView()
        setupDealOfTheDayRecyclerView()
        getCategories()
        getDealOfTheDay()
        onClick()
    }

    private fun getCategories() {
        homePageViewModel.getCategories()
    }

    private fun getDealOfTheDay() {
        homePageViewModel.getDealOfTheDay()
    }

    private fun setupCategoryRecyclerView() {
        binding.rvCatefory.adapter = categoryAdapter

        homePageViewModel.categoriesList.observe(requireActivity()) {
            categoryAdapter.submitList(it)
        }
        homePageViewModel.gotCategorySuccess.observe(requireActivity()) {
            
            // control when success or error ...
        }
    }

    private fun setupDealOfTheDayRecyclerView() {
        binding.rvDealOfTheDay.adapter = productAdapter

        homePageViewModel.dealOfTheDayList.observe(requireActivity()) {
            productAdapter = productAdapter.submitList(it)
        }

        homePageViewModel.gotDealOfTheDaySuccess.observe(requireActivity()) {
            //control when success or error 
        }
    }
}

使用ListAdapter,您只需要添加项目,不需要进一步处理。当有新数据可用时,它会自动更新。

调用Api的时间根据公司的要求而定。但大多数情况下它会显示加载屏幕、占位符。

通常情况下,我会显示正在加载等待Api调用,当调用完成后我会隐藏它

© www.soinside.com 2019 - 2024. All rights reserved.