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);

项目地址:mace-android/GradientSeekBar · GitHub

完事~

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
实现播放、暂停、上一首、下一首、渐变色进度条和时间点可以通过MediaPlayer和SeekBar组合实现。具体步骤如下: 1. 在布局文件中添加MediaPlayer和SeekBar组件,如下所示: ```xml <SeekBar android:id="@+id/seekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:progressDrawable="@drawable/custom_seekbar_progress" android:thumb="@drawable/custom_seekbar_thumb" /> <Button android:id="@+id/btnPrevious" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Previous" /> <Button android:id="@+id/btnPlayPause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Play" /> <Button android:id="@+id/btnNext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Next" /> ``` 2. 在Activity中实例化MediaPlayer和SeekBar组件,并设置监听器,如下所示: ```java private MediaPlayer mediaPlayer; private SeekBar seekBar; private int[] musicList = {R.raw.music1, R.raw.music2, R.raw.music3}; private int currentTrack = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mediaPlayer = MediaPlayer.create(this, musicList[currentTrack]); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { playNextTrack(); } }); seekBar = findViewById(R.id.seekBar); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { mediaPlayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); Button btnPrevious = findViewById(R.id.btnPrevious); btnPrevious.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { playPreviousTrack(); } }); Button btnPlayPause = findViewById(R.id.btnPlayPause); btnPlayPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mediaPlayer.isPlaying()) { pauseTrack(); } else { playTrack(); } } }); Button btnNext = findViewById(R.id.btnNext); btnNext.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { playNextTrack(); } }); } ``` 3. 实现播放、暂停、上一首、下一首功能,如下所示: ```java private void playTrack() { mediaPlayer.start(); updateSeekBar(); Button btnPlayPause = findViewById(R.id.btnPlayPause); btnPlayPause.setText("Pause"); } private void pauseTrack() { mediaPlayer.pause(); Button btnPlayPause = findViewById(R.id.btnPlayPause); btnPlayPause.setText("Play"); } private void playPreviousTrack() { if (currentTrack > 0) { currentTrack--; } else { currentTrack = musicList.length - 1; } mediaPlayer.stop(); mediaPlayer = MediaPlayer.create(this, musicList[currentTrack]); playTrack(); } private void playNextTrack() { if (currentTrack < musicList.length - 1) { currentTrack++; } else { currentTrack = 0; } mediaPlayer.stop(); mediaPlayer = MediaPlayer.create(this, musicList[currentTrack]); playTrack(); } ``` 4. 实现渐变色进度条和时间点功能,如下所示: ```java private void updateSeekBar() { seekBar.setMax(mediaPlayer.getDuration()); new Handler().postDelayed(new Runnable() { @Override public void run() { seekBar.setProgress(mediaPlayer.getCurrentPosition()); updateSeekBar(); } }, 1000); int minutes = (mediaPlayer.getCurrentPosition() / 1000) / 60; int seconds = (mediaPlayer.getCurrentPosition() / 1000) % 60; String time = String.format("%d:%02d", minutes, seconds); TextView txtTime = findViewById(R.id.txtTime); txtTime.setText(time); } ``` 5. 最后,添加自定义SeekBar的样式,如下所示: ```xml <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <color android:color="#BDBDBD" /> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="4dp" /> <gradient android:angle="0" android:endColor="#FF4081" android:startColor="#3F51B5" /> </shape> </clip> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="4dp" /> <gradient android:angle="0" android:endColor="#FF4081" android:startColor="#3F51B5" /> </shape> </clip> </item> </layer-list> ``` 至此,实现了Android url MP3实现播放、暂停、上一首、下一首、渐变色进度条和时间点的功能。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值