其他分享
首页 > 其他分享> > SeekBar究极进化效果—让滑块和渐变色进度条同步变色

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