如何以编程方式创建一个两种颜色的条纹Drawable?

huangapple go评论69阅读模式
英文:

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项的颜色更改为绿色,然后将整个可绘制对象设置为根视图的背景。

如何以编程方式创建一个两种颜色的条纹Drawable?

如何以编程方式创建一个两种颜色的条纹Drawable?

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>

如何以编程方式创建一个两种颜色的条纹Drawable?

如何以编程方式创建一个两种颜色的条纹Drawable?

英文:

> 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:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layer-list xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;item
        android:id=&quot;@+id/redRect&quot;
        android:bottom=&quot;20dp&quot;&gt;
        &lt;shape android:shape=&quot;rectangle&quot;&gt;
            &lt;size android:height=&quot;20dp&quot; /&gt;
            &lt;solid android:color=&quot;#ff0000&quot; /&gt;
        &lt;/shape&gt;
    &lt;/item&gt;

    &lt;item
        android:id=&quot;@+id/blueRect&quot;
        android:top=&quot;20dp&quot;&gt;
        &lt;shape android:shape=&quot;rectangle&quot;&gt;
            &lt;size android:height=&quot;20dp&quot; /&gt;
            &lt;solid android:color=&quot;#0000ff&quot; /&gt;
        &lt;/shape&gt;
    &lt;/item&gt;

&lt;/layer-list&gt;

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&lt;ConstraintLayout&gt;(R.id.root).background = background
    }
}

如何以编程方式创建一个两种颜色的条纹Drawable?

> Bonus if I can make one of the rectangles have curvy corners.

You'd use the &lt;corners&gt; tag within the shape, and define the radius:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layer-list xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;item
        android:id=&quot;@+id/redRect&quot;
        android:bottom=&quot;20dp&quot;&gt;
        &lt;shape android:shape=&quot;rectangle&quot;&gt;
            &lt;size android:height=&quot;20dp&quot; /&gt;
            &lt;solid android:color=&quot;#ff0000&quot; /&gt;
            &lt;corners android:radius=&quot;30dp&quot; /&gt;
        &lt;/shape&gt;
    &lt;/item&gt;

    &lt;item
        android:id=&quot;@+id/blueRect&quot;
        android:top=&quot;20dp&quot;&gt;
        &lt;shape android:shape=&quot;rectangle&quot;&gt;
            &lt;size android:height=&quot;20dp&quot; /&gt;
            &lt;solid android:color=&quot;#0000ff&quot; /&gt;
            &lt;corners
                android:bottomLeftRadius=&quot;30dp&quot;
                android:bottomRightRadius=&quot;30dp&quot; /&gt;
        &lt;/shape&gt;
    &lt;/item&gt;

&lt;/layer-list&gt;

如何以编程方式创建一个两种颜色的条纹Drawable?

huangapple
  • 本文由 发表于 2023年6月5日 22:48:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76407635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定