2014-02-21 31 views
0

我有一个特别的问题,我正试图解决。根据其宽度对条进行着色

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

我正在制作一个应用程序,它有一个小节,并且小节的宽度可以从屏幕的整个宽度到零。而不是根据条从一种颜色到另一种颜色的宽度来改变颜色,我有我想从它改变的颜色颜色。

在100%我想酒吧是蓝色的(#33B5E5)。

在80%我想酒吧是紫色的(#AA66CC)。

在60%我想要的栏为绿色(#99CC000。

在40%我想酒吧是橙色(#FFBB33)。

,并最终在20%我想了吧(#FFBB33)

因为低于20%的东西都会留下相同的红色,所以我会舍弃0%注意:为了减轻混淆,我有酒吧的百分比,这不是问题,主要目标是在宽度变化的同时,它是中间色的阴影。

例如:在90%时,酒吧应该是正好在蓝色和紫色之间的颜色,而不是他们中的任何一个。

在数学上,我该如何去做这件事?

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

编辑:我仍然得到答案,输出给定的间隔的颜色输出。这不是我想要完成的。这更像是一个数学问题。我想根据的百分比颜色为。唯一一次该酒吧应该是紫色的时候,百分比是正好在80%,在70%的颜色应该是完全在紫色和绿色之间。重点是,颜色是动态的。颜色改变所有的突然到另一个静态颜色根本没有视觉上的趣味:)

+1

实际上是伪代码已经包含在你的问题;-) – donfuxx

+0

我的答案事实上确实使色彩之间的过渡,如果需要的话会使你所寻求的视觉效果,所以只添加更多的色彩的步骤。每改变5%的健康状况我都会认为这足以让人感觉愉快。 – cYrixmorten

回答

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; 
} 
+0

这是如何工作的百分比?我为尺寸参数输入了什么?我相信这个作品我只是想知道如何,谢谢! – AggieDev

+0

如果你传递一个101的大小,你会得到一个长度为101的int数组,你需要索引范围从0到100%。所以你可以使用颜色[Math.round(百分比)]。如果你想要更细微的细微差别,例如一个不同的颜色值为每半个百分点,你可能会加倍数组的大小。 –

+0

啊,我已经得到你了,谢谢你!非常棒! – AggieDev

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

你需要的之间线性线性插值数字。

例如:

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]); 
} 
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 
相关问题