SeekBar究极进化效果—让滑块和渐变色进度条同步变色
作者:互联网
先看效果
静态细节:
滑动条是一个渐变色的,滑块会根据当前的位置动态变化,保持与所在位置的滑动条颜色一致。
使用到的技术点:
1.xml渐变色
2.渐变色算法
3.drawable图层
4.drawable动态修改背景色
下面逐一介绍一下:
xml渐变色
用xml的渐变色写滑动条的自定义背景:(直接上代码了)
上面那个seekbar的背景:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="24dp" />
<gradient
android:endColor="@color/seekbar_right"
android:centerColor="@color/seekbar_center"
android:startColor="@color/seekbar_left"
android:type="linear" />
</shape>
下面seekbar的背景:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="24dp" />
<gradient
android:centerColor="@color/seekbar_center"
android:endColor="@color/seekbar_right"
android:startColor="@color/seekbar_left"
android:type="linear" />
</shape>
</clip>
</item>
</layer-list>
颜色:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="seekbar_left">#FF436CFF</color>
<color name="seekbar_center">#FFF9DA55</color>
<color name="seekbar_right">#FFF74343</color>
<color name="seekbar_thumb_stroke_color">#FFF5F6FF</color>
</resources>
渐变色算法
用于获取当前位置的颜色
public class ColorPickGradient {
private int[] mColorArr ;
private float[] mColorPosition ;
public ColorPickGradient(int[] colorArr,float[] mColorPosition ) {
this.mColorArr = colorArr;
this.mColorPosition = mColorPosition;
}
/**
* 获取某个百分比位置的颜色
* @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);
}
}
3.drawable图层
滑块的drawable,是一个图层。背景是可变的,左右两个白色小箭头是第二层,不变。
上代码:(thumb图层代码)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/seekbar_thumb_ground_floor" />
<item
android:width="@dimen/seekbar_thumb_arrows_width"
android:height="@dimen/seekbar_thumb_arrows_height"
android:bottom="@dimen/seekbar_thumb_arrows_bottom"
android:drawable="@drawable/thumb_left"
android:left="@dimen/seekbar_thumb_arrows_left"
android:top="@dimen/seekbar_thumb_arrows_top" />
<item
android:width="@dimen/seekbar_thumb_arrows_width"
android:height="@dimen/seekbar_thumb_arrows_height"
android:bottom="@dimen/seekbar_thumb_arrows_bottom"
android:drawable="@drawable/thumb_right"
android:gravity="right"
android:right="@dimen/seekbar_thumb_arrows_right"
android:top="@dimen/seekbar_thumb_arrows_top" />
</layer-list>
圆圈的那个背景
左右那两个小箭头图标是我自己截的图,如果实际使用的话可以让美工给切图
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<!--背景色动态修改,默认值设置为seekbar的最左侧的颜色 -->
<solid android:color="@color/seekbar_left" />
<stroke
android:width="@dimen/seekbar_thumb_stroke_width"
android:color="@color/seekbar_thumb_stroke_color" />
<size
android:width="@dimen/seekbar_thumb_width"
android:height="@dimen/seekbar_thumb_height" />
</shape>
4.drawable动态修改背景色
先看代码:
public class GradientSeekBar extends androidx.appcompat.widget.AppCompatSeekBar {
private ColorPickGradient mColorPickGradient;
public GradientSeekBar(Context context) {
super(context);
init();
}
public GradientSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GradientSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
this.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mColorPickGradient != null) {
float radio = (float) progress / seekBar.getMax();
int mColor = mColorPickGradient.getColor(radio);
LayerDrawable layerDrawable = (LayerDrawable) seekBar.getThumb();
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.getDrawable(0);
gradientDrawable.setColor(mColor);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void setColorPickGradient(
ColorPickGradient mColorPickGradient) {
this.mColorPickGradient = mColorPickGradient;
}
}
LayerDrawable layerDrawable = (LayerDrawable) seekBar.getThumb(); 获取到图层drawable; GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.getDrawable(0); 取出图层第一个drawable; 给该drawable设置新的颜色(取色器取出来的) gradientDrawable.setColor(mColor);
完事~
标签:究极,滑块,int,渐变色,radio,context,drawable,public 来源: https://blog.csdn.net/mace_android/article/details/118556204