根据宽度为条形着色

时间:2014-02-21 23:20:43

标签: java android math

我想解决一个特殊问题。

拿一个视频游戏健康栏,一个完全绿色,慢慢变红,直到栏的宽度几乎为零时为红色。

我正在制作一个带有条形图的应用程序,该条形图的宽度可以是从屏幕的整个宽度到零的任何位置。我没有根据颜色从一种颜色到另一种颜色改变颜色,而是我想要改变它的 5 颜色。

100%我希望条形为蓝色(#33B5E5)。

80%我希望酒吧是紫色的(#AA66CC)。

60%我希望酒吧是绿色的(#99CC000。

40%我希望酒吧是橙色(#FFBB33)。

最后20%我希望酒吧变红(#FFBB33)。

我遗漏了0%,因为20%以下的任何东西都会保持相同的红色。注意:为了缓解混淆,我有条的百分比,这不是问题,主要目标是当宽度改变时,它是中间颜色的阴影。

示例:在90%时,条形应该是蓝色和紫色之间的颜色,而不是其中之一。

数学上,我将如何做到这一点?

我在技术上用Java做这个,但是任何语言,甚至伪代码的任何解决方案都将被接受。

编辑:我仍然得到给定间隔输出颜色的答案。这不是我想要完成的。这更像是一个数学问题。我希望颜色基于百分比。酒吧唯一应该是紫色的是当百分比完全在80%时,在70%时,颜色应该恰好在紫色和绿色之间。关键是颜色是动态的。将所有突然变为另一种静态颜色的颜色根本不具有视觉上的吸引力:)

4 个答案:

答案 0 :(得分:1)

将这些拼凑在一起,可能需要一些工作:

class HealthBar {

    public static final int ANIMATION_TIME = 500;

    String currentColor;
    View bar; // the view of the 

    public HealthBar(View view) {
        this.bar = view;
        this.currentColor = "#33B5E5";
    }

    public void updateHealthBar(int health) {

        if (health < 20) {
            tintColor("#FFBB33");
        } else if (health < 40) {
            tintColor("#FFBB33");
        } else if (health < 60) {
            tintColor("#99CC000");
        } else if (health < 80) {
            tintColor("#AA66CC");
        } else {
            tintColor("#33B5E5");
        }

    }

    @SuppressLint("NewApi") private void tintColor(String newColor) {

        ColorDrawable[] color = {
                new ColorDrawable(Color.parseColor(currentColor)),
                new ColorDrawable(Color.parseColor(newColor)) };
        TransitionDrawable trans = new TransitionDrawable(color);
        int sdk = android.os.Build.VERSION.SDK_INT;
        if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
            bar.setBackgroundDrawable(trans);
        } else {
            bar.setBackground(trans);
        }
        trans.startTransition(ANIMATION_TIME);

        this.currentColor = newColor;
    }

}

答案 1 :(得分:1)

你需要在数字之间线性地缩小。

例如:

int blue = Integer.parseInt("33B5E5", 16);
int purple = Integer.parseInt("AA66CC", 16);
int green = Integer.parseInt("99CC00", 16);
int orange = Integer.parseInt("FFBB33", 16);
int red = Integer.parseInt("FFBB33", 16);

int[] colors = new int[] {red, orange, green, purple, blue};

//Percent should be 0-100
public int getColorBasedOnPercent(int percent, int[] colors) {
    int intervalSize = 100 / (colors.length - 1);
    int startColor = Math.floor(percent / intervalSize);
    int endColor = Math.ceil(percent / intervalSize);

    float lerpAmount = (percent % intervalSize) / intervalSize;

    return (int)((colors[endColor] - colors[startColor]) * lerpAmount + colors[startColor]);
}

答案 2 :(得分:1)

这是一种重用Android的LinearGradient的方法,它支持色彩停止的非均匀分布。您可以预先构建颜色数组,并将其用作当前百分比的查找。

public static int[] getColors(int size) {

    LinearGradient gradient = new LinearGradient(0, 0, size, 1,
            new int[] {
                    0xffffbb33,
                    0xffffbb33,
                    0xff99cc00,
                    0xffaa66cc,
                    0xFF33b5e5 },
            new float[] {
                    0f, 0.2f, 0.4f, 0.6f, 1f },
            Shader.TileMode.CLAMP);

    Paint p = new Paint();
    p.setStyle(Paint.Style.FILL);
    p.setShader(gradient);

    Bitmap bitmap = Bitmap.createBitmap(size, 1, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawRect(0, 0, size, 1, p);

    int[] colors = new int[size];
    bitmap.getPixels(colors, 0, size, 0, 0, size, 1);
    bitmap.recycle();
    return colors;
}

答案 3 :(得分:0)

另一种可能的方法是使用Color.rgb:

    if (health < 20) {
        //default red here
    } else if (health < 40) {
        Color.rgb(256 - barLenghtPercent, 100, 100); // get something more red the shorter the bar
    } else if (health < 60) {
        // etc. same with other colors