英文:
How to create a two colour striped Drawable programmatically?
问题
与十多年前提出的类似问题类似:https://stackoverflow.com/questions/8727238/banded-background-with-two-colors
我需要创建一个可绘制对象,作为通用视图的背景,其中有两种不同的矩形条纹颜色,就像国旗一样。如果我能使其中一个矩形拥有弯曲的角落,那就更好了。不幸的是,我需要动态设置颜色,所以不能在XML中定义这个可绘制对象。我该如何在Kotlin中实现这个?
我最好的猜测是这样的,但它不起作用:
background = LayerDrawable(
arrayOf(
GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
layout(0, 0, 100, 20)
background = styles.rootBackground
},
GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadii = floatArrayOf(8f, 8f, 8f, 8f, 0f, 0f, 0f, 0f)
layout(0, 20, 100, 40)
color = styles.robotTextBackgroundColor //需要颜色状态列表 ?!
}
)
)
英文:
Similar to this question asked over 10 years ago:
https://stackoverflow.com/questions/8727238/banded-background-with-two-colors
I need to create a drawable to be the background of a generic view that has two distinct rectangular striped colors, like a flag. Bonus if I can make one of the rectangles have curvy corners. Unfortunately, I need to set the colors dynamically, so I cannot define this drawable in xml. How do I accomplish this in Kotlin.
My best guess was this, but it doesn't work:
background = LayerDrawable(
arrayOf(
GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
layout(0, 0, 100, 20)
background = styles.rootBackground
},
GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadii = floatArrayOf(8f, 8f, 8f, 8f, 0f, 0f, 0f, 0f)
layout(0, 20, 100, 40)
color = styles.robotTextBackgroundColor //requires color state list ?!
}
)
)
答案1
得分: 2
抱歉,以下是您要翻译的内容:
Unfortunately, I need to set the colors dynamically, so I cannot define this drawable in xml.
不幸的是,我需要动态设置颜色,所以无法在XML中定义此可绘制对象。
No, you can do that as an XML drawable, inflate into code, then change the color. That would be much easier than starting from scratch in code.
不,您可以将其创建为XML可绘制对象,然后在代码中进行充气(inflate),然后更改颜色。这比从头开始编写代码要容易得多。
But this requires to attach ids to the layer list items that you need to change their colors
但这需要将ID附加到您需要更改颜色的图层列表项。
Here is a demo from the referenced post:
这是来自引用帖子的演示:
R.drawable.test:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
</shape>
</item>
</layer-list>
这是R.drawable.test:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
</shape>
</item>
</layer-list>
Here we'll change the color of the redRect
item from red to green, then set the entire drawable to the root view background:
在这里,我们将把redRect
项的颜色从红色更改为绿色,然后将整个可绘制对象设置为根视图的背景:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val background = ResourcesCompat.getDrawable(resources, R.drawable.test, null)
if (background is LayerDrawable) {
val bgLayer =
background.findDrawableByLayerId(R.id.redRect) as GradientDrawable
bgLayer.setColor(Color.GREEN)
findViewById<ConstraintLayout>(R.id.root).background = background
}
}
在onCreate
方法中,我们将redRect
项的颜色更改为绿色,然后将整个可绘制对象设置为根视图的背景。
Bonus if I can make one of the rectangles have curvy corners.
如果我可以让其中一个矩形拥有圆角,那就更好了。
You'd use the <corners>
tag within the shape, and define the radius:
您可以在形状内使用<corners>
标签,并定义半径:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
<corners android:radius="30dp" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
<corners
android:bottomLeftRadius="30dp"
android:bottomRightRadius="30dp" />
</shape>
</item>
</layer-list>
您可以在形状内使用<corners>
标签,并定义半径:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
<corners android:radius="30dp" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
<corners
android:bottomLeftRadius="30dp"
android:bottomRightRadius="30dp" />
</shape>
</item>
</layer-list>
英文:
> Unfortunately, I need to set the colors dynamically, so I cannot define this drawable in xml.
No, you can do that as an XML drawable, inflate into code, then change the color. That would be much easier than starting from scratch in code.
But this requires to attach ids to the layer list items that you need to change their colors
Here is a demo from the referenced post:
R.drawable.test:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
</shape>
</item>
</layer-list>
Here we'll change the color of the redRect
item from red to green, then set the entire drawable to the root view background:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val background = ResourcesCompat.getDrawable(resources, R.drawable.test, null)
if (background is LayerDrawable) {
val bgLayer =
background.findDrawableByLayerId(R.id.redRect) as GradientDrawable
bgLayer.setColor(Color.GREEN)
findViewById<ConstraintLayout>(R.id.root).background = background
}
}
> Bonus if I can make one of the rectangles have curvy corners.
You'd use the <corners>
tag within the shape, and define the radius:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/redRect"
android:bottom="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#ff0000" />
<corners android:radius="30dp" />
</shape>
</item>
<item
android:id="@+id/blueRect"
android:top="20dp">
<shape android:shape="rectangle">
<size android:height="20dp" />
<solid android:color="#0000ff" />
<corners
android:bottomLeftRadius="30dp"
android:bottomRightRadius="30dp" />
</shape>
</item>
</layer-list>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论