亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android?View與Compose互相調用的方法是什么

發布時間:2023-02-01 09:31:17 來源:億速云 閱讀:153 作者:iii 欄目:開發技術

這篇文章主要講解了“Android View與Compose互相調用的方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Android View與Compose互相調用的方法是什么”吧!

1. 前言

Compose 具有超強的兼容性,兼容現有的所有代碼,Compose 能夠與現有 View 體系并存,可實現漸進式替換。這就很有意義了,我們可以在現有項目中一小塊一小塊逐步地替換Compose,或者在舊項目中實現新的需求的時候,使用Compose

2. Android傳統View調用Compose

2.1 新建傳統View體系的Android項目

新建項目的時候選擇 Empty Activity

Android?View與Compose互相調用的方法是什么

2.2 項目添加Compose配置

2.2.1 在android代碼塊添加

appbuild.config android代碼塊中添加

buildFeatures {
    compose true
}
composeOptions {
    kotlinCompilerExtensionVersion '1.1.1'
}

2.2.2 在dependencies中添加依賴

appbuild.config dependencies代碼塊中添加

dependencies {
    //...省略...

    def compose_ui_version = '1.1.1'
    implementation "androidx.compose.ui:ui:$compose_ui_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"

    implementation 'androidx.activity:activity-compose:1.3.1' //kotlin對應版本1.6.20
    implementation 'androidx.compose.material:material:1.1.1'
}

2.3 定義Compose函數

MainActivity.kt中定義Compose函數

@Composable
fun ComposeContent() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Hello world!")
    }
}

2.4 修改xml文件

activity_main.xml中添加androidx.compose.ui.platform.ComposeView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2.5 關聯Compose函數

MainActivity.kt中,先通過findViewById找到ComposeView,然后通過composeView.setContent將Android 傳統View和Compose建立關聯。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val composeView : ComposeView = findViewById(R.id.compose_view)
    composeView.setContent {
        ComposeContent()
    }
}

3. Compose中調用Android View

3.1 調用傳統View的日歷

3.1.1 使用AndroidView

@Composable內使用: androidx.compose.ui.viewinterop.AndroidView,然后在factory里面返回原生View即可

@Composable
fun AndroidViewPage() {
    AndroidView(factory = {
        CalendarView(it)
    }, modifier = Modifier.fillMaxWidth(), update = {
        it.setOnDateChangeListener { view, year, month, day ->
            Toast.makeText(view.context, "${year}年${month}月${day}日", Toast.LENGTH_SHORT).show()
        }
    })
}
3.1.2 顯示效果如下

Android?View與Compose互相調用的方法是什么

3.2 調用傳統View的WebView

3.2.1 添加網絡權限

首先需要在AndroidManifest.xml中添加網絡權限

<uses-permission android:name="android.permission.INTERNET" />
3.2.2 首先要注冊WebView的生命周期
@Composable
private fun rememberWebViewLifecycleObserver(webView: WebView): LifecycleEventObserver {
    return remember(webView) {
        LifecycleEventObserver { _, event ->
            run {
                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)
                }
            }
        }
    }
}
3.2.3 創建有狀態的WebView

創建有狀態的WebView,并注冊生命周期

@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
}
3.2.4 調用Android View
@Composable
fun WebViewPage() {
    //創建有狀態的WebView,并注冊生命周期
    val webView = rememberWebViewWIthLifecycle()
    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")
    })
}

4. 雙層嵌套

獲取AndroidView中的原生View id

有時候,我們會遇到這種情況,就是在原生項目了,頁面中有部分使用了Compose,然后在Compose中又有部分組件使用了原生View,這種情況下,要如何取到AndroidView中的原生View id 呢 ?

4.1 在定義Xml中定義ComposeView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

4.2 關聯Compose函數

MainActivity.kt中,先通過findViewById找到ComposeView,然后通過composeView.setContent將Android 傳統View和Compose建立關聯。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val composeView : ComposeView = findViewById(R.id.compose_view)
    composeView.setContent {
        ComposeContent()
    }
}
@Composable
fun ComposeContent() {
	//....
}

4.3 創建ids.xml定義原生view id

resources/values目錄下創建ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="id" name="my_calendar_view" />
</resources>

4.4 實現ComposeContent

@Composable
fun ComposeContent() {
    AndroidView(factory = {
        //這里也可以通過 layoutInflater.inflate(R.layout.xxxxxx) 的方式返回原生View
        val calendarView = CalendarView(it)
        val keyboard = R.id.my_calendar_view
        Log.i(TAG,"my_calendar_view id:$keyboard")
        calendarView.id = keyboard
        calendarView
    }, modifier = Modifier.fillMaxWidth(), update = {
        it.setOnDateChangeListener { view, year, month, day ->
            Toast.makeText(view.context, "${year}年${month}月${day}日", Toast.LENGTH_SHORT).show()
        }
    })
}

4.5 在外層的原生代碼處獲取Compose中的原生View

在原生代碼的地方,通過composeView.findViewById查找id為my_calendar_view的原生View

window?.decorView?.post {
    val calendarViewId = R.id.my_calendar_view
    Log.i(TAG,"my_calendar_view id ===>:$calendarViewId")
    val calendarView = composeView.findViewById<CalendarView>(calendarViewId)
    Log.i(TAG,"calendarView:$calendarView")
    calendarView.setOnDateChangeListener { view, year, month, day ->
        Toast.makeText(view.context, "!!!! ${year}年${month}月${day}日", Toast.LENGTH_SHORT).show()
    }
}

注意這里的window?.decorView?.post : 必須在頁面加載完成后,才能查找到my_calendar_view對應的原生View,如果直接在onCreate里面去查找,會發現composeView.findViewById<CalendarView>(calendarViewId)返回的是null

4.6 運行項目

選擇任意一個日期,可以發現彈出的toast是!!!! year年month月day日,即原生的setOnDateChangeListener覆蓋了Compose中的setOnDateChangeListener監聽,這樣說明我們也在原生代碼處,取到了Compose內部的原生View了。

感謝各位的閱讀,以上就是“Android View與Compose互相調用的方法是什么”的內容了,經過本文的學習后,相信大家對Android View與Compose互相調用的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广汉市| 佳木斯市| 庐江县| 阿图什市| 屯留县| 隆昌县| 涪陵区| 南雄市| 宁陵县| 冀州市| 横山县| 衢州市| 武威市| 保定市| 即墨市| 安岳县| 容城县| 枞阳县| 东源县| 南皮县| 大连市| 霍邱县| 建宁县| 淮阳县| 历史| 黄陵县| 太仆寺旗| 新蔡县| 虎林市| 德兴市| 虹口区| 区。| 鄯善县| 赤壁市| 鸡东县| 金秀| 湘潭市| 客服| 濮阳县| 怀柔区| 武隆县|