能不能好好的 發表於 2023-8-5 15:34:00

Android开发 Jetpack Compose 与xml的混合开发AndroidView

<h1><span style="color: rgba(22, 145, 121, 1)">前言</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">  Jetpack Compose虽然已经逐渐完善,但是其实还是有很多地方未满足需求。比如播放视频、相机预览等等依然需要原来的View。所以目前阶段Jetpack Compose与xml的混合开发<span style="color: rgba(186, 55, 42, 1)"><strong>非常重要</strong></span>。</span></p>
<p>  官方文档地址:https://developer.android.google.cn/jetpack/compose/migrate/interoperability-apis/views-in-compose?hl=zh-cn</p>
<h1><span style="color: rgba(22, 145, 121, 1)">在compose中添加TextView</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">View与Jetpack Compose进行混合时,主要依靠的是AndroidView</span></p>
<h2><span style="color: rgba(35, 111, 161, 1)">效果图</span></h2>
<p><img src="https://img2023.cnblogs.com/blog/1497956/202308/1497956-20230805154406600-1236673536.gif" alt="" height="731" width="406"></p>
<h2><span style="color: rgba(35, 111, 161, 1)">代码</span></h2>
<pre class="highlighter-hljs" data-dark-theme="true"><code>override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      APage()
    }
}

@Composable
fun APage() {
    val timeData = remember {
      mutableStateOf(0L)
    }
    Column(
      Modifier.fillMaxSize(),
      horizontalAlignment = Alignment.CenterHorizontally,
      verticalArrangement = Arrangement.Center
    ) {
      //这里在AndroidView的factory构建TextView
      AndroidView(factory = {
            TextView(it).apply {
                text = System.currentTimeMillis().toString()
                textSize = 40f
                setTextColor(android.graphics.Color.WHITE)
            }
      }, modifier = Modifier.background(color = Color.Gray)//这边依然可以使用compose的modifier对View进行配置

            , update = { //update是用来更新AndroidView里的数据的
                it.text = timeData.value.toString()
            })

      //这里举例通过Button更新AndroidView里的数据
      Button(onClick = {
            timeData.value = System.currentTimeMillis()
      }) {
            Text(text = "更新时间")
      }
    }
}</code></pre>
<h1><span style="color: rgba(22, 145, 121, 1)">通过ViewBinding导入xml布局</span></h1>
<h2><span style="color: rgba(35, 111, 161, 1)">效果图</span></h2>
<p><img src="https://img2023.cnblogs.com/blog/1497956/202308/1497956-20230805153228101-824233292.gif" alt="" height="731" width="406"></p>
<h2><span style="color: rgba(35, 111, 161, 1)">所需依赖</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">这个版本是跟随compose的大版本,需要参考你的androidx.compose.ui:ui:&nbsp; 、androidx.compose.ui:ui-tooling: 版本</span></p>
<pre class="highlighter-hljs" data-dark-theme="true"><code>//androidView binding
implementation("androidx.compose.ui:ui-viewbinding:1.4.3")</code></pre>
<h2><span style="color: rgba(35, 111, 161, 1)">此外还需要在build文件中启用viewBinding</span></h2>
<pre class="language-bash highlighter-hljs" data-dark-theme="true"><code>android {
    //略...

    defaultConfig {
         //略...
    }
   
    buildFeatures{
      viewBinding = true
    }

    //略...               
}</code></pre>
<h2><span style="color: rgba(35, 111, 161, 1)">xml布局</span></h2>
<p>item_user_layout.xml</p>
<pre class="highlighter-hljs" data-dark-theme="true"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"&gt;

    &lt;ImageView
      android:id="@+id/image"
      android:layout_width="200dp"
      android:layout_height="200dp"
      android:src="@mipmap/ic_fruit_apple"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" /&gt;

    &lt;TextView
      android:id="@+id/name"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="20dp"
      android:textSize="40sp"
      android:text="名称"
      android:textColor="@color/black"
      app:layout_constraintEnd_toEndOf="@+id/image"
      app:layout_constraintStart_toStartOf="@+id/image"
      app:layout_constraintTop_toBottomOf="@+id/image" /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</code></pre>
<h2><span style="color: rgba(35, 111, 161, 1)">代码</span></h2>
<pre class="highlighter-hljs" data-dark-theme="true"><code>override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      APage()
    }
}

@Composable
fun APage() {
    val imageRes = remember {
      mutableListOf(R.mipmap.ic_fruit_apple, R.mipmap.ic_fruit_banana,R.mipmap.ic_fruit_coconut)
    }
    val nameData = remember {
      mutableListOf("苹果", "香蕉","椰子")
    }
    val count = remember {
      mutableStateOf(0)
    }
    Column(
      Modifier.fillMaxSize(),
      horizontalAlignment = Alignment.CenterHorizontally,
      verticalArrangement = Arrangement.Center
    ) {
      AndroidViewBinding(factory = ItemUserLayoutBinding::inflate) {
            //这里已经是AndroidViewBinding的update参数lambda
            image.setImageResource(imageRes)
            name.text = nameData
            //这里也举例一下,可以在AndroidViewBinding里更新remember的数据
            image.setOnClickListener {
                image.setImageResource(imageRes)
                name.text = nameData
                count.value++
                if (count.value &gt; 2){
                  count.value = 0
                }
            }
      }
      //这是compose的Button,这里举例通过Button更新AndroidViewBinding里的数据
      Button(onClick = {
            count.value++
            if (count.value &gt; 2){
                count.value = 0
            }
      }) {
            Text(text = "更新数据")
      }
    }
}</code></pre>
<h1 id="call-view" role="presentation" data-text="从 Compose 调用 Android 框架"><span class="devsite-heading" style="color: rgba(22, 145, 121, 1)" role="heading" aria-level="2">从Compose调用Android框架</span></h1>
<p><span class="devsite-heading" style="color: rgba(0, 0, 0, 1)" role="heading" aria-level="2">下面的代码通过附带效应DisposableEffect实现了监听音量变化的例子,如果你对附带效应不甚了解可以参考我的博客:<span role="heading" aria-level="2">Android开发 Jetpack_Compose_6 附带效应</span></span></p>
<p><span class="devsite-heading" style="color: rgba(0, 0, 0, 1)" role="heading" aria-level="2">效果图</span></p>
<p><span class="devsite-heading" style="color: rgba(0, 0, 0, 1)" role="heading" aria-level="2"><img src="https://img2023.cnblogs.com/blog/1497956/202308/1497956-20230807142454282-1377539680.gif" alt="" height="730" width="414"></span></p>
<p id="1691389494869">代码</p>
<pre class="highlighter-hljs" data-dark-theme="true"><code>@Composable
fun APage() {
    val volumeData = remember {
      mutableStateOf(0)
    }
    Column(
      Modifier.fillMaxSize(),
      horizontalAlignment = Alignment.CenterHorizontally,
      verticalArrangement = Arrangement.Center
    ) {
      AndroidView(factory = {
            TextView(it).apply {
                setTextColor(android.graphics.Color.BLACK)
                textSize = 50f
            }
      }, update = {
            it.text = volumeData.value.toString()
      })
    }
    val context = LocalContext.current
    DisposableEffect(context){
      val volumeReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                if (intent.action.equals("android.media.VOLUME_CHANGED_ACTION")) {
                  val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
                  val currVolume: Int = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)       // 当前的媒体音量
                  volumeData.value = currVolume
                }
            }
      }
      val filter = IntentFilter()
      filter.addAction("android.media.VOLUME_CHANGED_ACTION")
      context.registerReceiver(volumeReceiver, filter)

      onDispose {
            //注销广播
            context.unregisterReceiver(volumeReceiver)
      }
    }
}</code></pre>
<p>&nbsp;</p>
<p>end</p>

</div>
<div id="MySignature" role="contentinfo">
    <div style="text-align: center">
    <p style="color:orange;font-size:16px;" >本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/17607554.html </p>
    <div style="color:orange;font-size:16px;">本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。 </div>
</div><br><br>
来源:https://www.cnblogs.com/guanxinjing/p/17607554.html
頁: [1]
查看完整版本: Android开发 Jetpack Compose 与xml的混合开发AndroidView