今天大概会聊到的范围
- Android View
前两天来回进出了公司楼下的 7-11 两三次,每次都要扫一次实名制的 QR Code。我现在用的 App 又有点笨,每次扫完之後都还要手动选要送 SMS(也是啦,又不是专门为 1922 开发的 App)。不过,作为工程师的好处是,当有件事情无法满足你的需求,你可以自己开发东西来改变它!於是,我想要自己写一个 QR Code Scanner 而且能认得 1922 的格式自动送 SMS。
我想说,QR Code Scanner 之前有试着做过,没有很复杂。用 CameraX 配上 MLKit 应该就可以达成了吧! 打开 Android Studio,熟悉的建立了一个 Compose App,然後插入 CameraPreview ....
等等!没有 XML 我要怎麽放 CameraPreview?
在 Compose 中放入 Android view
Compose 中,有一个 Composable 叫做 AndroidView 。在 AndroidView 中,我们可以摆放继承 View 的元件。
@Composable
fun Screen() {
AndroidView(
factory = { context ->
val view = // create view
view
}
)
}
举个例,Compose 的 Text 并没有直接显示 html 的功能,但是 android.widget 的 TextView 可以吃转成 html 的 Spanable。所以可以透过 AndroidView 来使用 TextView 。
@Composable
fun TextViewHtml() {
val html = """
<h3">Title</h3>
<hr>
<ul>
<li><p>First</p></li>
<li><p>Second</p></li>
</ul>
""".trimIndent()
AndroidView(
factory = { context ->
val textView = TextView(context)
textView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
HtmlCompat.fromHtml(html, 0)
} else {
Html.fromHtml(html)
}
textView
},
modifier = Modifier.background(color = Color.White)
)
}
除了熟悉的 modifier 参数外,AndroidView 需要一个负责产生 view 的 factory lambda,这个 Lambda 中可以取得 context ,透过这个 context 可以产生出 Android 的 View。
除了 factory 外,还可以提供另一个 lambda update,因为 composable 会在 recomposition 时重新绘制,但是每次重新绘制都产生一个新的 android view 太浪费了。所以 factory 其实不会在 recomposition 被触发。要改变 AndroidView 中的内容的话,需要透过 update 参数可以告诉 AndroidView 我们要使用的 view 如何变动。
@Composable
fun <T : View> AndroidView(
factory: (Context) -> T,
modifier: Modifier = Modifier,
update: (T) -> Unit = NoOpUpdate
) { ... }
@Composable
fun TextViewHtml() {
var data by remember { mutableStateOf(0) }
AndroidView(
factory = { context ->
val html = """
<h3">Title</h3>
<br/>
<p>$data</p>
""".trimIndent()
val textView = TextView(context)
textView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
HtmlCompat.fromHtml(html, 0)
} else {
Html.fromHtml(html)
}
textView
},
update = { textView: TextView -> // <-- update 中可以拿到 factory 建立的 view
val html = """
<h3">Title</h3>
<br/>
<p>$data</p>
""".trimIndent()
textView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
HtmlCompat.fromHtml(html, 0)
} else {
Html.fromHtml(html)
}
},
modifier = Modifier.fillMaxWidth().background(color = Color.White).clickable { data += 1 }
)
}
今天的题目比较小,但却是非常实用的东西。有了 AndroidView 我就可以将 CameraX 放进 Compose 专案了。
但实际上还一些问题没解,例如如何在取得 camera permission 之後触发 recomposition 。这些,就等後续分享吧!
<<: LeetCode 双刀流:Stack 与 Queue 的相互实作
GitHub Repo https://github.com/b2etw/Spring-Kotlin...
这是第一次参加铁人赛,期待自己可以依照书上的教学将Kotlin学好,并具备开发小型系统的能力。 此次...
Day 26 Docker-Compose nginx + flask container with...
我对VR的第一印象,就是一个人戴着罩住眼睛的头盔,手拿着摇杆的游戏。但是这个软件到底要怎麽制作,且是...
// 移动到档案路径 cd "档案路径" // 确认git版本并有无正确安装 g...