在Android上运行时更改渐变背景色

29

我正在尝试使用Drawable背景,并且到目前为止没有遇到任何问题。

现在我想在运行时更改渐变背景颜色。

不幸的是,似乎没有API可以在运行时更改它。甚至尝试使用mutate()方法来修改drawable也不行,正如这里所解释的一样:Drawable mutations

示例XML如下。 它按预期工作。

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#330000FF"
        android:endColor="#110000FF"
        android:angle="90"/>
</shape>

很遗憾,我需要一个包含各种颜色的列表,并且它们必须在运行时通过编程方式进行修改。

是否有另一种方法可以在运行时创建此渐变背景?甚至完全不使用XML也可以吗?

5个回答

47

是的!我找到了一种方法!

必须放弃XML,但是这就是我做的方式:

在我的getView()重载函数(ListAdapter)中,我只需要:

    int h = v.getHeight();
    ShapeDrawable mDrawable = new ShapeDrawable(new RectShape());
    mDrawable.getPaint().setShader(new LinearGradient(0, 0, 0, h, Color.parseColor("#330000FF"), Color.parseColor("#110000FF"), Shader.TileMode.REPEAT));
    v.setBackgroundDrawable(mDrawable);

接下来我得到了与上面XML背景相同的结果。现在我可以通过编程设置背景颜色。


3
可以给一个大于某个角度值的数吗? - Ahmed Faisal
1
如果您在活动中使用此功能,建议您将其放在onWindowFocusChanges()中运行,而不是在onCreate()中。 - Juuso Ohtonen

12

我尝试使用Phenome的Button视图解决方案。但不知何故它没有起作用。

我想出了另一种方法:(参考:Android API演示示例)

package com.example.testApp;

import android.app.Activity;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.View;

public class TetApp extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        View v = findViewById(R.id.btn);
        v.setBackgroundDrawable( new DrawableGradient(new int[] { 0xff666666, 0xff111111, 0xffffffff }, 0).SetTransparency(10));

    }

    public class DrawableGradient extends GradientDrawable {
        DrawableGradient(int[] colors, int cornerRadius) {
            super(GradientDrawable.Orientation.TOP_BOTTOM, colors);

            try {
                this.setShape(GradientDrawable.RECTANGLE);
                this.setGradientType(GradientDrawable.LINEAR_GRADIENT);
                this.setCornerRadius(cornerRadius);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public DrawableGradient SetTransparency(int transparencyPercent) {
            this.setAlpha(255 - ((255 * transparencyPercent) / 100));

            return this;
        }
    }
}

9

请使用我下面的代码:

 int[] colors = new int[2];
            colors[0] = getRandomColor();
            colors[1] = getRandomColor();


            GradientDrawable gd = new GradientDrawable(
                    GradientDrawable.Orientation.TOP_BOTTOM, colors);

            gd.setGradientType(GradientDrawable.RADIAL_GRADIENT);
            gd.setGradientRadius(300f);
            gd.setCornerRadius(0f);
            YourView.setBackground(gd);

生成随机颜色的方法:
public static int getRandomColor(){
    Random rnd = new Random();
    return Color.argb(255, rnd.nextInt(256), rnd.nextInt(56), rnd.nextInt(256));
}

1
Phenome提供的答案的Kotlin版本,作为扩展函数:

answer

fun View.backgroundGradientDrawable(@ColorInt startColor: Int, @ColorInt endColor: Int): Unit {
    val h = this.height.toFloat()
    val shapeDrawable = ShapeDrawable(RectShape())
    shapeDrawable.paint.shader =
        LinearGradient(0f, 0f, 0f, h, startColor, endColor, Shader.TileMode.REPEAT)
    this.background = shapeDrawable
}

"

Github

" 这句话的意思是:"

{{链接1:Github}}

"。

0
根据您的要求,使用颜色状态列表而不是固定颜色的startColor和endColor可能会实现您想要的效果。

有趣的替代方案,但我真的需要更动态的东西。它是一个列表,显示来自不同可插拔提供者的信息。每个提供者都有自定义颜色,因此用户知道该信息来自哪里。我知道这不是很多信息,但也许会有所帮助。 - Phenome

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接