使用可绘制图案作为按钮背景
Use drawable pattern as button background
我正在尝试将按钮背景从纯色更改为具有透明背景的可绘制图像,以确保我可以看到图案
我搬到了喷气背包,所以我创造了
Button(onClick = { /*TODO*/ },
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.gainsboro_00)),
modifier = Modifier
.fillMaxWidth()
.height(60.dp),
shape = RoundedCornerShape(0.dp)) {
Text(text = stringResource(id = R.string.login),
color = colorResource(id = R.color.gainsboro_05),
style = MaterialTheme.typography.body1)
}
此按钮的背景为灰色。
我想应用下面的可绘制对象:
<?xml version="1.0" encoding="UTF-8" ?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/pattern_stripe_loose_gainsboro_05"
android:tileMode="repeat"/>
作为背景而不是彩色背景,并显示图案。上面的xml只是重复一个模式来创建背景
所以我希望这样:
使用模式:
当使用传统的布局方式时,它可以工作,但我不能让它在 Jetpack 上工作
有什么想法吗?
为什么不直接创建一个具有该背景的框并放置文本,同时使整个框可点击?该框将充当整个按钮。我的意思是这就是按钮的本质,不是吗?一个包含一些文字的盒子?哦,如果你想不出一种方法来将 drawable 设置为你的 Box 上的背景,只需使用 Image
之类的东西结合 fillMaxSize()
修饰符。
类似
Box(Modifier.fillMaxWidth().height(...),
horizontalArrangement = Arrangement.CenterHorizontally){
Image(painter = painterResource(R.drawable.b_pattern),
contentDescription = "Lorem Ipsum")
Text(modifier = Modifier.align(Alignment.CenterVertically),
text = "Lorem Ipsum")
}
试试看,请告诉我。
Compose 还没有这样的功能。您可以在 issue tracker.
上创建功能请求
在此实现之前,您可以创建一个绘制大量图像的纯 Compose 解决方案,但我认为当 ImageView
已经由工程师优化时,这样做没有意义。在这种情况下,您可以使用 AndroidView
与旧视图互操作。
@Composable
fun TileAndroidImage(
@DrawableRes drawableId: Int,
contentDescription: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val drawable = remember(drawableId) {
BitmapDrawable(
context.resources,
BitmapFactory.decodeResource(
context.resources,
drawableId
)
).apply {
tileModeX = Shader.TileMode.REPEAT
tileModeY = Shader.TileMode.REPEAT
}
}
AndroidView(
factory = {
ImageView(it)
},
update = { imageView ->
imageView.background = drawable
},
modifier = modifier
.semantics {
this.contentDescription = contentDescription
role = Role.Image
}
)
}
下一部分,将它放在按钮的背景中。在 compose 中,我们使用容器来做到这一点。您可以创建您的 TiledButton
。我将零填充传递给容器按钮并手动添加实际填充,这样它就不会影响背景:
@Composable
fun TiledButton(
onClick: () -> Unit,
@DrawableRes backgroundDrawableId: Int,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
contentColor: Color = MaterialTheme.colors.primary,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
) {
Button(
onClick = onClick,
contentPadding = PaddingValues(0.dp),
enabled = enabled,
shape = shape,
border = border,
elevation = null,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Transparent,
contentColor = contentColor,
disabledBackgroundColor = Color.Transparent,
disabledContentColor = contentColor.copy(alpha = ContentAlpha.disabled),
),
modifier = modifier
) {
Box(
contentAlignment = Alignment.Center,
) {
TileAndroidImage(
drawableId = backgroundDrawableId,
contentDescription = "...",
modifier = Modifier.matchParentSize()
)
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(contentPadding),
content = content,
)
}
}
}
用法:
TiledButton(
onClick = { /*TODO*/ },
backgroundDrawableId = R.drawable.tile,
border = BorderStroke(1.dp, Color.Blue),
) {
Text("Apple")
}
我正在尝试将按钮背景从纯色更改为具有透明背景的可绘制图像,以确保我可以看到图案
我搬到了喷气背包,所以我创造了
Button(onClick = { /*TODO*/ },
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.gainsboro_00)),
modifier = Modifier
.fillMaxWidth()
.height(60.dp),
shape = RoundedCornerShape(0.dp)) {
Text(text = stringResource(id = R.string.login),
color = colorResource(id = R.color.gainsboro_05),
style = MaterialTheme.typography.body1)
}
此按钮的背景为灰色。
我想应用下面的可绘制对象:
<?xml version="1.0" encoding="UTF-8" ?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/pattern_stripe_loose_gainsboro_05"
android:tileMode="repeat"/>
作为背景而不是彩色背景,并显示图案。上面的xml只是重复一个模式来创建背景
所以我希望这样:
使用模式:
当使用传统的布局方式时,它可以工作,但我不能让它在 Jetpack 上工作
有什么想法吗?
为什么不直接创建一个具有该背景的框并放置文本,同时使整个框可点击?该框将充当整个按钮。我的意思是这就是按钮的本质,不是吗?一个包含一些文字的盒子?哦,如果你想不出一种方法来将 drawable 设置为你的 Box 上的背景,只需使用 Image
之类的东西结合 fillMaxSize()
修饰符。
类似
Box(Modifier.fillMaxWidth().height(...),
horizontalArrangement = Arrangement.CenterHorizontally){
Image(painter = painterResource(R.drawable.b_pattern),
contentDescription = "Lorem Ipsum")
Text(modifier = Modifier.align(Alignment.CenterVertically),
text = "Lorem Ipsum")
}
试试看,请告诉我。
Compose 还没有这样的功能。您可以在 issue tracker.
上创建功能请求在此实现之前,您可以创建一个绘制大量图像的纯 Compose 解决方案,但我认为当 ImageView
已经由工程师优化时,这样做没有意义。在这种情况下,您可以使用 AndroidView
与旧视图互操作。
@Composable
fun TileAndroidImage(
@DrawableRes drawableId: Int,
contentDescription: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val drawable = remember(drawableId) {
BitmapDrawable(
context.resources,
BitmapFactory.decodeResource(
context.resources,
drawableId
)
).apply {
tileModeX = Shader.TileMode.REPEAT
tileModeY = Shader.TileMode.REPEAT
}
}
AndroidView(
factory = {
ImageView(it)
},
update = { imageView ->
imageView.background = drawable
},
modifier = modifier
.semantics {
this.contentDescription = contentDescription
role = Role.Image
}
)
}
下一部分,将它放在按钮的背景中。在 compose 中,我们使用容器来做到这一点。您可以创建您的 TiledButton
。我将零填充传递给容器按钮并手动添加实际填充,这样它就不会影响背景:
@Composable
fun TiledButton(
onClick: () -> Unit,
@DrawableRes backgroundDrawableId: Int,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
contentColor: Color = MaterialTheme.colors.primary,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
) {
Button(
onClick = onClick,
contentPadding = PaddingValues(0.dp),
enabled = enabled,
shape = shape,
border = border,
elevation = null,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Transparent,
contentColor = contentColor,
disabledBackgroundColor = Color.Transparent,
disabledContentColor = contentColor.copy(alpha = ContentAlpha.disabled),
),
modifier = modifier
) {
Box(
contentAlignment = Alignment.Center,
) {
TileAndroidImage(
drawableId = backgroundDrawableId,
contentDescription = "...",
modifier = Modifier.matchParentSize()
)
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(contentPadding),
content = content,
)
}
}
}
用法:
TiledButton(
onClick = { /*TODO*/ },
backgroundDrawableId = R.drawable.tile,
border = BorderStroke(1.dp, Color.Blue),
) {
Text("Apple")
}