一直都想实现一个自己的 WheelView ,现在处在找工作期间 ,就做了一个。还很丑,功能还很简单,持续更新吧,也算给自己挖个坑。
自定义的的属性就不贴了
代码如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 | package com.yangxbfuj.pathologicalalarm.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import com.yangxbfuj.pathologicalalarm.Logger;import com.yangxbfuj.pathologicalalarm.R;import java.util.ArrayList;import java.util.List; * Created by yangxb on 2017/3/2. */public class extends View { private static final String TAG = "WheelView"; private static final int SRCOLL_STATUS_IDLE = 0; private static final int SRCOLL_STATUS_DRAGGING = 1; private static final int SRCOLL_STATUS_SCROLLING = 2; private static final int DEFAULT_LINE_NUM = 5; private int mLineNum; // unit dp private static final int DEFALUT_LINE_HEIGHT = 10; private int mLineHeight; // unit sp private static final int TEXT_SIZE = 10; private int mTextSize; private static final boolean DEFAULT_EYCLE = true; private boolean mCycle; private static final int DEFAULT_COLOR = 0; private int mTextColor; private static final int DEFAULT_BOX_COLOR = 0; private int mBoxColor; private String[] mContentArray; private Paint mTextPaint; private Paint mBoxPaint; public void setContentArray(String[] contentArray) { mContentArray = contentArray; } // 当前滚动导致的位移,往上移动为正 private int mScrollOffset = 0; * 设置显示的范围,如果方程 start + n * gap = end 的解 n 不为整数,则舍弃 end 值 , * 最后将取 end 值之前第一个匹配参数的值。 * * @param start 开始数字 * @param end 结束数字 * @param gap 数字间隙 */ public void setRange(int start, int end, int gap) { if (gap == 0) { throw new IllegalArgumentException("gap == 0 error,gap should not be 0"); } else if ((start - end) * gap > 0) { throw new IllegalArgumentException("(start - end) * gap <0 error"); } List<String> range = new ArrayList<>(); range.add(String.valueOf(start)); int newValue = start; while (true) { newValue += gap; if (gap > 0 && newValue - end > 0) { break; } else if (gap < 0 && newValue - end < 0) { break; } else { range.add(String.valueOf(newValue)); } } mContentArray = new String[range.size()]; for (int i = 0; i < range.size(); i++) { mContentArray[i] = range.get(i); } } public (Context context) { super(context); } public (Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WheelView); mLineNum = a.getInt(R.styleable.WheelView_line_num, DEFAULT_LINE_NUM); mLineHeight = a.getDimensionPixelSize(R.styleable.WheelView_line_height, DEFALUT_LINE_HEIGHT); mTextSize = a.getDimensionPixelSize(R.styleable.WheelView_line_height, DEFALUT_LINE_HEIGHT); mCycle = a.getBoolean(R.styleable.WheelView_cycle, DEFAULT_EYCLE); mTextColor = a.getColor(R.styleable.WheelView_textColor, DEFAULT_COLOR); mBoxColor = a.getColor(R.styleable.WheelView_current_choose_box_color, DEFAULT_BOX_COLOR); a.recycle(); if (mLineNum % 2 == 0) { throw new IllegalArgumentException("line num should not be even number"); } // init Paints mTextPaint = new Paint(); mTextPaint.setColor(mTextColor); mTextPaint.setTextSize(mTextSize); mBoxPaint = new Paint(); mBoxPaint.setColor(mBoxColor); } public (Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private float mLastY; public boolean onTouchEvent(MotionEvent event) { Logger.d(TAG,"onTouchEvent " + event.getAction()); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: mLastY = event.getY(); break; case MotionEvent.ACTION_MOVE: float currentY = event.getY(); mScrollOffset = (int) (mScrollOffset - (currentY - mLastY)); if(mScrollOffset < 0){ mScrollOffset += mContentArray.length * mLineHeight; }else { mScrollOffset %= mContentArray.length * mLineHeight; } mLastY = currentY; invalidate(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: break; } return true; } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = mLineHeight * mLineNum; setMeasuredDimension(widthMeasureSpec, height); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawText(canvas); drawBox(canvas); } private void drawText(Canvas canvas) { int startTop = -mLineNum / 2 * mLineHeight; int startBottom = (mLineNum / 2 + 1) * mLineHeight; int currentTop = startTop + mScrollOffset; int currentBottom = startBottom + mScrollOffset; int indexTop = currentTop / mLineHeight; int indexBottom = currentBottom / mLineHeight; for (int i = indexTop; i <= indexBottom; i++) { Rect textRect = new Rect(); String str = mContentArray[(i + mContentArray.length) % mContentArray.length]; mTextPaint.getTextBounds(str, 0, str.length(), textRect); int top = -mScrollOffset % mLineHeight + (i - indexTop) * mLineHeight; canvas.drawText(str, getWidth() / 2 - textRect.width() / 2, top + textRect.height() / 2 + mLineHeight / 2, mTextPaint); } } private void drawBox(Canvas canvas) { int boxLineHeight = 4; // 绘制上线 canvas.drawLine(getPaddingLeft(), mLineHeight * (mLineNum / 2) - boxLineHeight / 2 , getWidth() - getPaddingRight(), mLineHeight * (mLineNum / 2) + boxLineHeight / 2 , mBoxPaint); // 绘制下线 canvas.drawLine(getPaddingLeft(), mLineHeight * (mLineNum / 2 + 1) - boxLineHeight / 2 , getWidth() - getPaddingRight(), mLineHeight * (mLineNum / 2 + 1) + boxLineHeight / 2 , mBoxPaint); }} |