Android Weekly Issue #477
Jetpack Compose: styling Text
Text
composable方法:
textDecoration属性
- None
- Underline
- LineThrough
我们可以用combine和plus结合多个效果.
如果只有两个:
Text(
text = "Jetpack Compose: Text",
textDecoration = TextDecoration.Underline
.plus(TextDecoration.LineThrough)
)
如果有多个:
Text(
text = "Jetpack Compose: Text",
textDecoration = TextDecoration.combine(
listOf(
TextDecoration.Underline,
TextDecoration.LineThrough
)
)
)
overflow属性
- Clip: 截断.
- Ellipsis: 末尾带点点点.
- Visibile: 可能会超出范围显示.
style属性
颜色, 字体, 方向, 阴影等.
Text(
text = "Jetpack Compose",
style = TextStyle(
color = Color.Green,
fontSize = 24.sp,
fontFamily = FontFamily.Monospace,
letterSpacing = 4.sp,
textAlign = TextAlign.Center,
shadow = Shadow(
color = Color.Black,
offset = Offset(8f, 8f),
blurRadius = 4f
),
textGeometricTransform = TextGeometricTransform(
scaleX = 2.5f,
skewX = 1f
)
),
modifier = Modifier.width(300.dp)
)
使用AnnotatedString
可以给文字带上多种样式.
eBook sample with Jetpack Window Manager
Microsoft Surface Duo可折叠屏上的Two Page layout.
sample: https://github.com/microsoft/surface-duo-window-manager-samples/tree/main/EBookReader
How does suspension work in Kotlin coroutines?
协程的挂起是如何工作的, 一些简单的例子.
Coroutines (Part I) – Grasping the Fundamentals
协程基础.
Android Sleep API Tutorial: Getting Started
Sleep API: https://developers.google.com/location-context/sleep
系统会收集周围光线和设备运动等信息来假设用户是否在睡觉.
这篇文章可以教你弄个睡眠追踪app.
NavigationRailView MaterialDesign 1.4.0 Stable
- 竖屏下用
BottomNavigationView
. - 横屏下用
NavigationRailView
.
Atomic Updates on MutableStateFlow
如果并发地改stateFlow, 有可能会出现问题.
比如下面这两段代码分别要改不同的字段:
// Assume the state flow value has the following existing properties:
// title: "Default title"
// doneButtonEnabled: false
// Label: Launch A
viewModelScope.launch(Dispatchers.IO) {
val currentValueA = _viewState.value
val newValueA = currentValueA.copy(doneButtonEnabled = true)
_viewState.value = newValueA
}
// Label: Launch B
viewModelScope.launch(Dispatchers.Default) {
val currentValueB = _viewState.value
val newValueB = currentValueB.copy(title = "New Title")
_viewState.value = newValueB
}
很可能第二个修改会覆盖第一个修改的字段.
一种解决方案是用mutex:
val mutex = Mutex()
// Assume the state flow value has the following existing properties:
// title: "Default title"
// doneButtonEnabled: false
// Label: Launch A
viewModelScope.launch(Dispatchers.IO) {
mutex.withLock {
_viewState.value = _viewState.value.copy(doneButtonEnabled = true)
}
}
// Label: Launch B
viewModelScope.launch(Dispatchers.Default) {
mutex.withLock {
_viewState.value = _viewState.value.copy(title = "New title")
}
}
还有一种解决方案就是用Kotlin 1.5的新api:
// Assume the state flow value has the following existing properties:
// title: "Default title"
// doneButtonEnabled: false
// Label: Launch A
viewModelScope.launch(Dispatchers.IO) {
_viewState.update { it.copy(doneButtonEnabled = true) }
}
// Label: Launch B
viewModelScope.launch(Dispatchers.Default) {
_viewState.update { it.copy(title = "New title") }
}
CREATE AN ANIMATED INSTAGRAM-LIKE PROGRESS BAR WITH JETPACK COMPOSE
一个分段的水平progress bar.
Composing composable in the Text line with InlineTextContent in Jetpack Compose
InlineTextContent的使用.
做了一个: LinkedIn/Twitter/Portfolio
的效果.
需要placeholder来占位.
gist在这里:
https://gist.github.com/PatilShreyas/eb81fa1e47c66cf4fb7596d289e68ba9
Code
- https://github.com/mocklets/pluto 在设备上debug, 检查请求/崩溃/ANR等.
- https://github.com/halilozercan/compose-richtext compose的富文本控件, 文档见: https://halilibo.com/compose-richtext/