ComposeView的使用:

一、 ComposeView 核心使用指南

ComposeView 是 Android 原生视图系统(View)和 Jetpack Compose 之间的 "桥梁",核心作用是在传统 View 布局(XML / 代码创建)中嵌入 Compose 界面,比如在 Activity/Fragment/ 自定义 View 中使用 Compose 写局部 UI。

1、前置条件(必配)

首先确保项目已集成 Compose,在 Module 的 build.gradle 中配置:

arduino 复制代码
android { 
   buildFeatures { 
       compose true // 启用 Compose 
   } 
 
  composeOptions { 
    kotlinCompilerExtensionVersion "1.5.3" // 需和 Kotlin 版本匹配(比如 Kotlin 1.9.0 对应 1.5.3) 
   } 
  } 

dependencies { 
 // Compose 核心依赖 
 implementation "androidx.compose.ui:ui:1.6.0" 
 implementation "androidx.compose.material:material:1.6.0"     implementation "androidx.activity:activity-compose:1.8.2" // 关联生命周期 
}

二 、核心使用场景(按频率排序)

场景 1:在 XML 布局中嵌入 ComposeView(最常用)

步骤 1:编写 XML 布局(比如 activity_main.xml
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">

    <!-- 原生 View -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="原生View区域"/>

    <!-- 嵌入 ComposeView -->
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>
步骤 2:在 Activity/Fragment 中绑定并设置 Compose 内容
kotlin 复制代码
// Activity 示例,
//注意:必须是FragmentActivity,选择AppCompatActivity会报Theme错误;
class MainActivity : FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 找到 ComposeView 并设置 Compose 内容
        val composeView = findViewById<ComposeView>(R.id.compose_view)
        composeView.setContent {
            // 这里写 Compose 代码(和纯 Compose 写法完全一致)
            MaterialTheme {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(16.dp),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(text = "Compose 嵌入区域", fontSize = 20.sp)
                    Button(onClick = { Toast.makeText(this@MainActivity, "点击按钮", Toast.LENGTH_SHORT).show() }) {
                        Text("Compose 按钮")
                    }
                }
            }
        }
    }
}

场景 2:纯代码创建 ComposeView(无需 XML)

适合动态添加 Compose 界面到原生 View 容器中:

kotlin 复制代码
//AppCompatActivity会报错  
class MainActivity : FragmentActivity () {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 1. 创建 ComposeView 实例
        val composeView = ComposeView(this).apply {
            // 2. 设置 Compose 内容
            setContent {
                MaterialTheme {
                    Text("纯代码创建的 ComposeView", modifier = Modifier.padding(16.dp))
                }
            }
        }

        // 3. 将 ComposeView 添加到原生 View 容器(比如 LinearLayout)
        val rootLayout = LinearLayout(this).apply {
            orientation = LinearLayout.VERTICAL
            layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
        }
        rootLayout.addView(composeView)

        // 4. 设置为 Activity 布局
        setContentView(rootLayout))
    }
}

场景 3:在 Fragment 中使用 ComposeView

核心是绑定 viewLifecycleOwner,避免生命周期泄漏:

kotlin 复制代码
class MyFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // 方式1:从 XML 加载(推荐)
        val view = inflater.inflate(R.layout.fragment_my, container, false)
        val composeView = view.findViewById<ComposeView>(R.id.compose_view)

        // 关键:关联 Fragment 的视图生命周期
        composeView.setViewCompositionStrategy(
            ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
        )
        composeView.setContent {
            MaterialTheme {
                Text("Fragment 中的 ComposeView")
            }
        }
        return view
    }
}

场景 4:在自定义 View 中嵌入 ComposeView

scss 复制代码
class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    init {
        orientation = VERTICAL

        // 添加原生 View
        addView(TextView(context).apply {
            text = "自定义 View 中的原生文本"
            layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
        })

        // 添加 ComposeView
        val composeView = ComposeView(context).apply {
            layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
            setContent {
                MaterialTheme {
                    Text("自定义 View 中的 Compose 文本")
                }
            }
        }
        addView(composeView)
    }
}

三 、自己写的Demo

1、HomeActivity

kotlin 复制代码
class HomeActivity: FragmentActivity (){

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_home)
        
        val composeView = findViewById<ComposeView>(R.id.compose_view)
        //使用Compose写代码
        BuyCarUtils.bindComposeView(composeView)
    }
}

2、activity_home.xml

ini 复制代码
<?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:gravity="center"
    android:orientation="vertical"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="XML页面嵌套Compose代码"
        android:gravity="center"
        android:textSize="25dp"
        android:textColor="@color/purple_700"
        />
        <androidx.compose.ui.platform.ComposeView
            android:id="@+id/compose_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            />

</LinearLayout>

3、BuyCarUtils

kotlin 复制代码
object BuyCarUtils {

    @JvmStatic
    fun bindComposeView(composeView: ComposeView) {
        composeView.apply {
           setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                AdapterDesignWidthByCompositionLocalProvider() {
                   BuyCarPage()
                }
            }
        }
    }
}

@Composable
private fun BuyCarPage() {
    Column (modifier = Modifier.padding(start = 12.dp).clickable {
        Log.d("lyy","---哈哈哈,点我了----")
    }){
        Text(text = "hello compose",
            color = Color.Black,
            fontSize = 15.sp,
        )

        Text(text = "hello 世界",
            color = Color.Black,
            fontSize = 15.sp,
        )
    }
}

@Preview(showBackground = true)
@Composable
private fun PreviewBuyCarPage() {
    BuyCarPage()
}

4、使用AppCompatActivity报错:

csharp 复制代码
- Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

- java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lyy.mydemo4/com.lyy.mydemo4.HomeActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
class HomeActivity: FragmentActivity (){

结论:主题报错,把继承类AppCompatActivity 改为 FragmentActivity就行了。

相关推荐
AskHarries2 分钟前
工具调用协议:模型如何决定调用哪个工具
程序员
DogDaoDao38 分钟前
C++核心技术深度剖析:从底层原理到工程实践
开发语言·c++·面试·程序员·指针·虚函数
DogDaoDao1 小时前
【GitHub】last30days-skill 深度技术解析
深度学习·程序员·大模型·github·ai agent·agent skill
Java爱好狂.2 小时前
阿里1658页2026最新Java面试题总结(含答案)
数据库·redis·程序员·java面试·java面试题·java编程·java八股文
DogDaoDao2 小时前
【GitHub】深度解析 Open Notebook:开源 AI 笔记研究平台的完整指南
人工智能·ai·程序员·开源·github·ai编程·notebook
文心快码BaiduComate16 小时前
提升组织级AI Coding质量:电商搜索项目实践
前端·后端·程序员
DogDaoDao17 小时前
深入理解 Qt:从原理到实战的全景指南
开发语言·qt·程序员
ClouGence19 小时前
自动化测试 CueCast 新版本发布:录制更稳、回放更准、排障更清晰
前端·程序员·测试
前端小蜗20 小时前
搞了个 vibecoding 时防摸鱼沉迷的提醒,震到手环上
人工智能·程序员
程序员cxuan21 小时前
Fable 5 的系统提示词被人扒出来了,精彩,太精彩了。
人工智能·后端·程序员