其他
深入详解 Jetpack Compose | 优化 UI 构建
Compose 所解决的问题
Composable 函数剖析
@Composable
fun App(appData: AppData) {
val derivedData = compute(appData)
Header()
if (appData.isOwner) {
EditButton()
}
Body {
for (item in derivedData.items) {
Item(item)
}
}
}
声明式 UI
fun updateCount(count: Int) {
if (count > 0 && !hasBadge()) {
addBadge()
} else if (count == 0 && hasBadge()) {
removeBadge()
}
if (count > 99 && !hasFire()) {
addFire()
setBadgeText("99+")
} else if (count <= 99 && hasFire()) {
removeFire()
}
if (count > 0 && !hasPaper()) {
addPaper()
} else if (count == 0 && hasPaper()) {
removePaper()
}
if (count <= 99) {
setBadgeText("$count")
}
}
@Composable
fun BadgedEnvelope(count: Int) {
Envelope(fire=count > 99, paper=count > 0) {
if (count > 0) {
Badge(text="$count")
}
}
}
这里我们定义:
当数量大于 99 时,显示火焰;
当数量大于 0 时,显示纸张;
当数量大于 0 时,绘制数量气泡。
组合 vs 继承
class Input : View() { /* ... */ }
class ValidatedInput : Input() { /* ... */ }
class DateInput : ValidatedInput() { /* ... */ }
class DateRangeInput : ??? { /* ... */ }
@Composable
fun <T> Input(value: T, onChange: (T) -> Unit) {
/* ... */
}
@Composable
fun ValidatedInput(value: T, onChange: (T) -> Unit, isValid: Boolean) {
InputDecoration(color=if(isValid) blue else red) {
Input(value, onChange)
}
}
@Composable
fun DateInput(value: DateTime, onChange: (DateTime) -> Unit) {
ValidatedInput(
value,
onChange = { ... onChange(...) },
isValid = isValidDate(value)
)
}
@Composable
fun DateRangeInput(value: DateRange, onChange: (DateRange) -> Unit) {
DateInput(value=value.start, ...)
DateInput(value=value.end, ...)
}
class FancyBox : View() { /* ... */ }
class Story : View() { /* ... */ }
class EditForm : FormView() { /* ... */ }
class FancyStory : ??? { /* ... */ }
class FancyEditForm : ??? { /* ... */ }
@Composable
fun FancyBox(children: @Composable () -> Unit) {
Box(fancy) { children() }
}
@Composable fun Story(…) { /* ... */ }
@Composable fun EditForm(...) { /* ... */ }
@Composable fun FancyStory(...) {
FancyBox { Story(…) }
}
@Composable fun FancyEditForm(...) {
FancyBox { EditForm(...) }
}
封装
重组
fun bind(liveMsgs: LiveData<MessageData>) {
liveMsgs.observe(this) { msgs ->
updateBody(msgs)
}
}
@Composable
fun Messages(liveMsgs: LiveData<MessageData>) {
val msgs by liveMsgs.observeAsState()
for (msg in msgs) {
Message(msg)
}
}
总结
推荐阅读
Modified on