使用AndroidView创建日历
@Composable
fun AndroidViewPage() {
AndroidView(
factory = {
CalendarView(it)
},
modifier = Modifier.fillMaxWidth(),
update = {
it.setOnDateChangeListener { view, year, month, day ->
Toast.makeText(
view.context, "${year}年${month + 1}月${day}日",
Toast.LENGTH_LONG
).show()
}
}
)
}
使用Android原生视图需要引入AndroidView组件,factory属性中加入CalendarView日历视图组件,update属性中设置日历的点击事件。
使用WebView
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SetJavaScriptEnabled")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WebViewPage() {
val webView = rememberWebViewWithLifecycle()
Scaffold(
content = {
AndroidView(
factory = {
webView
}, modifier = Modifier
.fillMaxSize()
.background(Color.Red),
update = { webView ->
// 设置支持JavaScript
val webSettings = webView.settings
webSettings.javaScriptEnabled = true
webView.loadUrl("https://www.baidu.com")
}
)
}
)
}
@Composable
fun rememberWebViewWithLifecycle(): WebView {
val context = LocalContext.current
val webView = remember {
WebView(context)
}
val lifecycleObserver = rememberWebViewLifecycleObserver(webView)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return webView
}
@Composable
private fun rememberWebViewLifecycleObserver(webView: WebView): LifecycleEventObserver =
remember(webView) {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> webView.onResume()
Lifecycle.Event.ON_PAUSE -> webView.onPause()
Lifecycle.Event.ON_DESTROY -> webView.destroy()
else -> Log.e("WebView", event.name)
}
}
}
使用Android布局
使用Android布局用到了Viewbinding,这里需要引入ui-viewbinding库
implementation "androidx.compose.ui:ui-viewbinding:1.5.0-alpha01"
这是android_view.xml原生页面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:hint="name" />
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:hint="password"
android:inputType="textPassword" />
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAllCaps="false"
android:layout_marginTop="30dp"
android:text="Login" />
</LinearLayout>
Compose中使用原生布局并操作
@Composable
fun AndroidViewBindingPage() {
val context = LocalContext.current
AndroidViewBinding(
factory = { inflate, parent, attachToParent ->
AndroidViewBinding.inflate(inflate, parent, attachToParent)
},
modifier = Modifier.fillMaxSize(),
update = {
btnLogin.setOnClickListener {
val name = editName.text.toString().trim()
val password = editPassword.text.toString().trim()
toLogin(context, name, password)
}
}
)
}
fun toLogin(context: Context, name: String, password: String) {
if (name.isEmpty() || password.isEmpty()) {
Toast.makeText(context, "请输入完整信息", Toast.LENGTH_SHORT).show()
return
}
Toast.makeText(context, "登录信息为:name:${name}, password:${password}", Toast.LENGTH_SHORT)
.show()
}
引用非常简单,只要通过ViewBinding组件在factory属性中添加页面的引用就行,update属性下对页面进行操作逻辑。