安卓官方确实提供了好多非常强大的工具给我们了,例如我们最近经常在shape中加入gradient(渐变),像我的项目中用的是线性渐变,
-
<?xml version="1.0" encoding="utf-8"?>
-
<shape xmlns:android="http://schemas.android.com/apk/res/android">
-
<corners android:radius="5dip" />
-
<gradient android:startColor="#262626" android:endColor="#ffbc1c" android:angle="0" />
-
</shape>
转载请保留原文链接: http://blog.csdn.net/u010593680/article/details/50987671
并且这个图片作为SeekBar的背景,用来选择颜色,滑到哪就选择哪里的颜色,如图所示:
为此我想到了两种可能的实现方法:
1、获取SeekBar的背景的图片的bitmap,获取对应点来获得颜色
2、直接通过线性渐变的算法获得某个位置上的颜色
方法1 简单方便,对于其他的控件也可以使用,但是消耗的内存比较大
方法2 内存消耗非常少,但是需要了解线性渐变的算法,并且只能对线性渐变的图片有效,其他渐变方式都需要重新写,但是线性渐变往往用得比较多,所以打算使用第二个方法。
线性渐变是最简单的渐变,思想就是对应颜色A的R G B不断的往颜色B的R G B靠近,并且认识到的是:在java中,(很多其他语言也是)用一个int来存放颜色的RGB值,但是这个只是存储方式而已,实际上每个RGB是互不相关的,渐变时需要分别取出,分别变化。写了一个简易的两个颜色渐变的颜色选择器,代码如下:
-
/**
-
* Created by chenxiaoxuan1 on 16/3/25.
-
*/
-
public class LinearGradientUtil {
-
private int mStartColor;
-
private int mEndColor;
-
public LinearGradientUtil(int startColor, int endColor) {
-
this.mStartColor = startColor;
-
this.mEndColor = endColor;
-
}
-
public void setStartColor(int startColor) {
-
this.mStartColor = startColor;
-
}
-
public void setEndColor(int endColor) {
-
this.mEndColor = endColor;
-
}
-
//获取某一个百分比间的颜色,radio取值[0,1]
-
public int getColor(float radio) {
-
int redStart = Color.red(mStartColor);
-
int blueStart = Color.blue(mStartColor);
-
int greenStart = Color.green(mStartColor);
-
int redEnd = Color.red(mEndColor);
-
int blueEnd = Color.blue(mEndColor);
-
int greenEnd = Color.green(mEndColor);
-
int red = (int) (redStart + ((redEnd - redStart) * radio + 0.5));
-
int greed = (int) (greenStart + ((greenEnd - greenStart) * radio + 0.5));
-
int blue = (int) (blueStart + ((blueEnd - blueStart) * radio + 0.5));
-
return Color.argb(255,red, greed, blue);
-
}
-
}
实现后并且用单元测试测试过,然后就正式的使用了,使用结果还是很满意的~
后来,有一个需求是做一个简单的条形颜色选择器,也是用SeekBar实现的,也是线性渐变,只是颜色多了一些而已。如图:
原理是一样的,代码如下:
-
/**
-
* 线性颜色取色器
-
* Created by chenxiaoxuan1 on 16/3/25.
-
*/
-
public class ColorPickGradient {
-
//设置的颜色
-
public static final int[] PICKCOLORBAR_COLORS = new int[]{0xFFFFFFFF,0xFFFF3030, 0xFFF4A460,
-
0xFFFFFF00, 0xFF66CD00,
-
0xFF458B00, 0xFF0000EE,
-
0xFF912CEE,0xFF000000};
-
//每个颜色的位置
-
public static final float[] PICKCOLORBAR_POSITIONS = new float[]{0f, 0.1f, 0.2f, 0.3f, 0.5f, 0.65f,0.8f,0.9f,1f};
-
private int[] mColorArr = PICKCOLORBAR_COLORS;
-
private float[] mColorPosition = PICKCOLORBAR_POSITIONS;
-
public ColorPickGradient(int[] colorArr) {
-
this.mColorArr = colorArr;
-
}
-
public ColorPickGradient() {
-
}
-
/**
-
* 获取某个百分比位置的颜色
-
* @param radio 取值[0,1]
-
* @return
-
*/
-
public int getColor(float radio) {
-
int startColor;
-
int endColor;
-
if (radio >= 1) {
-
return mColorArr[mColorArr.length - 1];
-
}
-
for (int i = 0; i < mColorPosition.length; i++) {
-
if (radio <= mColorPosition[i]) {
-
if (i == 0) {
-
return mColorArr[0];
-
}
-
startColor = mColorArr[i - 1];
-
endColor = mColorArr[i];
-
float areaRadio = getAreaRadio(radio,mColorPosition[i-1],mColorPosition[i]);
-
return getColorFrom(startColor,endColor,areaRadio);
-
}
-
}
-
return -1;
-
}
-
public float getAreaRadio(float radio, float startPosition, float endPosition) {
-
return (radio - startPosition) / (endPosition - startPosition);
-
}
-
/**
-
* 取两个颜色间的渐变区间 中的某一点的颜色
-
* @param startColor
-
* @param endColor
-
* @param radio
-
* @return
-
*/
-
public int getColorFrom(int startColor, int endColor, float radio) {
-
int redStart = Color.red(startColor);
-
int blueStart = Color.blue(startColor);
-
int greenStart = Color.green(startColor);
-
int redEnd = Color.red(endColor);
-
int blueEnd = Color.blue(endColor);
-
int greenEnd = Color.green(endColor);
-
int red = (int) (redStart + ((redEnd - redStart) * radio + 0.5));
-
int greed = (int) (greenStart + ((greenEnd - greenStart) * radio + 0.5));
-
int blue = (int) (blueStart + ((blueEnd - blueStart) * radio + 0.5));
-
return Color.argb(255, red, greed, blue);
-
}
-
}
使用代码如下:
-
private SeekBar mSbColor;
-
//....
-
//设置SeekBar的颜色
-
private void initColorBar(){
-
ShapeDrawable.ShaderFactory shaderFactory = new ShapeDrawable.ShaderFactory() {
-
@Override
-
public Shader resize(int width, int height) {
-
LinearGradient linearGradient = new LinearGradient(0, 0, width, height,
-
ColorPickGradient.PICKCOLORBAR_COLORS, ColorPickGradient.PICKCOLORBAR_POSITIONS, Shader.TileMode.REPEAT);
-
return linearGradient;
-
}
-
};
-
PaintDrawable paint = new PaintDrawable();
-
paint.setShape(new RectShape());
-
paint.setCornerRadius(10);
-
paint.setShaderFactory(shaderFactory);
-
mSbColor.setProgressDrawable(paint);
-
}
-
//当SeekBar被滑动时,获取颜色
-
mSbColor.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-
@Override
-
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-
float radio = (float)progress / mSbColor.getMax();
-
mColor = mColorPickGradient.getColor(radio);
-
}
-
@Override
-
public void onStartTrackingTouch(SeekBar seekBar) {
-
}
-
@Override
-
public void onStopTrackingTouch(SeekBar seekBar) {
-
}
-
});
转载请保留原文链接: http://blog.csdn.net/u010593680/article/details/50987671
Android 用代码设置Shape,corners,Gradient
网上查找资料 记录学习
int strokeWidth = 5; // 3dp 边框宽度
int roundRadius = 15; // 8dp 圆角半径
int strokeColor = Color.parseColor("#2E3135");//边框颜色
int fillColor = Color.parseColor("#DFDFE0");//内部填充颜色
GradientDrawable gd = new GradientDrawable();//创建drawable
gd.setColor(fillColor);
gd.setCornerRadius(roundRadius);
gd.setStroke(strokeWidth, strokeColor);
setBackgroundDrawable(gd);
如果想设置Gradient的渐变色:
方法是改变GradientDrawable的创建方法:
int colors[] = { 0xff255779 , 0xff3e7492, 0xffa6c0cd };//分别为开始颜色,中间夜色,结束颜色 GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);