美文网首页
Android 关于网络请求和 UI 状态的对应关系

Android 关于网络请求和 UI 状态的对应关系

作者: 雁过留声_泪落无痕 | 来源:发表于2022-04-11 10:52 被阅读0次

    背景

    如何处理网络请求和 UI 状态的对应关系,并没有严格的限制或者说对错之分,主要还是看是否适合自己的业务。

    这里给出一种相对通用点的方案。

    封装

    参考 关于Kotlin中的Nothing - 掘金 (juejin.cn)

    sealed class Result<out R> {
        object Loading : Result<Nothing>()
        class Success<out T>(val result: T) : Result<T>()
        class Error(val exception: Exception) : Result<Nothing>()
    }
    

    一次性请求的界面

    对于一次性请求的界面(简单理解就是没有下拉刷新),UI 状态应该为:

    • 请求返回正常的列表数据
      EmptyView -> Loading -> ResultList
    • 请求返回空列表
      EmptyView -> Loading -> EmptyView
    • 请求发生错误
      EmptyView -> Loading -> ErrorView
    class MyViewModel : ViewModel() {
        private val _testLiveData = MutableLiveData<Result<List<Int>>>()
        val testLiveData: LiveData<Result<List<Int>>> = _testLiveData
    
        fun getList() {
            _testLiveData.value = Result.Loading
            // get list from internet
            try {
                _testLiveData.value = API.getList()
            } catch (e: java.lang.Exception) {
                _testLiveData.value = Result.Error(e)
            }
        }
    }
    
    class MyActivity : AppCompatActivity() {
    
        private fun showLoading() {
            // loading view
        }
    
        private fun showData(data: List<Int>) {
            // result list
            data?.let {
            }
        }
    
        private fun showError() {
            // include a retry button.
        }
    
        fun test() {
            val viewModel = MyViewModel()
            viewModel.testLiveData.observe(this) { result ->
                when (result) {
                    is Result.Loading -> showLoading()
                    is Result.Success -> showData(result.result)
                    is Result.Error -> showError()
                }
            }
        }
    }
    

    可重复请求的界面

    对于可重复发起请求的界面(简单理解为有下拉刷新),不同的点在于如果发生错误,应该先判断下当前界面是否为空界面,如果为空则显示 ErrorView;已经有数据显示出来的情况下就弹个 Toast 即可,这样就不会让之前的列表数据变为不可见(同时,这种情况下是不需要展示 Retry 按钮的,因为再次下拉就相当于点击重试按钮了)。

    fun test() {
        val viewModel = MyViewModel()
        viewModel.testLiveData.observe(this) { result ->
            when (result) {
                is Result.Loading -> showLoading()
                is Result.Success -> showData(result.result)
                is Result.Error -> {
                    if (recyclerViewAdapter.isEmpty()) {
                        showError()
                    } else {
                        ToastUtils.showShort(result.exception.message)
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Android 关于网络请求和 UI 状态的对应关系

          本文链接:https://www.haomeiwen.com/subject/txrisrtx.html