错误处理与用户体验
使用密封类对 UI 状态进行建模(Loading/Success/Error)。显示 ProgressBar,使用带有重试操作的 Snackbar,并以内嵌方式显示 TextInputLayout 验证错误。
错误处理与用户体验 是 CoddyKit 上的免费 Android Academy 课时。 这是第 3 节课,共 6 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 6 节课。
为什么错误处理很重要
应用无故崩溃或卡住,会让用户觉得它无法正常工作。用户不知道发生了什么,也不知道接下来该做什么。
良好的错误处理意味着:
- 应用保持稳定
- 用户能看到清晰的提示
- 用户可以重试或采取相应操作
这就是应用获得 2 星评价和 5 星评价之间的差别。
对界面状态建模
一种简洁的模式是:使用密封类对所有可能的界面状态进行建模:
Loading— 请求正在进行Success(data)— 数据已准备就绪Error(message)— 发生了问题
ViewModel 发出其中一种状态,界面负责将其呈现出来。
密封类 UiState
为所有可能的状态定义一个密封类:
sealed class UiState<out T> {
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String) : UiState<Nothing>()
}
// In ViewModel:
private val _state = MutableLiveData<UiState<List<Post>>>()
val state: LiveData<UiState<List<Post>>> = _state
fun loadPosts() {
_state.value = UiState.Loading
viewModelScope.launch {
try {
val posts = withContext(Dispatchers.IO) { repo.getPosts() }
_state.value = UiState.Success(posts)
} catch (e: Exception) {
_state.value = UiState.Error(e.message ?: "Unknown error")
}
}
}在界面中呈现状态
观察状态,并针对每种情况显示正确的视图:
viewModel.state.observe(this) { state ->
when (state) {
is UiState.Loading -> {
binding.progressBar.visibility = View.VISIBLE
binding.recyclerView.visibility = View.GONE
binding.tvError.visibility = View.GONE
}
is UiState.Success -> {
binding.progressBar.visibility = View.GONE
binding.recyclerView.visibility = View.VISIBLE
adapter.submitList(state.data)
}
is UiState.Error -> {
binding.progressBar.visibility = View.GONE
binding.tvError.text = state.message
binding.tvError.visibility = View.VISIBLE
}
}
}使用 ProgressBar 表示加载中
等待数据时显示 ProgressBar:
- 使用
android:indeterminate="true"显示旋转式加载指示器 - 在
View.VISIBLE和View.GONE之间切换可见性 GONE会将视图从布局中移除(不只是不可见——它不会占用空间)
Snackbar 与 Toast
显示错误消息时,优先使用 Snackbar,而不是 Toast:
- Snackbar 可以包含操作按钮(例如“重试”)
- 它附着在当前屏幕上,不会浮在其他应用上方
- 它会自动消失,也可以通过点击关闭
带重试功能的 Snackbar
显示带有“重试”操作按钮的错误提示:
import com.google.android.material.snackbar.Snackbar
fun showError(message: String) {
Snackbar.make(
binding.root, // root view of the screen
message,
Snackbar.LENGTH_INDEFINITE // stays until dismissed
).setAction("Retry") {
viewModel.loadPosts() // retry the request
}.show()
}输入验证
将用户输入发送到服务器之前,请先进行验证:
- 使用带有
error属性的TextInputLayout,在输入框下方显示行内错误 - 调用 API 前检查空字段、电子邮件格式和密码长度
- 用户开始输入时清除错误
TextInputLayout 错误
在表单字段中显示行内验证错误:
fun validateAndSubmit() {
val email = binding.etEmail.text.toString().trim()
val password = binding.etPassword.text.toString()
var hasError = false
if (email.isBlank() || !email.contains("@")) {
binding.tilEmail.error = "Enter a valid email"
hasError = true
} else {
binding.tilEmail.error = null // clear error
}
if (password.length < 6) {
binding.tilPassword.error = "Minimum 6 characters"
hasError = true
} else {
binding.tilPassword.error = null
}
if (!hasError) viewModel.login(email, password)
}快速检查
哪种视图可见性状态会将视图从布局中完全移除(不占用空间)?
回顾:错误处理与用户体验
现在,您的应用已经可以妥善处理错误:
- 使用密封类将状态建模为 Loading / Success / Error
- 加载期间显示 ProgressBar
- 网络错误时显示带有“重试”操作的 Snackbar
- 使用 TextInputLayout 为表单验证显示行内错误
View.GONE与View.INVISIBLE— 移除与隐藏
最后一课:将您的应用发布到 Play 商店!
常见问题解答
「错误处理与用户体验」课时是免费的吗?
是的 — 「错误处理与用户体验」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 6 节课。
「错误处理与用户体验」这节课中我会学到什么?
使用密封类对 UI 状态进行建模(Loading/Success/Error)。显示 ProgressBar,使用带有重试操作的 Snackbar,并以内嵌方式显示 TextInputLayout 验证错误。 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 6 节。
「错误处理与用户体验」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。