Compose中Button的简单使用

7/11/2021 AndroidComposeButton

# 基础API

fun Button(
    onClick: () -> Unit, // 点击事件
    modifier: Modifier = Modifier, // 修饰符
    enabled: Boolean = true, // 是否可用
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, 表示一个由组件发出的交互流
    elevation: ButtonElevation? = ButtonDefaults.elevation(), // 梯度
    shape: Shape = MaterialTheme.shapes.small, // 按钮的形状,对背景不生效
    border: BorderStroke? = null, // 按钮的边框,对背景不生效
    colors: ButtonColors = ButtonDefaults.buttonColors(), // 在不同状态下按钮和背景的颜色
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding, // 内边距,默认上下8dp,左右16dp
    content: @Composable RowScope.() -> Unit // 内部内容(可以把Button理解为一个FrameLayout,content就是子View)
)
1
2
3
4
5
6
7
8
9
10
11
12

我们可以把Button理解为Android中的FrameLayout,也就是帧布局,内部可以放任何子View,而Button只是提供了可点击属性而已,当然也可以添加各种顶层装饰,我们先来看个Demo:

各种按钮

示例直接列举了几种常见的Button,当然很简单,但是这些示例不需要创建任何xml布局,而且基本上都是两三行代码实现的。

比方说,第二个圆角边框按钮:

Button(
    onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() }, // 点击弹出吐司
    shape = RoundedCornerShape(8.dp), // 圆角8dp
    border = BorderStroke(2.dp, color = Color.Magenta) // 边框2dp,粉色
) {
    Text(text = "RoundedBorder") // 展示文字
}
1
2
3
4
5
6
7

再比如第三个图片按钮:

Button(onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() }) // 点击弹出吐司
{
    // 内部直接放一张图片完事
    Image(
        painter = painterResource(id = R.drawable.ic_google),
        contentDescription = "ImageButton", modifier = sizeModifier
    )
}
1
2
3
4
5
6
7
8

说白了,就是一个道理,因为是个布局,所以可以放置任何内容,有无限可能性。

# 基础但非主流API

我们先看个demo:

@Composable
fun ButtonDemo1(context: Context) {
    Button(
        onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() },
        shape = RoundedCornerShape(16.dp), // 16dp的圆角
        border = BorderStroke(2.dp, Color.DarkGray), // 灰色边框
    ) {
        Text(
            text = "Button",
            modifier = Modifier.background(Color.Red), // 背景为红色
        )
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

效果如下:

给Text添加背景

我们看到,Text文字独立于Button而存在, 这证明了Button就是一个布局,而Text是内部的一个子View而已,现在让我们给Button添加背景,添加如下代码:

modifier = Modifier.background(Color.Green) // 给Button添加绿色背景
1

效果如下:

Button添加背景

我们看到,Button背景是绿色,而边框绘制在背景上,这是因为对于Compose控件来说,background和控件本身的内容是两个图层,控件本身的内容是绘制在background上面的。

现在让我们去掉Text中的

modifier = Modifier.background(Color.Red) // 背景为红色
1

然后使用Button自带的colors属性,代码如下:

@Composable
fun ButtonDemo1(context: Context) {
    Button(
        onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() },
        shape = RoundedCornerShape(16.dp), // 16dp的圆角
        border = BorderStroke(2.dp, Color.DarkGray), // 灰色边框
        modifier = Modifier.background(Color.Green), //给Button添加绿色背景
        contentPadding = PaddingValues(40.dp), // 添加内边距
        colors = object : ButtonColors { // 添加颜色
            @Composable
            override fun backgroundColor(enabled: Boolean): State<Color> {
                // 内容的背景颜色: 可用时为黄色,不可用为灰色
                return rememberUpdatedState(if (enabled) Color.Yellow else Color.Gray)
            }

            @Composable
            override fun contentColor(enabled: Boolean): State<Color> {
                // 内容的内容颜色: 可用时为绿色,不可用时为蓝色
                return rememberUpdatedState(if (enabled) Color.Green else Color.Blue)
            }
        },
        enabled = true
    ) {
        Text(text = "Button")
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

效果如下:

使用colors

此乃情理之内,意料之中,现在让我们将enabled改为false:

enabled = false
1

效果如下:

不可用

完全意料之内,前面我们说过,Compose的UI绘制,是后面覆盖前面,现在让我们再给Text添加背景色和文字颜色,如下:

Text(text = "Button", color = Color.White, modifier = Modifier.background(Color.Red))
1

效果如下:

不可用

完全再意料之内。

Button的API非常简单,说白了当成Android原生xml中的FrameLayout看就行,比如,开头的各种Button组合效果代码:

@Composable
fun ButtonDemo2(context: Context) {

    // 点击事件
    val onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() }

    val sizeModifier = Modifier.size(width = 32.dp, height = 32.dp)

    Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxSize()) {

        // 文字按钮
        Button(onClick = onClick, elevation = ButtonDefaults.elevation(pressedElevation = 8.dp)) {
            Text(text = "TextButton")
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        Button(
            onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() },
            shape = RoundedCornerShape(8.dp),
            border = BorderStroke(2.dp, color = Color.Magenta)
        ) {
            Text(text = "RoundedBorder")
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        // 图片按钮
        Button(onClick = onClick) {
            Image(
                painter = painterResource(id = R.drawable.ic_google),
                contentDescription = "ImageButton", modifier = sizeModifier
            )
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        // 图上字下
        Button(onClick = onClick) {
            Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
                Image(painter = painterResource(id = R.drawable.ic_google), contentDescription = "ImageButton", modifier = sizeModifier)
                Text(text = "图上字下")
            }
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        // 图下字上
        Button(onClick = onClick) {
            Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
                Text(text = "图下字上")
                Image(painter = painterResource(id = R.drawable.ic_google), contentDescription = "ImageButton", modifier = sizeModifier)
            }
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        // 图左字右
        Button(onClick = onClick) {
            Row(horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
                Image(painter = painterResource(id = R.drawable.ic_google), contentDescription = "ImageButton", modifier = sizeModifier)
                Text(text = "图左字右")
            }
        }

        Spacer(modifier = Modifier.size(width = 10.dp, height = 8.dp))

        // 图右字左
        Button(onClick = onClick) {
            Row(horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
                Text(text = "图右字左")
                Image(painter = painterResource(id = R.drawable.ic_google), contentDescription = "ImageButton", modifier = sizeModifier)
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

完整代码在: 这里 (opens new window)

Last Updated: 1/28/2022, 4:13:43 PM