android开发:FM刻度尺自定义view

效果:
android开发:FM刻度尺自定义view_第1张图片

公司最近接了个傻屌项目,写个app控制广场舞音箱,我也是醉了。需要使用到刻度尺去换FM台,自己对自定义view研究又不是很多,只要会找会改实现自己想要的就行。然后自己网上参考了这位老哥的博客:Android 自定义View:实现一个 FM 刻度尺,在它上面修改了一下实现自己的需求:

代码:

package com.skyworth.car.rulerdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class RulerView extends View {
     
    public static final int MIN_POSITION = 20;//起始位置
    public static final int MAX_POSITION = 1700;//结束位置
    private OnMoveActionListener mMove = null;

    private Paint mLinePaint;//刻度线画笔
    private Paint mTextPaint;//指示数字画笔
    private Paint mRulerPaint;//指示线画笔

    private float position = 20;
    private int max = 1080;//FM频道最大值108*10
    private int min = 870;//FM频道最小值87*10
    private int  scale = 900;

    public RulerView(Context context) {
     
        super(context);
        init();
    }

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

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

    private void init() {
     
        mLinePaint = new Paint();
        mLinePaint.setColor(getResources().getColor(R.color.grey));
        //抗锯齿
        mLinePaint.setAntiAlias(true);
        mLinePaint.setStyle(Paint.Style.STROKE);
        mLinePaint.setStrokeWidth(5);


        mTextPaint = new Paint();
        mTextPaint.setColor(getResources().getColor(R.color.grey));
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setStrokeWidth(2);
        mTextPaint.setTextSize(30);

        mRulerPaint = new Paint();
        mRulerPaint.setAntiAlias(true);
        mRulerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mRulerPaint.setColor(getResources().getColor(R.color.white));
        mRulerPaint.setStrokeWidth(3);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(setMeasureWidth(widthMeasureSpec), setMeasureHeight(heightMeasureSpec));
    }

    private int setMeasureHeight(int spec) {
     
        int mode = MeasureSpec.getMode(spec);
        int size = MeasureSpec.getSize(spec);
        int result = Integer.MAX_VALUE;
        switch (mode) {
     
            case MeasureSpec.AT_MOST:
                size = Math.min(result, size);
                break;
            case MeasureSpec.EXACTLY:
                break;
            default:
                size = result;
                break;
        }
        return size;
    }

    private int setMeasureWidth(int spec) {
     
        int mode = MeasureSpec.getMode(spec);
        int size = MeasureSpec.getSize(spec);
        int result = Integer.MAX_VALUE;
        switch (mode) {
     
            case MeasureSpec.AT_MOST:
                size = Math.min(result, size);
                break;
            case MeasureSpec.EXACTLY:
                break;
            default:
                size = result;
                break;
        }
        return size;
    }

    @Override
    protected void onDraw(Canvas canvas) {
     
        super.onDraw(canvas);
        canvas.save();
        //绘制刻度线
        for (int i = min; i <= max; i++) {
     
            //900、950、1000符合条件
            if ((i - scale) % 50 == 0) {
     
                //绘制直线
                canvas.drawLine(20, 20, 20, 220, mLinePaint);
                String text = i / 10 + "";
                Rect rect = new Rect();
                float txtWidth = mTextPaint.measureText(text);
                mTextPaint.getTextBounds(text, 0, text.length(), rect);
                canvas.drawText(text, 20 - txtWidth / 2, 150 + rect.height() + 80, mTextPaint);
            } else if ((i - scale) % 10 == 0) {
     
                canvas.drawLine(20, 60, 20, 180, mLinePaint);
            } else if ((i - scale) % 2 == 0) {
     
                canvas.drawLine(20, 100, 20, 160, mLinePaint);
            }
            //刻度尺密度
            canvas.translate((float) 5, 0);
        }
        canvas.restore();
        drawLine(canvas);
        mTextPaint.setTextSize(30);
    }

    public void drawLine(Canvas canvas){
     
        //绘制指示线
        canvas.drawRect(position - 10, 100, position + 10, 160, mRulerPaint);
        canvas.drawLine(position, 20, position, 240, mRulerPaint);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
     
        switch (event.getAction()) {
     
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                if (x < MIN_POSITION) {
     
                    setPosition(MIN_POSITION);
                } else if (x > MAX_POSITION) {
     
                    setPosition(MAX_POSITION);
                } else {
     
                    setPosition((int) x);
                }
                //移动指示条
                if (mMove != null) {
     
                    mMove.onMove(Double.parseDouble(String.format("%.1f", getFmChannel())));
                }
                Log.d("TAG", "position:" + position);
                Log.d("TAG", "channel:" + getFmChannel());
            case MotionEvent.ACTION_CANCEL:
                //只停在0.1(刻度线上)的位置
               // setFmChanel(Double.parseDouble(String.format("%.1f", getFmChannel())));
                Log.d("停下来后", "channel:" + Double.parseDouble(String.format("%.1f", getFmChannel())));
                break;
            default:
        }
        return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
     
        //解决刻度尺和viewPager的滑动冲突
        //当滑动刻度尺时,告知父控件不要拦截事件,交给子view处理
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.dispatchTouchEvent(ev);
    }

    public void setPosition(int i) {
     
        position = i;
        //刷新布局,不需要重绘
        requestLayout();

    }

    public void setFmChanel(double fmChanel) {
     
        int temp = (int) ((fmChanel - 90) * 80) + 20;
        setPosition(temp);
    }

    public double getFmChannel() {
     
        return ((position - 20.0) / 50.0 + 87);
    }

    /**
     * 定义监听接口
     */
    public interface OnMoveActionListener {
     
        void onMove(double x);
    }

    /**
     * 为每个接口设置监听器
     */
    public void setOnMoveActionListener(OnMoveActionListener move) {
     
        mMove = move;
    }

}

你可能感兴趣的:(android,view)