当前位置: 首页 > article >正文

Android开发实战班 - 现代 UI 开发之自定义 Compose 组件

Jetpack Compose 不仅提供了丰富的内置组件,还允许开发者根据项目需求创建自定义组件。自定义 Compose 组件可以提高代码复用性、简化 UI 逻辑,并使应用界面更加一致和模块化。本章节将介绍如何创建自定义 Compose 组件,包括组件的创建、样式定制、状态管理以及在项目中的应用。

为什么需要自定义 Compose 组件

  • 代码复用:

    • 通过创建自定义组件,可以将常用的 UI 逻辑封装起来,避免重复代码,提高代码复用性。
  • 简化 UI 逻辑:

    • 将复杂的 UI 逻辑封装到自定义组件中,可以简化调用代码,使代码更简洁易懂。
  • 一致性:

    • 自定义组件可以保证应用界面的一致性,例如统一的按钮样式、输入框样式等。
  • 模块化:

    • 自定义组件可以将 UI 拆分成更小的模块,便于维护和测试。

创建自定义 Compose 组件

创建自定义 Compose 组件非常简单,只需定义一个带有 @Composable 注解的函数即可。以下是一个简单的自定义按钮组件示例:

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun MyButton(
    text: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    backgroundColor: Color = MaterialTheme.colorScheme.primary,
    contentColor: Color = MaterialTheme.colorScheme.onPrimary
) {
    Text(
        text = text,
        modifier = modifier
            .clip(RoundedCornerShape(8.dp))
            .background(backgroundColor)
            .clickable { onClick() }
            .padding(vertical = 12.dp, horizontal = 16.dp),
        color = contentColor,
        style = MaterialTheme.typography.labelLarge
    )
}
  • 参数说明:

    • text: 按钮显示的文本。
    • onClick: 按钮点击事件回调。
    • modifier: 修饰符,用于自定义按钮的布局和样式。
    • backgroundColor: 按钮背景颜色,默认为主题主色。
    • contentColor: 按钮文本颜色,默认为主题主色文本颜色。
  • 使用自定义按钮:

    MyButton(
        text = "Click Me",
        onClick = { /* 处理点击事件 */ },
        modifier = Modifier.align(Alignment.Center)
    )
    

样式定制

自定义 Compose 组件可以通过参数传递样式,例如颜色、字体、形状等,从而实现样式的定制。

  • 颜色定制:

    • 可以通过参数传递不同的颜色值来定制组件的颜色。
      MyButton(
          text = "Red Button",
          onClick = { /* 处理点击事件 */ },
          backgroundColor = Color.Red,
          contentColor = Color.White
      )
      
  • 字体和排版:

    • 可以通过 MaterialTheme.typography 来定制组件的字体和排版。
      MyButton(
          text = "Large Button",
          onClick = { /* 处理点击事件 */ },
          modifier = Modifier.padding(16.dp),
          style = MaterialTheme.typography.headlineMedium
      )
      
  • 形状定制:

    • 可以通过 clip()RoundedCornerShape 等函数来定制组件的形状。
      MyButton(
          text = "Rounded Button",
          onClick = { /* 处理点击事件 */ },
          modifier = Modifier.clip(RoundedCornerShape(16.dp))
      )
      

状态管理

自定义 Compose 组件可以管理自己的状态,例如按钮的选中状态、输入框的内容等。

  • 按钮选中状态:

    @Composable
    fun ToggleButton(
        text: String,
        isSelected: Boolean,
        onToggle: (Boolean) -> Unit,
        modifier: Modifier = Modifier
    ) {
        val backgroundColor = if (isSelected) MaterialTheme.colorScheme.primary else Color.Gray
        val contentColor = if (isSelected) MaterialTheme.colorScheme.onPrimary else Color.White
    
        Text(
            text = text,
            modifier = modifier
                .clip(RoundedCornerShape(8.dp))
                .background(backgroundColor)
                .clickable { onToggle(!isSelected) }
                .padding(vertical = 12.dp, horizontal = 16.dp),
            color = contentColor,
            style = MaterialTheme.typography.labelLarge
        )
    }
    
    // 使用 ToggleButton
    var isButtonSelected by remember { mutableStateOf(false) }
    
    ToggleButton(
        text = "Toggle Me",
        isSelected = isButtonSelected,
        onToggle = { isButtonSelected = it }
    )
    
  • 输入框内容状态:

    @Composable
    fun MyTextField(
        value: String,
        onValueChange: (String) -> Unit,
        modifier: Modifier = Modifier,
        label: String = ""
    ) {
        TextField(
            value = value,
            onValueChange = onValueChange,
            label = { Text(text = label) },
            modifier = modifier,
            colors = TextFieldDefaults.textFieldColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                textColor = MaterialTheme.colorScheme.onSecondaryContainer,
                placeholderColor = MaterialTheme.colorScheme.onSecondaryContainer.copy(alpha = 0.5f)
            )
        )
    }
    
    // 使用 MyTextField
    var text by remember { mutableStateOf("") }
    
    MyTextField(
        value = text,
        onValueChange = { text = it },
        label = "Enter text"
    )
    

实战案例

  1. 案例一:自定义导航栏组件

    • 创建一个自定义导航栏组件,包含多个导航项。
    • 使用 RowButton 组件实现导航栏布局。
    • 通过参数传递导航项列表和点击事件回调。
    @Composable
    fun MyNavigationBar(
        items: List<String>,
        onItemClick: (String) -> Unit,
        modifier: Modifier = Modifier
    ) {
        Row(modifier = modifier) {
            items.forEach { item ->
                MyButton(
                    text = item,
                    onClick = { onItemClick(item) },
                    modifier = Modifier.weight(1f)
                )
            }
        }
    }
    
    // 使用 MyNavigationBar
    val navigationItems = listOf("Home", "Settings", "Profile")
    var selectedItem by remember { mutableStateOf("Home") }
    
    MyNavigationBar(
        items = navigationItems,
        onItemClick = { selectedItem = it }
    )
    
  2. 自定义卡片组件

    • 创建一个自定义卡片组件,包含标题、内容和按钮。
    • 使用 Card, Column, Text, Button 等组件实现卡片布局。
    • 通过参数传递标题、内容和按钮文本。
    @Composable
    fun MyCard(
        title: String,
        content: String,
        buttonText: String,
        onButtonClick: () -> Unit,
        modifier: Modifier = Modifier
    ) {
        Card(
            modifier = modifier,
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
            shape = RoundedCornerShape(8.dp)
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    text = title,
                    style = MaterialTheme.typography.titleMedium,
                    modifier = Modifier.padding(bottom = 8.dp)
                )
                Text(
                    text = content,
                    style = MaterialTheme.typography.bodyMedium,
                    modifier = Modifier.padding(bottom = 12.dp)
                )
                MyButton(
                    text = buttonText,
                    onClick = onButtonClick
                )
            }
        }
    }
    
    // 使用 MyCard
    MyCard(
        title = "Welcome",
        content = "Thank you for using our app!",
        buttonText = "OK",
        onButtonClick = { /* 处理按钮点击事件 */ }
    )
    

课后作业

  1. 任务一:创建一个自定义按钮组件

    • 定义一个自定义按钮组件 MyButton,包含文本、点击事件、颜色、字体等参数。
    • 使用 Modifier 和 Compose 布局组件实现按钮布局。
    • 在应用中调用 MyButton 组件,并传递不同的参数。
  2. 任务二:创建一个自定义卡片组件

    • 定义一个自定义卡片组件 MyCard,包含标题、内容、按钮文本和点击事件等参数。
    • 使用 Card, Column, Text, Button 等组件实现卡片布局。
    • 在应用中调用 MyCard 组件,并传递不同的参数。
  3. 任务三:实现一个自定义导航栏组件

    • 定义一个自定义导航栏组件 MyNavigationBar,包含导航项列表和点击事件回调。
    • 使用 RowMyButton 组件实现导航栏布局。
    • 在应用中调用 MyNavigationBar 组件,并传递导航项列表和点击事件回调。

通过本章节的学习,学员将能够掌握创建自定义 Compose 组件的方法,包括组件的创建、样式定制、状态管理以及在项目中的应用,从而提高代码复用性、简化 UI 逻辑,并使应用界面更加一致和模块化。

作者简介

前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!

温馨提示:可搜老码小张公号联系导师


http://www.kler.cn/a/402694.html

相关文章:

  • python中lxml 库之 etree 使用详解
  • 【C++】list模拟实现(详解)
  • [RabbitMQ] 重试机制+TTL+死信队列
  • Java基础面试题04:Iterator 和 ListIterator 的区别是什么?
  • 鸿蒙NEXT开发案例:随机数生成
  • Javaweb前端HTML css 整体布局
  • Java基于微信小程序的校园跑腿平台(V2.0)
  • elementUI 表格组件结合单选框做单选效果显示
  • 人形机器人开发、XR仿真训练、影视动画制作,一副手套支持多种应用
  • 安装CLIP
  • 前端项目支持tailwindcss写样式
  • 【Linux】编译器gcc/g++、动静态库
  • docker pull命令拉取镜像失败的解决方案
  • 机器学习笔记——聚类算法(Kmeans、GMM-使用EM优化)
  • ansible从入门到精通(完整篇)
  • 软件测试 —— 自动化基础
  • opencv项目:自动评分答题卡识别系统
  • layui合并table相同内的行
  • web——sqliabs靶场——第十三关——报错注入+布尔盲注
  • 告别反馈滞后!看板管理让UX设计流程更流畅
  • 208.实现前缀树 207.课程表
  • 22.UE5控件切换器,存档列表,
  • aws上安装ssm-agent
  • 16:00面试,16:06就出来了,问的问题有点变态。。。
  • 【蓝桥杯C/C++】翻转游戏:多种实现与解法解析
  • 【云原生开发】K8S集群调度资源deployment,daemonset,statefulset,cronjob,节点管理等开发设计与实现