我想在Jetpack Compose中做一个自定义按钮,它从左侧开始,没有边框,但在所有其他边保持BorderStroke.如下所示:

enter image description here

然而,我唯一能做出来的就是这个按钮:

enter image description here

我的按钮代码是:

@Composable
fun StandardButton(modifier: Modifier, onClicked: () -> Unit) {
    OutlinedButton(modifier = modifier
        .fillMaxWidth()
        .height(70.dp)
        .padding(PaddingValues(end = 50.dp)),
        colors = ButtonDefaults.buttonColors(containerColor = Color.Black),
        border = BorderStroke(6.dp, Color.Blue),
        shape = RoundedCornerShape(topStart = 0.dp, topEnd = 50.dp, bottomEnd = 50.dp),
        onClick = onClicked) {
        Text(text = "Button")
    }
}

我try 添加绘图修改器来自己绘制笔划:

fun Modifier.topBorder(strokeWidth: Dp, color: Color, cornerRadiusDp: Dp) = composed(
    factory = {
        val density = LocalDensity.current
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val cornerRadiusPx = density.run { cornerRadiusDp.toPx() }

        Modifier.drawBehind {
            val width = size.width
            val height = size.height

            drawLine(
                color = color,
                start = Offset(x = 0f, y = height),
                end = Offset(x = 0f, y = cornerRadiusPx),
                strokeWidth = strokeWidthPx
            )

            drawArc(
                color = color,
                startAngle = 180f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset.Zero,
                size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
                style = Stroke(width = strokeWidthPx)
            )

            drawLine(
                color = color,
                start = Offset(x = cornerRadiusPx, y = 0f),
                end = Offset(x = width - cornerRadiusPx, y = 0f),
                strokeWidth = strokeWidthPx
            )

            drawArc(
                color = color,
                startAngle = 270f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset(x = width - cornerRadiusPx * 2, y = 0f),
                size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
                style = Stroke(width = strokeWidthPx)
            )

            drawLine(
                color = color,
                start = Offset(x = width, y = height),
                end = Offset(x = width, y = cornerRadiusPx),
                strokeWidth = strokeWidthPx
            )
        }
    }
)

fun Modifier.bottomBorder(strokeWidth: Dp, color: Color, cornerRadiusDp: Dp) = composed(
    factory = {
        val density = LocalDensity.current
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val cornerRadiusPx = density.run { cornerRadiusDp.toPx() }

        Modifier.drawBehind {
            val width = size.width
            val height = size.height

            drawLine(
                color = color,
                start = Offset(x = 0f, y = 0f),
                end = Offset(x = 0f, y = height-cornerRadiusPx),
                strokeWidth = strokeWidthPx
            )

            drawArc(
                color = color,
                startAngle = 90f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset(x = 0f, y = height - cornerRadiusPx * 2),
                size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
                style = Stroke(width = strokeWidthPx)
            )

            drawLine(
                color = color,
                start = Offset(x = cornerRadiusPx, y = height),
                end = Offset(x = width - cornerRadiusPx, y = height),
                strokeWidth = strokeWidthPx
            )

            drawArc(
                color = color,
                startAngle = 0f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset(x = width - cornerRadiusPx * 2, y = height - cornerRadiusPx * 2),
                size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
                style = Stroke(width = strokeWidthPx)
            )

            drawLine(
                color = color,
                start = Offset(x = width, y = 0f),
                end = Offset(x = width, y = height - cornerRadiusPx),
                strokeWidth = strokeWidthPx
            )
        }
    }
)

用法:

@Composable
fun StandardButton(modifier: Modifier, onClicked: () -> Unit) {
    OutlinedButton(modifier = modifier
        .fillMaxWidth()
        .height(70.dp)
        .padding(PaddingValues(end = 50.dp))
        .topBorder(6.dp, Color.White, 50.dp)
        .bottomBorder(6.dp, Color.White, 50.dp),
        colors = ButtonDefaults.buttonColors(containerColor = Color.Black),
        shape = RoundedCornerShape(topStart = 0.dp, topEnd = 50.dp, bottomEnd = 50.dp),
        onClick = onClicked) {
        Text(text = "Button")
    }
}

这导致了这样的结果:

enter image description here

有人能帮帮我吗?

推荐答案

一种快捷而肮脏的方法是向按钮添加负的x轴偏移:

    modifier = Modifier
                  .offset(x = -16.dp)
                  ...

这将隐藏按钮的左侧部分.

Android相关问答推荐

ENV变量在gradle进程中没有更新

无法列出目录中的文件'

在Android的Whatsapp中共享多个图片和文本

Android意图过滤器不限制应用程序仅处理YouTube链接

如何从sqlite数据库中检索数据到碎片android?

如何使用进度条和返回函数进行API调用,同时在Android上使用Kotlin保持高效?

Kotlin - 在继续之前如何等待这个协程完成?

在 kotlin 上向适配器添加绑定视图功能

Jetpack Compose 使用 SavedStateHandle 发送返回结果不适用于 ViewModel 中注入的 SavedStateHandle

从 Jetpack Compose 中的图像中删除默认高度

使用 Gadle kotlin 为多模块 Android 代码库设置 jacoco

请求访问小部件中的位置权限

单击按钮时不显示 Toast 消息

AirDroid Business 如何能够从屏幕截图中排除覆盖?

如何将可重用的 ExtendedFloatingActionButton 与可重用的脚手架链接起来

在 Jetpack Compose 中重用具有重复代码的列

Jetpack 组合千位分隔符视觉转换,也适用于小数

Android Compose:LazyColumn 和 Column with verticalScroll 的区别

如何在 MAUI 项目中包含每个平台的现有 C++ 库?

Jetpack Compose 中的按钮上的文本未更新