今天大概会聊到的范围
- ComposeView
之前有介绍过 Compose 中的 AndroidView ,是一个可以在 Compose 中放入一般 Android View 。那如果我们要在一般的 Android 专案中放入 Compose 呢? 有几个方法可以在原先 Android 的专案中加入 Compose
之前有介绍过 Compose compiler 的运作机制,那些转换都是透过 Kotlin 在 1.5 新增的 JVM IR compiler backend 。另外,Android Studio 也只有在 Arctic Fox 之後的版本才有支援 Compose、Android Build Tool 也需要在 7.0 以上:
// project-level build.gradle
buildscript {
...
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
...
}
}
// module-level build.gradle
android {
...
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
...
}
准备就绪,开始导入 Compose 吧!先加入 Compose 相关的 library:
dependencies {
// Integration with activities
implementation 'androidx.activity:activity-compose:1.3.1'
// Compose Material Design
implementation 'androidx.compose.material:material:1.0.1'
// Animations
implementation 'androidx.compose.animation:animation:1.0.1'
// Tooling support (Previews, etc.)
implementation 'androidx.compose.ui:ui-tooling:1.0.1'
// Integration with ViewModels
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07'
// UI Tests
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.1'
}
如果整个页面都可以使用 Compose 来建制的话,我们可以用我们学习 Compose 以来常常见到的好朋友 setContent function 来加入 Composable:
// 记得要加入 'androidx.activity:activity-compose:1.3.1'
class InteropActivity : AppCompatActivity() { // <-- 一般的 AppCompactActivity 就有继承 ComponentActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { // <-- setContent 是 compose 在 ComponentActivity 身上加上的 extension fucntion
ComposeScreen() // <--- 这里就可以放 Composable 了
}
}
}
如果只有 Activity 中的某个部分想转成 Compose,在 xml 中使用 ComposeView :
// in xml
<LinearLayout ...>
...
<androidx.compose.ui.platform.ComposeView
android:id="@+id/interopComposeView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
...
</LinearLayout>
// in activity
class InteropActivity : AppCompatActivity() {
private lateinit var binding: ActivityInteropBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityInteropBinding.inflate(layoutInflater) // <-- 这里是用 ViewBinding。一般的 findViewById 也可以喔
val root = binding.root
binding.interopComposeView.setContent {
// composable // ComposeView 有 setContent function 可以放入 composable
}
setContentView(root)
}
}
没特别设定的话,ComposeView 会在 该 View detach window 时触发 dispose。但是这可能不是期望的行为,例如在 Fragment 中我们可能希望跟着 Fragment 的 Lifecycle。
ComposeView 有 setViewCompositionStrategy function 可以使用,调整 dispose 的策略:
就这样,把 ComposeView 当成一般的 View 放在 Android 内,再配合之前研究到的 AndroidView 就可以慢慢将计有专案 migrate 到 Compose 上罗!
Reference:
<<: Day24【Web】网路传输协定:TCP 与 UDP
C# BASE64 原由:厂商丢了编成 Base64 字串的东西来,接到後,要把它还原. strin...
Q: 终於要讲效能了! A: 以Loading为范例讲黑~ Animation Loading 直...
人工智慧8 前言 系列文章简介 大家好,我们是 AI . FREE Team - 人工智慧自由团队,...
今天要接触我们的Javascript,让网页更多动画,互动性,不是一个只有图片跟文字的死板网页,而J...
Windows Web Form(C#) import Web API 步骤一 :先新增或使...