Android 自定义刻度尺

Android 自定义View

正好趁着放假做一次总结,关于最近用到的自定义刻度尺。

  1. 效果图


    图片.png
  2. 首先继承一下View构建三个方法。实现这个图片的具体思路,首先要控制控件的大小,那就是要用到onMeasure()方法,然后onDraw()方法也不用说,再多一个方法就是重写onTouchEvent()方法。

  3. onMeasure()方法重写

      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int specMode = MeasureSpec.getMode(widthMeasureSpec);
            int specSize = MeasureSpec.getSize(widthMeasureSpec);
            HEIGHT = MeasureSpec.getSize(heightMeasureSpec);
            switch (specMode) {
                //未指定大小
                case MeasureSpec.UNSPECIFIED:
                     WIDTH = 500;
                    break;
                    //wrap_content
                case MeasureSpec.AT_MOST:
                     //match_parent
                case MeasureSpec.EXACTLY:
                     WIDTH = specSize;
                     break;
               default:
                   break;
       }
     //设置View的大小
     setMeasuredDimension(WIDTH,HEIGHT);
    }
    

这里其实应该写的规范一点,将宽高写成单独的处理方法,因为想写的明了些就直接塞到一起了,不绕弯子了。上面的意思就是宽没指定就按照500来,这个500算是给的一个默认值。这样我们就可以把一个View的大小给整出来。

  1. onDraw()方法重写

     @Override
      protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //这里减去20是为了有个padding效果,左右空出一点  SIZE 就是自己要分成的多少块,自己设置。
        spacing = (WIDTH-20) / SIZE ;
       //画线段出刻度尺
       for(int i = 0;i

    }

  2. 就是onTouchEvent()方法了 思路就是获取当前的响应事件,根据偏移量进行操作。

       @Override
       public boolean onTouchEvent(MotionEvent event) {
        //判断动作
         int  action = event.getAction();
        //获取当前的x坐标
         float x = event.getX();
        //屏蔽外界的点
         if(x<10 ||x>WIDTH-20){
             return true;
         }
         switch (action){
             case MotionEvent.ACTION_DOWN:
               progress = x;
       
              invalidate();
              break;
           case MotionEvent.ACTION_MOVE:
        
             progress = event.getX();
             //刷新
              invalidate();
              break;
              case MotionEvent.ACTION_CANCEL:
              case MotionEvent.ACTION_UP:
                  progress = event.getX();
                  handleProgress();
                  break;
     }
              return true;
    
     }
    
  3. 所有代码:

 public class TunerView extends View {

   String TAG  = "TunerView";
    //控件宽度
   int WIDTH ;
   //控件长度
   int HEIGHT ;
   //刻度间隔
   int spacing;
  //分成12段
   int SIZE = 12 ;
  
  //默认开始位置
  float progress = 10;

   private Paint paint;
   private Paint mPaint;
   private Paint textPaint;

   public TunerView(Context context) {
    super(context);
    Log.d(TAG, "TunerView: ");
    init(context);
}

public TunerView(Context context,  AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public TunerView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int specMode = MeasureSpec.getMode(widthMeasureSpec);
    int specSize = MeasureSpec.getSize(widthMeasureSpec);
    HEIGHT = MeasureSpec.getSize(heightMeasureSpec);
    switch (specMode) {
            //未指定大小
            case MeasureSpec.UNSPECIFIED:
                 WIDTH = 500;
                 break;
                 //wrap_content
            case MeasureSpec.AT_MOST:
                 //match_parent
            case MeasureSpec.EXACTLY:
                  WIDTH = specSize;
                  break;
            default:
                break;
    }

    setMeasuredDimension(WIDTH,HEIGHT);
}

@Override
protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);
    spacing = (WIDTH-20) / SIZE ;

    for(int i = 0;iWIDTH-20){
        return true;
    }
    switch (action){
        case MotionEvent.ACTION_DOWN:
             progress = x;
           //  isCanMove= true ;
             invalidate();
             break;
        case MotionEvent.ACTION_MOVE:


            progress = event.getX();

            //刷新
             invalidate();
             break;
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                 progress = event.getX();
                 handleProgress();
                 break;
    }
             return true;

}

private void handleProgress(){
    int i = 0 ;
    float index = progress ;

    for(int j = 0;j
  1. 后记,加上了吸附效果,就是1.4给自己移动到1.0 1.5 移动到2这个样子。没什么特别的简单处理一下逻辑就行。

update 2019/5/4
在onMove事件中加上此方法,防止与父控件进行滑动冲突(比如scorll嵌套这个View)

   private void attemptClaimDrag() {
      if (getParent() != null) {
          getParent().requestDisallowInterceptTouchEvent(true);
      }
   }

你可能感兴趣的:(Android 自定义刻度尺)