根据一段代码来了解kotlin中布局结构

实际效果:

image

源代码:

    // 搜索框部分为:
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 8.dp, vertical = 12.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    // 搜索输入框
                    Box(
                        modifier = Modifier
                            .weight(1f)
                            .height(54.dp) // 增加高度到54dp
                            .background(Color.White, RoundedCornerShape(24.dp)) // 圆角也相应调整
                    ) {
                        Row(
                            modifier = Modifier
                                .fillMaxSize()
                                .padding(horizontal = 16.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Icon(
                                imageVector = Icons.Filled.Search,
                                contentDescription = "搜索",
                                tint = Color.Gray,
                                modifier = Modifier.size(25.dp) // 稍微增大图标
                            )
                            Spacer(modifier = Modifier.width(12.dp))
                            TextField(
                                value = keyword,
                                onValueChange = { newKeyword: String ->
                                    keyword = newKeyword
                                },
                                modifier = Modifier
                                    .weight(1f)
                                    .fillMaxHeight(), // 使用fillMaxHeight填满可用高度
                                placeholder = {
                                    Text(
                                        text = "搜索咨询师姓名、擅长领域...",
                                        color = Color.Gray,
                                        fontSize = 14.sp, // 增大占位符字体
                                        maxLines = 1
                                    )
                                },
                                textStyle = TextStyle(
                                    fontSize = 16.sp, // 增大输入文字字体
                                    color = Color.Black
                                ),
                                singleLine = true,
                                colors = TextFieldDefaults.colors(
                                    focusedContainerColor = Color.Transparent,
                                    unfocusedContainerColor = Color.Transparent,
                                    focusedIndicatorColor = Color.Transparent,
                                    unfocusedIndicatorColor = Color.Transparent,
                                    focusedTextColor = Color.Black,
                                    unfocusedTextColor = Color.Black,
                                    cursorColor = Color.Black
                                )
                            )
                        }
                    }

                    Spacer(modifier = Modifier.width(12.dp))

                    // 搜索按钮 - 也相应增大
                    Box(
                        modifier = Modifier
                            .size(48.dp) // 增大到48dp
                            .background(Color(0xFF5A67D8))
                            .clip(RoundedCornerShape(24.dp)) // 圆角相应调整
                            .clickable { searchCounselors() },
                        contentAlignment = Alignment.Center
                    ) {
                        Text(
                            text = "搜索",
                            color = Color.White,
                            fontSize = 16.sp, // 增大按钮文字
                            fontWeight = FontWeight.Bold
                        )
                    }
                }

接下来我们来逐行逐属性地分析代码

这是一个搜索框组件,包含:

  • 左侧:搜索输入区域(图标 + 输入框)

  • 右侧:搜索按钮

  • 整体布局使用 Row 水平排列

外层容器

Row(
    modifier = Modifier
        .fillMaxWidth()                    // 填满父容器宽度
        .padding(horizontal = 16.dp, vertical = 12.dp), // 四周内边距
    verticalAlignment = Alignment.CenterVertically // 子项垂直居中
) {

搜索输入区域结构

Box (白色背景圆角容器)
└── Row (水平布局)
├── Icon (搜索图标)
├── Spacer (间距)
└── TextField (文本输入框)

搜索按钮结构

Box (蓝色背景圆形按钮)
└── Text ("搜索"文字)

1. 搜索输入框外层容器

Box(
    modifier = Modifier
        .weight(1f)                        // 在Row中占据剩余空间
        .height(54.dp)                     // 固定高度54dp
        .background(Color.White, RoundedCornerShape(24.dp)) // 白色背景,24dp圆角
) {

2. 内部水平布局

Row(
    modifier = Modifier
        .fillMaxSize()                     // 填满父Box的全部空间
        .padding(horizontal = 16.dp),      // 左右内边距16dp
    verticalAlignment = Alignment.CenterVertically // 内容垂直居中
) {

3. 搜索图标

Icon(
    imageVector = Icons.Filled.Search,     // 使用Material Design的搜索图标
    contentDescription = "搜索",           // 无障碍描述
    tint = Color.Gray,                     // 图标颜色为灰色
    modifier = Modifier.size(20.dp)        // 图标尺寸20dp
)

4. 图标与输入框间距

Spacer(modifier = Modifier.width(12.dp))   // 水平间距12dp

5. 文本输入框核心部分

TextField(
    value = keyword,                       // 绑定的文本值
    onValueChange = { newKeyword: String -> // 文本变化回调
        keyword = newKeyword
    },
    modifier = Modifier
        .weight(1f)                        // 在Row中占据剩余宽度
        .fillMaxHeight(),                  // 填满可用高度

6. 占位符文本

placeholder = {
    Text(
        text = "搜索咨询师姓名、擅长领域...", // 提示文字
        color = Color.Gray,                // 灰色提示文字
        fontSize = 14.sp,                  // 字体大小14sp
        maxLines = 1                       // 单行显示
    )
},

7. 输入文本样式

textStyle = TextStyle(
    fontSize = 16.sp,                      // 输入文字大小16sp
    color = Color.Black                    // 输入文字颜色黑色
),
singleLine = true,                         // 单行输入模式

8. 输入框颜色配置

colors = TextFieldDefaults.colors(
    focusedContainerColor = Color.Transparent,     // 聚焦时背景透明
    unfocusedContainerColor = Color.Transparent,   // 未聚焦时背景透明
    focusedIndicatorColor = Color.Transparent,     // 聚焦时下划线透明(隐藏)
    unfocusedIndicatorColor = Color.Transparent,   // 未聚焦时下划线透明(隐藏)
    focusedTextColor = Color.Black,                // 聚焦时文字黑色
    unfocusedTextColor = Color.Black,              // 未聚焦时文字黑色
    cursorColor = Color.Black                      // 光标颜色黑色
)

9. 搜索按钮与输入框间距

Spacer(modifier = Modifier.width(12.dp))   // 水平间距12dp

10. 搜索按钮容器

Box(
    modifier = Modifier
        .size(48.dp)                       // 固定尺寸48x48dp
        .background(Color(0xFF5A67D8))     // 蓝色背景(#5A67D8)
        .clip(RoundedCornerShape(24.dp))   // 裁剪为24dp圆角(圆形)
        .clickable { searchCounselors() }, // 点击事件,调用搜索函数
    contentAlignment = Alignment.Center    // 内容居中对齐
) {

11. 按钮文字

Text(
    text = "搜索",                         // 按钮文字
    color = Color.White,                   // 白色文字
    fontSize = 16.sp,                      // 字体大小16sp
    fontWeight = FontWeight.Bold           // 粗体字重
)

细心的我发现对于搜索按钮容器有了这行代码:.clip(RoundedCornerShape(24.dp)) // 裁剪为24dp圆角(圆形)

不就该是圆角的吗,可是现在它是一个正方形,是什么原因导致它没有生效呢?

问题在于 修饰符的应用顺序。在Compose中,修饰符是按顺序应用的。背景色在裁剪之前就已经绘制了,所以裁剪只影响后续的内容和点击区域,但不会改变已经绘制的背景形状。

解决方案:

方案1.调整修饰符顺序

Box(
    modifier = Modifier
        .size(48.dp)
        .clip(RoundedCornerShape(24.dp))   // 先裁剪
        .background(Color(0xFF5A67D8))     // 再绘制背景(会被裁剪)
        .clickable { searchCounselors() },
    contentAlignment = Alignment.Center
) {
    // Text内容不变
}

方案2.在background中直接指定形状

Box(
    modifier = Modifier
        .size(48.dp)
        .background(Color(0xFF5A67D8), RoundedCornerShape(24.dp)) // 形状和颜色一起设置
        .clickable { searchCounselors() },
    contentAlignment = Alignment.Center
) {
    // Text内容不变
}

修改之后的效果:

image

posted @ 2025-10-14 20:02  雨花阁  阅读(14)  评论(0)    收藏  举报