我想解决一个特殊问题。
拿一个视频游戏健康栏,一个完全绿色,慢慢变红,直到栏的宽度几乎为零时为红色。
我正在制作一个带有条形图的应用程序,该条形图的宽度可以是从屏幕的整个宽度到零的任何位置。我没有根据颜色从一种颜色到另一种颜色改变颜色,而是我想要改变它的 5 颜色。
100%我希望条形为蓝色(#33B5E5)。
80%我希望酒吧是紫色的(#AA66CC)。
60%我希望酒吧是绿色的(#99CC000。
40%我希望酒吧是橙色(#FFBB33)。
最后20%我希望酒吧变红(#FFBB33)。
我遗漏了0%,因为20%以下的任何东西都会保持相同的红色。注意:为了缓解混淆,我有条的百分比,这不是问题,主要目标是当宽度改变时,它是中间颜色的阴影。
示例:在90%时,条形应该是蓝色和紫色之间的颜色,而不是其中之一。
数学上,我将如何做到这一点?
我在技术上用Java做这个,但是任何语言,甚至伪代码的任何解决方案都将被接受。
编辑:我仍然得到给定间隔输出颜色的答案。这不是我想要完成的。这更像是一个数学问题。我希望颜色基于百分比。酒吧唯一应该是紫色的是当百分比完全在80%时,在70%时,颜色应该恰好在紫色和绿色之间。关键是颜色是动态的。将所有突然变为另一种静态颜色的颜色根本不具有视觉上的吸引力:)
答案 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