首先这段代码是网上有的不过我进行了修改

package com.sfqj.view;  
   




import com.sfqj.yingsu.R;


import android.annotation.SuppressLint;  
import android.content.Context;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.Paint;  
import android.graphics.drawable.Drawable;  
import android.graphics.drawable.GradientDrawable;  
import android.text.Layout;  
import android.text.TextPaint;  
import android.util.AttributeSet;  
import android.view.MotionEvent;  
import android.view.VelocityTracker;  
import android.view.View;  
import android.view.ViewConfiguration;  
import android.widget.Scroller;  
   
  
   
/** 
 *  
 * @author SunXinxin 
 * @version create:2015年9月17日 
 */ 
@SuppressLint("ClickableViewAccessibility")  
public class RuleView extends View {  
   
    public interface OnValueChangeListener {  
        public void onValueChange(float value);  
    }  
   
    public static final int MOD_TYPE_HALF = 2;  
    public static final int MOD_TYPE_ONE = 36;  
   
    private static final int ITEM_HALF_DIVIDER = 1;  
    private static final int ITEM_ONE_DIVIDER = 1;  
   
    private static final int ITEM_MAX_HEIGHT = 25;  
    private static final int ITEM_MIN_HEIGHT = 10;  
   
    private static final int TEXT_SIZE = 14;  
   
    private float mDensity;  
    public int mValue = 1, mMaxValue = 864, mModType = MOD_TYPE_ONE, mLineDivider = ITEM_HALF_DIVIDER;  //当然这里的值是最重要的我们这里需要精确到秒,不过我写的精确到分,至于秒那就随机数生成凑个效果,误差也不是很大,想读懂源码主要是这些参数的需要理解。我简单的凑了一下并没有深度研究。
    // private int mValue = 50, mMaxValue = 500, mModType = MOD_TYPE_ONE,  
    // mLineDivider = ITEM_ONE_DIVIDER;  
   
    private int mLastX, mMove;  
    private int mWidth, mHeight;  
   
    private int mMinVelocity;  
    private Scroller mScroller;  
    private VelocityTracker mVelocityTracker;  
   
    private OnValueChangeListener mListener;  
   
    @SuppressWarnings("deprecation")  
    public RuleView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
   
        mScroller = new Scroller(getContext());  
        mDensity = getContext().getResources().getDisplayMetrics().density;  
   
        mMinVelocity = ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();  
   
        // setBackgroundResource(R.drawable.bg_wheel);  
        setBackgroundDrawable(createBackground());  
    }  
   
    private GradientDrawable createBackground() {  
        float strokeWidth = 4 * mDensity; // 边框宽度  
        float roundRadius = 6 * mDensity; // 圆角半径  
        int strokeColor = Color.parseColor("#FF666666");// 边框颜色  
        // int fillColor = Color.parseColor("#DFDFE0");// 内部填充颜色  
           
        setPadding((int)strokeWidth, (int)strokeWidth, (int)strokeWidth, 0);  
   
        int colors[] = { 0xFF999999, 0xFFFFFFFF, 0xFF999999 };// 分别为开始颜色,中间夜色,结束颜色  
        GradientDrawable bgDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);// 创建drawable  
        // bgDrawable.setColor(fillColor);  
        bgDrawable.setCornerRadius(roundRadius);  
        bgDrawable.setStroke((int)strokeWidth, strokeColor);  
        // setBackgroundDrawable(gd);  
        return bgDrawable;  
    }  
   
    /** 
     *  
     * 考虑可扩展,但是时间紧迫,只可以支持两种类型效果图中两种类型 
     *  
     * @param value 
     *            初始值 
     * @param maxValue 
     *            最大值 
     * @param model 
     *            刻度盘精度:
 
     *            {@link MOD_TYPE_HALF}
 
     *            {@link MOD_TYPE_ONE}
 
     */ 
    public void initViewParam(int defaultValue, int maxValue, int model) {  
        switch (model) {  
        case MOD_TYPE_HALF:  
            mModType = MOD_TYPE_HALF;  
            mLineDivider = ITEM_HALF_DIVIDER;  
            mValue = defaultValue * 2;  
            mMaxValue = maxValue * 2;  
            break;  
        case MOD_TYPE_ONE:  
            mModType = MOD_TYPE_ONE;  
            mLineDivider = ITEM_ONE_DIVIDER;  
            mValue = defaultValue;  
            mMaxValue = maxValue;  
            break;  
   
        default:  
            break;  
        }  
        invalidate();  
   
        mLastX = 0;  
        mMove = 0;  
        notifyValueChange();  
    }  
   
    /** 
     * 设置用于接收结果的监听器 
     *  
     * @param listener 
     */ 
    public void setValueChangeListener(OnValueChangeListener listener) {  
        mListener = listener;  
    }  
   
    /** 
     * 获取当前刻度值 
     *  
     * @return 
     */ 
    public float getValue() {  
        return mValue;  
    }  
   
    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  
        mWidth = getWidth();  
        mHeight = getHeight();  
        super.onLayout(changed, left, top, right, bottom);  
    }  
   
    @Override 
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
   
        drawScaleLine(canvas);  
        // drawWheel(canvas);  
        drawMiddleLine(canvas);  
    }  
   
    private void drawWheel(Canvas canvas) {  
        Drawable wheel = getResources().getDrawable(R.drawable.ic_launcher);  
        wheel.setBounds(0, 0, getWidth(), getHeight());  
        wheel.draw(canvas);  
    }  
   
    /** 
     * 从中间往两边开始画刻度线 
     *  
     * @param canvas 
     */ 
    private void drawScaleLine(Canvas canvas) {  
        canvas.save();  
   
        Paint linePaint = new Paint();  
        linePaint.setStrokeWidth(2);  
        linePaint.setColor(Color.BLACK);  
   
        TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);  
        textPaint.setTextSize(TEXT_SIZE * mDensity);  
   
        int width = mWidth, drawCount = 0;  
        float xPosition = 0, textWidth = Layout.getDesiredWidth("0", textPaint);  
   
        for (int i = 0; drawCount <= 4 * width; i++) {  
            int numSize = String.valueOf(mValue + i).length();  
   
            xPosition = (width / 2 - mMove) + i * mLineDivider * mDensity;  
            if (xPosition + getPaddingRight() < mWidth) {  
                if ((mValue + i) % mModType == 0) {  
                    canvas.drawLine(xPosition, getPaddingTop(), xPosition, mDensity * ITEM_MAX_HEIGHT, linePaint);  
   
                    if (mValue + i <= mMaxValue) {  
                        switch (mModType) {  
                        case MOD_TYPE_HALF:  
                            canvas.drawText(String.valueOf((mValue + i) / 2), countLeftStart(mValue + i, xPosition, textWidth), getHeight() - textWidth, textPaint);  
                            break;  
                        case MOD_TYPE_ONE:  
                            canvas.drawText(String.valueOf((mValue + i)/36), xPosition - (textWidth * numSize / 2), getHeight() - textWidth, textPaint);  
                            break;  
   
                        default:  
                            break;  
                        }  
                    }  
                } else {  
                    canvas.drawLine(xPosition, getPaddingTop(), xPosition, mDensity * ITEM_MIN_HEIGHT, linePaint);  
                }  
            }  
   
            xPosition = (width / 2 - mMove) - i * mLineDivider * mDensity;  
            if (xPosition > getPaddingLeft()) {  
                if ((mValue - i) % mModType == 0) {  
                    canvas.drawLine(xPosition, getPaddingTop(), xPosition, mDensity * ITEM_MAX_HEIGHT, linePaint);  
   
                    if (mValue - i >= 0) {  
                        switch (mModType) {  
                        case MOD_TYPE_HALF:  
                            canvas.drawText(String.valueOf((mValue - i) / 2), countLeftStart(mValue - i, xPosition, textWidth), getHeight() - textWidth, textPaint);  
                            break;  
                        case MOD_TYPE_ONE:  
                            canvas.drawText(String.valueOf((mValue - i)/36), xPosition - (textWidth * numSize / 2), getHeight() - textWidth, textPaint);  
                            break;  
   
                        default:  
                            break;  
                        }  
                    }  
                } else {  
                    canvas.drawLine(xPosition, getPaddingTop(), xPosition, mDensity * ITEM_MIN_HEIGHT, linePaint);  
                }  
            }  
   
            drawCount += 2 * mLineDivider * mDensity;  
        }  
   
        canvas.restore();  
    }  
   
    /** 
     * 计算没有数字显示位置的辅助方法 
     *  
     * @param value 
     * @param xPosition 
     * @param textWidth 
     * @return 
     */ 
    private float countLeftStart(int value, float xPosition, float textWidth) {  
        float xp = 0f;  
        if (value < 20) {  
            xp = xPosition - (textWidth * 1 / 2);  
        } else {  
            xp = xPosition - (textWidth * 2 / 2);  
        }  
        return xp;  
    }  
   
    /** 
     * 画中间的红色指示线、阴影等。指示线两端简单的用了两个矩形代替 
     *  
     * @param canvas 
     */ 
    private void drawMiddleLine(Canvas canvas) {  
        // TOOD 常量太多,暂时放这,最终会放在类的开始,放远了怕很快忘记  
        int gap = 1, indexWidth = 5, indexTitleWidth = 10, indexTitleHight = 5, shadow = 3;  
        String color = "#66999999";  
   
        canvas.save();  
   
        Paint redPaint = new Paint();  
        redPaint.setStrokeWidth(indexWidth);  
        redPaint.setColor(Color.RED);  
        canvas.drawLine(mWidth / 2, 0, mWidth / 2, mHeight, redPaint);  
   
        Paint ovalPaint = new Paint();  
        ovalPaint.setColor(Color.RED);  
        ovalPaint.setStrokeWidth(indexTitleWidth);  
        canvas.drawLine(mWidth / 2, 0, mWidth / 2, indexTitleHight, ovalPaint);  
        canvas.drawLine(mWidth / 2, mHeight - indexTitleHight, mWidth / 2, mHeight, ovalPaint);  
   
        // RectF ovalRectF = new RectF(mWidth / 2 - 10, 0, mWidth / 2 + 10, 4 *  
        // mDensity); //TODO 椭圆  
        // canvas.drawOval(ovalRectF, ovalPaint);  
        // ovalRectF.set(mWidth / 2 - 10, mHeight - 8 * mDensity, mWidth / 2 +  
        // 10, mHeight); //TODO  
   
        Paint shadowPaint = new Paint();  
        shadowPaint.setStrokeWidth(shadow);  
        shadowPaint.setColor(Color.parseColor(color));  
        canvas.drawLine(mWidth / 2 + gap, 0, mWidth / 2 + gap, mHeight, shadowPaint);  
   
        canvas.restore();  
    }  
   
    @Override 
    public boolean onTouchEvent(MotionEvent event) {  
        int action = event.getAction();  
        int xPosition = (int) event.getX();  
   
        if (mVelocityTracker == null) {  
            mVelocityTracker = VelocityTracker.obtain();  
        }  
        mVelocityTracker.addMovement(event);  
   
        switch (action) {  
        case MotionEvent.ACTION_DOWN:  
   
            mScroller.forceFinished(true);  
   
            mLastX = xPosition;  
            mMove = 0;  
            break;  
        case MotionEvent.ACTION_MOVE:  
            mMove += (mLastX - xPosition);  
            changeMoveAndValue();  
            break;  
        case MotionEvent.ACTION_UP:  
        case MotionEvent.ACTION_CANCEL:  
            countMoveEnd();  
            countVelocityTracker(event);  
            return false;  
            // break;  
        default:  
            break;  
        }  
   
        mLastX = xPosition;  
        return true;  
    }  
   
    private void countVelocityTracker(MotionEvent event) {  
        mVelocityTracker.computeCurrentVelocity(1000);  
        float xVelocity = mVelocityTracker.getXVelocity();  
        if (Math.abs(xVelocity) > mMinVelocity) {  
            mScroller.fling(0, 0, (int) xVelocity, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);  
        }  
    }  
   
    private void changeMoveAndValue() {  
        int tValue = (int) (mMove / (mLineDivider * mDensity));  
        if (Math.abs(tValue) > 0) {  
            mValue += tValue;  
            mMove -= tValue * mLineDivider * mDensity;  
            if (mValue <= 0 || mValue > mMaxValue) {  
                mValue = mValue <= 0 ? 0 : mMaxValue;  
                mMove = 0;  
                mScroller.forceFinished(true);  
            }  
            notifyValueChange();  
        }  
        postInvalidate();  
    }  
   
    private void countMoveEnd() {  
        int roundMove = Math.round(mMove / (mLineDivider * mDensity));  
        mValue = mValue + roundMove;  
        mValue = mValue <= 0 ? 0 : mValue;  
        mValue = mValue > mMaxValue ? mMaxValue : mValue;  
   
        mLastX = 0;  
        mMove = 0;  
   
        notifyValueChange();  
        postInvalidate();  
    }  
   
    private void notifyValueChange() {  
        if (null != mListener) {  
            if (mModType == MOD_TYPE_ONE) {  
                mListener.onValueChange(mValue);  
            }  
            if (mModType == MOD_TYPE_HALF) {  
                mListener.onValueChange(mValue / 2f);  
            }  
        }  
    }  
   
    @Override 
    public void computeScroll() {  
        super.computeScroll();  
        if (mScroller.computeScrollOffset()) {  
            if (mScroller.getCurrX() == mScroller.getFinalX()) { // over  
                countMoveEnd();  
            } else {  
                int xPosition = mScroller.getCurrX();  
                mMove += (mLastX - xPosition);  
                changeMoveAndValue();  
                mLastX = xPosition;  
            }  
        }  
    }  
}

更多相关文章

  1. android 颜色16进制对应的xml配置值(工具参考)
  2. android只title背景色随着滚动渐变颜色
  3. Android(安卓)5.0新控件 FloatingActionButton | 悬浮按钮 介绍
  4. Android(安卓)修改App中默认TextView的字体和颜色
  5. Android中OptionMenu的使用
  6. Android(安卓)SeekBar
  7. Android(安卓)给TextView的内容 添加跳转无下划线
  8. Android(安卓)实现不同字体颜色的TextView实现代码
  9. Android中OptionMenu的使用

随机推荐

  1. MySQL如何快速导入数据
  2. MySQL备份脚本的写法
  3. 5个MySQL GUI工具推荐,帮助你进行数据库管
  4. mysql查看用户授权信息的具体方法
  5. 如何清除mysql注册表
  6. Mysql 命令行模式访问操作mysql数据库操
  7. 解析MySQL8.0新特性——事务性数据字典与
  8. Mysql| 使用通配符进行模糊查询详解(like
  9. MYSQL SERVER收缩日志文件实现方法
  10. MySQL中常见的几种日志汇总