2024/03/01
密封类
在安卓开发中,Sealed Class(密封类)是一种特殊的类别,它用于表示受限的类继承结构。密封类可以有多个子类,但是这些子类必须是在密封类内部定义的,并且在同一个文件中。
密封类在类定义前使用 sealed 关键字进行声明。它的目的是为了限制类的继承结构,确保所有的子类都是已知的,并且不允许在其他文件或类中进行扩展。这样可以提供更好的代码组织和类型安全性。
当使用密封类时,通常会在代码中使用 when 表达式来处理密封类的实例。when 表达式会检查密封类的所有可能子类,并针对每个子类提供相应的分支处理逻辑。由于密封类的子类是有限的,因此编译器可以在 when 表达式中确保所有情况都被处理,从而避免遗漏分支的问题。
以下是一个简单的示例,展示了如何使用密封类和 when 表达式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sealed class Result data class Success(val data: String) : Result() data class Error(val message: String) : Result()
fun handleResult(result: Result) { when (result) { is Success -> { println("Success: ${result.data}") } is Error -> { println("Error: ${result.message}") } } }
|
在这个例子中,Result 是一个密封类,它有两个子类 Success 和 Error。handleResult 函数使用了 when 表达式来处理不同的 Result 实例,并根据实例的类型执行相应的操作。
通过使用密封类,可以明确知道 Result 只有 Success 和 Error 两个子类,从而确保所有可能的情况都被处理,避免了潜在的逻辑错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package com.samsung.recipeapp
import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.rememberAsyncImagePainter import java.time.format.TextStyle
@Composable fun RecipeScreen(modifier: Modifier = Modifier) { val recipeViewModel: MainViewModel = viewModel() val viewState by recipeViewModel.categoriesState Box(modifier = Modifier.fillMaxSize()) { when { viewState.loading -> { CircularProgressIndicator(modifier.align(Alignment.Center)) } viewState.error != null -> { Text(text = "Error Occurred") } else -> { CategoryScreen(categories = viewState.categories) } } } }
@Composable fun CategoryScreen(categories: List<Category>){ LazyVerticalGrid(GridCells.Fixed(2), modifier = Modifier.fillMaxSize()){ items(categories) { category -> CategoryItem(category = category) } } }
@Composable fun CategoryItem(category: Category) { Column(modifier = Modifier .padding(8.dp) .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) { Image(painter = rememberAsyncImagePainter(model = category.strCategory), contentDescription = null, modifier = Modifier.fillMaxSize().aspectRatio(1f)) Text( text = category.strCategory, color = Color.Black, style = androidx.compose.ui.text.TextStyle(fontWeight = FontWeight.Bold), modifier = Modifier.padding(top=4.dp) ) } }
|