Android自定义可控制精度带刻度盘和波纹效果的炫酷SeekBar

一、前言

最近项目里面需要用到多个seekbar并且需要显示不同的精度,于是参考了部分博客模仿华为的天气刻度盘添加了精度控制和自己定义的seekbar实现了如下效果(画面模糊是因为录制Gif图的工具导致的)。

本控件最低兼容到API16 更低的版本没有getThumb()函数

二、刻度盘部分

  • 1.刻度:刻度的绘制类似于绘制时钟刻度绘制出一条刻度通过旋转canvas绘制出其他刻度

  • 2.波浪:波浪的绘制是通过两个正弦函数y = Asin(wx+b)+h 实时变换sin的初相

  • 3.精度控制:通过设定 精度模式,最大进度值和显示的最大值共同决定。最大进度值/当前进度值=实际显示的最大值/当前显示的值

  • 4.WaveDialView代码:

      package com.hubin.scaleseekbar;
      /*
       *  @项目名:  ScaleSeekBar
       *  @包名:    com.hubin.scaleseekbar
       *  @文件名:   DigitalThumbSeekbar
       *  @创建者:   胡英姿
       *  @创建时间:  2018-03-10 14:38
       *  @描述:    一个带水波纹的刻度盘自定义view
       */
      
      import android.content.Context;
      import android.graphics.Canvas;
      import android.graphics.Color;
      import android.graphics.Paint;
      import android.graphics.Path;
      import android.graphics.RectF;
      import android.util.AttributeSet;
      import android.view.View;
      
      import java.text.DecimalFormat;
      import java.util.Timer;
      import java.util.TimerTask;
      
      public class WaveDialView extends View {
          private static final String TAG = "ScaleView";
      
          public static final int PRECISION_MODE_INTEGER =0; //整数模式
          public static final int PRECISION_MODE_ONE_DECIMAL_PLACES =1; //精确到小数点后一位
          public static final int PRECISION_MODE_TWO_DECIMAL_PLACES =2;//精确到小数点后两位
          public  int PRECISION_MODE_DEFUALE =PRECISION_MODE_INTEGER;//默认精度模式  整数模式
      
          private float mMaxValue = 100; //显示的最大值
      
          private String textUnit = ""; //右上角文字 单位
          private String textName = "";//中间要显示的文字名字
      
          // 画圆弧的画笔
          private Paint paint;
          // 正方形的宽高
          private int len;
          // 圆弧的半径
          private float radius;
          // 矩形
          private RectF oval;
          // 圆弧的起始角度
          private float startAngle = 120;
          // 圆弧的经过总范围角度角度
          private float sweepAngle = 300;
      
          // 刻度经过角度范围
          private float targetAngle = 300;
      
          // 绘制文字
          Paint textPaint;
      
          // 监听角度变化对应的颜色变化
          private OnAngleColorListener onAngleColorListener;
      
          public WaveDialView(Context context) {
              this(context,null);
          }
      
          public WaveDialView(Context context, AttributeSet attrs) {
              super(context, attrs);
              paint = new Paint();
              paint.setColor(Color.WHITE);
              paint.setAntiAlias(true);
              paint.setStyle(Paint.Style.STROKE);
      
              textPaint = new Paint();
              textPaint.setARGB(255, 255, 255, 255);
              textPaint.setAntiAlias(true);
      
              waterPaint = new Paint();
              waterPaint.setAntiAlias(true);
      
              moveWaterLine();//让水波纹开始运动
          }
      
          /**
           * 设置动画效果,开启子线程定时绘制
           *
           * @param trueAngle
           */
          // 前进或者后退的状态,1代表前进,2代表后退。初始为后退状态。
          int state = 2;
          // 每次后退时的值,实现越来越快的效果
          private int[] back = {2, 2, 4, 4, 6, 6, 8, 8, 10};
          // 每次前进时的值,实现越来越慢的效果
          private int[] go = {10, 10, 8, 8, 6, 6, 4, 4, 2};
          // 前进的下标
          private int go_index = 0;
          // 后退的下标
          private int back_index = 0;
          private float score;
          private int color;
      
          private boolean isRunning;
      
          /**
           * 使用定时器自动开始变幻刻度
           *
           * @param trueAngle
           */
          public void change(final float trueAngle) {
              if (isRunning) {
                  return;
              }
              final Timer timer = new Timer();
              timer.schedule(new TimerTask() {
      
                  @Override
                  public void run() {
                      switch (state) {
                          case 1:
                              // 开始增加
                              targetAngle += go[go_index];
                              go_index++;
                              if (go_index == go.length) {// 到最后的元素时,下标一直为最后的
                                  go_index--;
                              }
                              if (targetAngle >= trueAngle) {// 如果画过刻度大于等于真实角度
                                  // 画过刻度=真实角度
                                  targetAngle = trueAngle;
                                  // 状态改为2
                                  state = 2;
                                  isRunning = false;
                                  timer.cancel();
                              }
                              break;
                          case 2:
                              isRunning = true;
                              targetAngle -= back[back_index];
                              back_index++;
                              if (back_index == back.length) {
                                  back_index--;
                              }
      
                              if (targetAngle <= 0) {
                                  targetAngle = 0;
                                  state = 1;
                              }
                              break;
                          default:
                              break;
                      }
                      computerScore();// 计算当前比例应该的多少分
                      // 计算出当前所占比例,应该增长多少
                      computerUp();
      
                      postInvalidate();
                  }
              }, 500, 30);
          }
      
          /**
           * 手动设置刻度盘的值
           * @param trueAngle  0-300
           */
          public void setChange(final float trueAngle) {
              targetAngle = trueAngle;
              computerScore();//计算得分
      
              if (clipRadius == 0) {
                  final Timer timer = new Timer();
                  timer.schedule(new TimerTask() {
                      @Override
                      public void run() {
                          if (clipRadius != 0) {
                              // 计算出当前所占比例,应该增长多少
                              computerUp();
                              postInvalidate();
                              timer.cancel();
                          }
                      }
                  }, 0, 10);
              } else {
                  computerUp();
                  invalidate();
              }
          }
      
      
          //计算当前比例应该得多少分
          private void computerScore() {
              score = targetAngle / 300 * mMaxValue;
          }
      
          //计算水位
          private void computerUp() {
              up = (int) (targetAngle / 360 * clipRadius * 2);
          }
      
          /**
           * 调用此方法水波纹开始运动
           */
          public void moveWaterLine() {
              final Timer timer = new Timer();
              timer.schedule(new TimerTask() {
      
                  @Override
                  public void run() {
                      move += 1;
                      if (move == 100) {
                          timer.cancel();
                      }
                      postInvalidate();
                  }
              }, 500, 200);
          }
      
          // 存放第一条水波Y值
          private float[] firstWaterLine;
          // 第二条
          private float[] secondWaterLine;
          // 画水球的画笔
          private Paint waterPaint;
          // 影响三角函数的初相
          private float move;
          // 剪切圆的半径
          private int clipRadius;
          // 水球的增长值
          int up = 0;
      
          @Override
          protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      
              // 通过测量规则获得宽和高
              int width = MeasureSpec.getSize(widthMeasureSpec);
              int height = MeasureSpec.getSize(heightMeasureSpec);
              // 取出最小值
              len = Math.min(width, height);
              oval = new RectF(0, 0, len, len);
              radius = len / 2;
              clipRadius = (len / 2) - 45;
              firstWaterLine = new float[len];
              secondWaterLine = new float[len];
              setMeasuredDimension(len, len);
          }
      
          @Override
          protected void onDraw(Canvas canvas) {
              // 绘制一个圆弧,如果懂得坐标系的旋转,可以不写。
              // canvas.drawArc(oval, startAngle, sweepAngle, false, paint);
              // 画布,圆心左边,半径,起始角度,经过角度,
              // 说白了就是canvas没有提供画特殊图形的方法,就需要我们自己去实现这种功能了
              // 画刻度线
              drawLine(canvas);
              // 画刻度线内的内容
              drawText(canvas);
      
          }
      
          /**
           * 画水球的功能
           *
           * @param canvas
           */
          private void drawWaterView(Canvas canvas) {
              // y = Asin(wx+b)+h ,w影响周期,A影响振幅,h影响y位置,b为初相;
              // 将周期定为view总宽度
              float mCycleFactorW = (float) (2 * Math.PI / len);
      
              // 得到第一条波的y值
              for (int i = 0; i < len; i++) {
                  firstWaterLine[i] = (float) (10 * Math
                          .sin(mCycleFactorW * i + move) - up);
              }
              // 得到第一条波的y值
              for (int i = 0; i < len; i++) {
                  secondWaterLine[i] = (float) (15 * Math.sin(mCycleFactorW * i
                          + move + 10) - up);
      
              }
      
              canvas.save();
      
              // 裁剪成圆形区域
              Path path = new Path();
              waterPaint.setColor(color);
              path.reset();
              canvas.clipPath(path);
      
              path.addCircle(len / 2, len / 2, clipRadius, Path.Direction.CCW);
              canvas.clipPath(path, android.graphics.Region.Op.REPLACE);
              // 将坐标系移到底部
              canvas.translate(0, len / 2 + clipRadius);
      
              for (int i = 0; i < len; i++) {
                  canvas.drawLine(i, firstWaterLine[i], i, len, waterPaint);
              }
              for (int i = 0; i < len; i++) {
                  canvas.drawLine(i, secondWaterLine[i], i, len, waterPaint);
              }
              canvas.restore();
          }
      
          /**
           * 实现画刻度线内的内容
           *
           * @param canvas
           */
          private void drawText(Canvas canvas) {
              Paint cPaint = new Paint();
              // cPaint.setARGB(50, 236, 241, 243);
              cPaint.setAlpha(50);
              cPaint.setARGB(50, 236, 241, 243);
              // 画圆形背景
              RectF smalloval = new RectF(40, 40, radius * 2 - 40, radius * 2 - 40);
              // 画水波
              drawWaterView(canvas);
              canvas.drawArc(smalloval, 0, 360, true, cPaint);
              // 在小圆圈的外围画一个白色圈
              canvas.drawArc(smalloval, 0, 360, false, paint);
              // 设置文本对齐方式,居中对齐
              textPaint.setTextAlign(Paint.Align.CENTER);
              textPaint.setTextSize(clipRadius / 2);
              // 画分数
              switch (PRECISION_MODE_DEFUALE) {
                  case PRECISION_MODE_ONE_DECIMAL_PLACES://小数点后一位
                      float  f1Score   =  (float)(Math.round(score*10))/10;
                      canvas.drawText("" + f1Score, radius, radius, textPaint);
                      break;
                  case PRECISION_MODE_TWO_DECIMAL_PLACES://小数点后两位
                      DecimalFormat   fnum  =   new DecimalFormat("##0.00");
                      String   f2Score=fnum.format(score);
                      canvas.drawText( f2Score, radius, radius, textPaint);
                      break;
                  default://默认 整数模式
                      canvas.drawText("" + (int)score, radius, radius, textPaint);
                      break;
              }
      
              textPaint.setTextSize(clipRadius / 6);
      
              // 画固定值分
              canvas.drawText(textUnit, radius + clipRadius / 2, radius - clipRadius / 4, textPaint);
              textPaint.setTextSize(clipRadius / 6);
              // 画固定值立即优化
              canvas.drawText(textName, radius, radius + clipRadius / 2, textPaint);
      
          }
      
      
          float a = sweepAngle / 100;
          private Paint linePaint;
      
          /**
           * 实现画刻度线的功能
           *
           * @param canvas
           */
          private void drawLine(final Canvas canvas) {
              // 保存之前的画布状态
              canvas.save();
              // 移动画布,实际上是改变坐标系的位置
              canvas.translate(radius, radius);
              // 旋转坐标系,需要确定旋转角度
              canvas.rotate(30);
              // 初始化画笔
              linePaint = new Paint();
              // 设置画笔的宽度(线的粗细)
              linePaint.setStrokeWidth(2);
              // 设置抗锯齿
              linePaint.setAntiAlias(true);
              // 累计叠加的角度
              float c = 0;
              for (int i = 0; i <= 100; i++) {
      
                  if (c <= targetAngle && targetAngle != 0) {// 如果累计画过的角度,小于当前有效刻度
                      // 计算累计划过的刻度百分比(画过的刻度比上中共进过的刻度)
                      double p = c / (double) sweepAngle;
      
                      int red = 255 - (int) (p * 255);
                      int green = (int) (p * 255);
                      color = linePaint.getColor();
                      if (onAngleColorListener != null) {
                          onAngleColorListener.onAngleColorListener(red, green);
                      }
                      linePaint.setARGB(255, red, green, 50);
                      canvas.drawLine(0, radius, 0, radius - 20, linePaint);
                      // 画过的角度进行叠加
                      c += a;
                  } else {
                      linePaint.setColor(Color.WHITE);
                      canvas.drawLine(0, radius, 0, radius - 20, linePaint);
                  }
      
                  canvas.rotate(a);
              }
              // 恢复画布状态。
              canvas.restore();
          }
      
      
          public void setOnAngleColorListener(
                  OnAngleColorListener onAngleColorListener) {
              this.onAngleColorListener = onAngleColorListener;
          }
      
          /**
           * 默认初始化配置  精度模式为整数 最大值为100
           * @param textName  水球中间显示的名字
           * @param textUnit  右上角的单位
           */
          public  void setInitConfig(String textName,String textUnit) {
              this.textName = textName;
              this.textUnit = textUnit;
          }
      
          /**
           * 默认初始化配置  精度模式为整数
           * @param maxValue  最大值
           * @param textName  水球中间显示的名字
           * @param textUnit  右上角的单位
           */
          public  void setInitConfig(int maxValue,String textName,String textUnit) {
              mMaxValue= maxValue;
              this.textName = textName;
              this.textUnit = textUnit;
          }
          /**
           * 初始化配置
           * @param precisionModeDefuale 精度模式
           * @param maxValue  最大值
           * @param textName  水球中间显示的名字
           * @param textUnit  右上角的单位
           */
          public  void setInitConfig(int precisionModeDefuale,float maxValue,String textName,String textUnit) {
              PRECISION_MODE_DEFUALE = precisionModeDefuale;
              mMaxValue= maxValue;
              this.textName = textName;
              this.textUnit = textUnit;
          }
      
      
          /**
           * 监听角度和颜色变化的接口
           *
           * @author Administrator
           */
          public interface OnAngleColorListener {
              void onAngleColorListener(int red, int green);
          }
      }
    

三、自定义seekbar

  • 1.thumb(滑块):通过扩展已有的seekbar控件获取滑块位置并且通过canvas绘制图像和进度的数值

  • 2.进度线:进度线条是一个圆角的矩形通过滑块的位置绘制矩形的长度,滑块左边一根右边一根拼起来

  • 3.尺寸的确定都是基于滑块而绘制的所以在初始化时需要先有一个确定尺寸的滑块,我是在drawable中定义的一个只有尺寸的滑块,这样做的缺陷在于在XML布局文件中的android:layout_height="" 任何设置均无效设置成wrap_content即可,要调整大小就修改drawable中绘制的滑块的尺寸

  • 4.精度控制:原理同刻度盘精度控制

  • 5.DigitalThumbSeekbar代码:

      package com.hubin.scaleseekbar;
      
      /*
       *  @项目名:  ScaleSeekBar 
       *  @包名:    com.hubin.scaleseekbar
       *  @文件名:   DigitalThumbSeekbar
       *  @创建者:   胡英姿
       *  @创建时间:  2018-03-10 14:38
       *  @描述:    自定义进度显示在thumb上的Seekbar
       */
      
      import android.content.Context;
      import android.content.res.TypedArray;
      import android.graphics.Canvas;
      import android.graphics.Color;
      import android.graphics.Paint;
      import android.graphics.Rect;
      import android.graphics.RectF;
      import android.graphics.drawable.Drawable;
      import android.support.v7.widget.AppCompatSeekBar;
      import android.util.AttributeSet;
      
      import java.text.DecimalFormat;
      
      public class DigitalThumbSeekbar extends AppCompatSeekBar {
      
          private Paint mTextPaint;
          private Paint mLinePaint;
          private RectF mRectF;
          private Paint mCirclePaint;
          private Paint mCirclePaint2;
      
          private Drawable mThumb;
      
      
          private float mMaxShowValue; //需要显示的最大值
          private int mPrecisionMode;//精度模式
          private int mViewWidth;
          private int mCenterX;
          private int mCenterY;
          private int mThumbHeight;
      
          public DigitalThumbSeekbar(Context context) {
              this(context, null);
          }
      
      
          public DigitalThumbSeekbar(Context context, AttributeSet attrs) {
              this(context, attrs, 0);
          }
      
          public DigitalThumbSeekbar(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
      
              TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DigitalThumbSeekbar);
              mMaxShowValue = typedArray.getFloat(R.styleable.DigitalThumbSeekbar_maxShowValue, getMax());//获取最大显示值
              mPrecisionMode = typedArray.getInt(R.styleable.DigitalThumbSeekbar_PrecisionMode, 0);//进度模式
              typedArray.recycle();//释放资源
      
              //设置滑块样式
              mThumb = context.getResources().getDrawable(R.drawable.circle_thumb);
              setThumb(mThumb);
              setThumbOffset(0);
              initPaint();//初始化画笔
          }
      
          private void initPaint() {
              //文字画笔
              mTextPaint = new Paint();
              mTextPaint.setARGB(255, 255, 255, 255);
              mTextPaint.setAntiAlias(true);
              mTextPaint.setTextSize(mThumb.getMinimumHeight() * 3 / 7);//文字大小为滑块高度的2/3
              mTextPaint.setTextAlign(Paint.Align.CENTER); // 设置文本对齐方式,居中对齐
      
              //进度画笔
              mLinePaint = new Paint();
              mLinePaint.setAntiAlias(true);
      
              //实心圆
              mCirclePaint = new Paint();
      //        mCirclePaint.setColor(0xFFFFFFFF);
              mCirclePaint.setARGB(255, 255, 65, 130);
              mCirclePaint.setAntiAlias(true);
              mCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
      //        mCirclePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
      
              //空心圆
              mCirclePaint2 = new Paint();
              mCirclePaint2.setARGB(255, 255, 255, 255);
              mCirclePaint2.setAntiAlias(true);
              mCirclePaint2.setStrokeWidth(mThumb.getMinimumHeight() / 20);
              mCirclePaint2.setStyle(Paint.Style.STROKE);
          }
      
          @Override
          protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      
             //父容器传过来的宽度的值
             mViewWidth = MeasureSpec.getSize(widthMeasureSpec) -getPaddingLeft() - getPaddingRight();
             //根据滑块的尺寸确定大小 布局文件中的android:layout_height="" 任何设置不会改变绘制的大小
             heightMeasureSpec = MeasureSpec.makeMeasureSpec(mThumb.getMinimumHeight(), MeasureSpec.EXACTLY);
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          }
      
          @Override
          protected void onDraw(Canvas canvas) {
              super.onDraw(canvas);
              //获取滑块坐标
              Rect thumbRect = getThumb().getBounds();
              mCenterX = thumbRect.centerX();//中心X坐标
              mCenterY = thumbRect.centerY(); //中心Y坐标
              mThumbHeight = thumbRect.height();//滑块高度
      
              //绘制进度条
              drawRect(canvas);
      
              //绘制滑块
              canvas.drawCircle(mCenterX, mCenterY, mThumbHeight / 2, mCirclePaint);
              canvas.drawCircle(mCenterX, mCenterY, mThumbHeight / 2 - mThumbHeight / 20, mCirclePaint2);//描边
      
              //绘制进度文字
              drawProgress(canvas);
          }
      
          /**
           * 绘制进度条
           * @param canvas
           */
          private void drawRect(Canvas canvas) {
              //绘制左边的进度
              mRectF = new RectF();
              mRectF.left = 0;
      //        mRectF.right = thumbRect.left;
              mRectF.right = mCenterX;
              mRectF.top = mCenterY - mThumbHeight / 4;
              mRectF.bottom = mCenterY + mThumbHeight / 4;
              mLinePaint.setColor(Color.GREEN);
              canvas.drawRoundRect(mRectF, mThumbHeight / 4, mThumbHeight / 4, mLinePaint);
      
              //绘制右边剩余的进度
              mRectF.left= mCenterX;
              mRectF.right = mViewWidth;
              mRectF.top = mCenterY - mThumbHeight / 15;
              mRectF.bottom = mCenterY + mThumbHeight / 15;
              mLinePaint.setARGB(255,255,65,130);
              canvas.drawRoundRect(mRectF, mThumbHeight / 15, mThumbHeight /15, mLinePaint);
          }
      
      
          /**
           * 绘制显示的进度文本
           * @param canvas
           */
          private void drawProgress(Canvas canvas) {
              String progress;
              float score = mMaxShowValue*getProgress()/getMax();
              switch (mPrecisionMode) {
                  case 1://小数点后一位
                      float  f1Score   =  (float)(Math.round(score*10))/10;
                      progress="" + f1Score;
                      break;
                  case 2://小数点后两位
                      DecimalFormat fnum  =   new DecimalFormat("##0.00");
                      progress=fnum.format(score);
                      break;
                  default://默认 整数模式
                      progress="" +(int)score;
                      break;
              }
              //测量文字高度
              Rect bounds = new Rect();
              mTextPaint.getTextBounds(progress, 0, progress.length(), bounds);
              int mTextHeight = bounds.height();//文字高度
      //      float mTextWidth = mTextPaint.measureText(progress);
              canvas.drawText(progress, mCenterX, mCenterY + mTextHeight / 2, mTextPaint);
          }
      
      }
    

四、包装

刻度盘显示在PopupWindow中,当触摸Seekbar显示PopupWindow并且使得sin函数开始运动,通过进度值去控制进度盘的指示位置和水的深度以及颜色ARGB值,所以整个对刻度盘的控制都包装在Seekbar 的监听器里面:

    package com.hubin.scaleseekbar;
    
    /*
     *  @项目名:  ScaleSeekBar 
     *  @包名:    com.hubin.scaleseekbar
     *  @文件名:   WaveDialSeekbarListener
     *  @创建者:   胡英姿
     *  @创建时间:  2018-03-09 16:26
     *  @描述:    一个将SoftDialView 包装在里面的seekbar监听器
     */
    
    import android.graphics.Color;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.PopupWindow;
    import android.widget.SeekBar;
    
    import java.lang.ref.WeakReference;
    
    public class WaveDialSeekbarListener implements SeekBar.OnSeekBarChangeListener {
        private static final String TAG = "WaveDialSeekbarListener";
        private WeakReference<MainActivity> mActivityWeakReference;  //activity的弱应用
        private WaveDialView mWaveDialView;
        private PopupWindow mPopupWindow;
        private int mMaxProgress; //最大进度值
        private float mMaxShowValue; //最大显示值
        private String textUnit = ""; //右上角文字 单位
        private String textName = "";//中间要显示的文字名字
    
        private int precisionModeDefuale;//精度模式
        /**
         * 构造函数
         * @param activity activity的引用
         * @param maxProgress seekbar 的最大进度值
         * @param maxShowValue 刻度盘上需要显示的最大值
         * @param textName  中间要显示的文字名字
         * @param textUnit  右上角文字 单位
         * @param precisionModeDefuale 精度模式  整数,1位小数,2位小数
         */
        public WaveDialSeekbarListener(MainActivity activity, int maxProgress, float maxShowValue, String textName, String textUnit, int precisionModeDefuale) {
            mActivityWeakReference = new WeakReference(activity);
            mMaxProgress= maxProgress;
            mMaxShowValue = maxShowValue;
            this.textName = textName;
            this.textUnit = textUnit;
            this.precisionModeDefuale = precisionModeDefuale;
        }
    
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
          if (mWaveDialView != null) {
            mWaveDialView.setChange((float) progress*300/mMaxProgress);
            }
        }
    
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mWaveDialView = new WaveDialView(mActivityWeakReference.get());
            mWaveDialView.setInitConfig(precisionModeDefuale,mMaxShowValue,textName,textUnit);
            mWaveDialView.moveWaterLine();
            mWaveDialView.setOnAngleColorListener(onAngleColorListener);//颜色监听器 可自行设置
            //窗口宽度
            int windowWidth = mActivityWeakReference.get().getWindowManager().getDefaultDisplay().getWidth();
    
            mPopupWindow = new PopupWindow(mWaveDialView, windowWidth/2, ViewGroup
                    .LayoutParams.WRAP_CONTENT, true);
            mPopupWindow.showAtLocation(View.inflate(mActivityWeakReference.get(),R.layout.activity_main, null),
                    Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);    //显示位置
        }
    
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mWaveDialView=null;
            mPopupWindow.dismiss();
        }
    
    
    
        private WaveDialView.OnAngleColorListener onAngleColorListener=new WaveDialView.OnAngleColorListener() {
            @Override
            public void onAngleColorListener(int red, int green) {
                int c=Color.argb(150, red, green, 0);
               mActivityWeakReference.get().setBgColor(c);
            }
        };
    }

五、项目下载(记得Star)

https://github.com/CNHubin/ScaleSeekBar

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345