android 自定义View 滚动选择器PickerView_第1张图片

1:自定义View

package com.arch.datetimepicker;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;public class PickerView extends View {    public static final String TAG = "PickerView";    /**     * Text spacing and minTextSize ratio     */    //public static final float MARGIN_ALPHA = 2.0f;    /**     * Automatic rollback to intermediate speed     */    public static final float SPEED = 20;    private List mDataList;    /**     * Selected location, this position is the center of mDataList, has been unchanged     */    private int mCurrentSelected;    private Paint mPaint;    private float mMaxTextSize = 15;    private float mMinTextSize = 10;    private float mMaxTextAlpha = 255;    private float mMinTextAlpha = 255;    private int mColorText = 0x333333;    private int mViewHeight;    private int mViewWidth;    private float mLastDownY;    private int textSizeUp ;    private int textSizeDown;    private float MARGIN_ALPHA;    /**     * Sliding distance     */    private float mMoveLen = 0;    private boolean isInit = false;    private onSelectListener mSelectListener;    private Timer timer;    private MyTimerTask mTask;    Handler updateHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (Math.abs(mMoveLen) < SPEED) {                mMoveLen = 0;                if (mTask != null) {                    mTask.cancel();                    mTask = null;                    performSelect();                }            } else                // Here mMoveLen / Math.abs (mMoveLen) is to maintain the mMoveLen positive and negative numbers, in order to achieve roll or roll                mMoveLen = mMoveLen - mMoveLen / Math.abs(mMoveLen) * SPEED;            invalidate();        }    };    public void setPaintTextSizeDivide(int upSize ,int downSize,float divide){        textSizeUp = upSize;        textSizeDown = downSize;        MARGIN_ALPHA = divide;    }    public PickerView(Context context) {        super(context);        init();    }    public PickerView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public void setOnSelectListener(onSelectListener listener) {        mSelectListener = listener;    }    private void performSelect() {        if (mSelectListener != null)            mSelectListener.onSelect(mDataList.get(mCurrentSelected));    }    public void setData(List datas) {        mDataList = datas;        mCurrentSelected = datas.size() / 2;        invalidate();    }    /**     * Select the selected item index     *     * @param selected     */    public void setSelected(int selected) {        mCurrentSelected = selected;        int distance = mDataList.size() / 2 - mCurrentSelected;        if (distance < 0)            for (int i = 0; i < -distance; i++) {                moveHeadToTail();                mCurrentSelected--;            }        else if (distance > 0)            for (int i = 0; i < distance; i++) {                moveTailToHead();                mCurrentSelected++;            }        invalidate();    }    /**     * Select selected content     *     * @param mSelectItem     */    public void setSelected(String mSelectItem) {        for (int i = 0; i < mDataList.size(); i++)            if (mDataList.get(i).equals(mSelectItem)) {                setSelected(i);                break;            }    }    private void moveHeadToTail() {        String head = mDataList.get(0);        mDataList.remove(0);        mDataList.add(head);    }    private void moveTailToHead() {        String tail = mDataList.get(mDataList.size() - 1);        mDataList.remove(mDataList.size() - 1);        mDataList.add(0, tail);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mViewHeight = getMeasuredHeight();        mViewWidth = getMeasuredWidth();        // Font size according to View height        mMaxTextSize = mViewHeight / 4.0f;        mMinTextSize = mMaxTextSize / 2f;        isInit = true;        invalidate();    }    private void init() {        timer = new Timer();        mDataList = new ArrayList();        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setTextAlign(Paint.Align.CENTER);        mPaint.setColor(mColorText);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // draw view according index        if (isInit)            drawData(canvas);    }    private void drawData(Canvas canvas) {        // First draw the selected text and then draw up the rest of the text        float scale = parabola(mViewHeight / 4.0f, mMoveLen);        float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;        mPaint.setTextSize(textSizeUp);        mPaint.setColor(0xffea9566);        mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));        // Text center draw, pay attention to the calculation of baseline to achieve the center, y value is text center coordinates        float x = (float) (mViewWidth / 2.0);        float y = (float) (mViewHeight / 2.0 + mMoveLen);        Paint.FontMetricsInt fmi = mPaint.getFontMetricsInt();        float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));        canvas.drawText(mDataList.get(mCurrentSelected), x, baseline, mPaint);        // Draw top data        for (int i = 1; (mCurrentSelected - i) >= 0; i++) {            drawOtherText(canvas, i, -1);        }        // Draw below data        for (int i = 1; (mCurrentSelected + i) < mDataList.size(); i++) {            drawOtherText(canvas, i, 1);        }    }    /**     * @param canvas     * @param position     *            Distance mCurrentSelected difference     * @param type     *            1 represents down drawing, -1 means up drawing     */    private void drawOtherText(Canvas canvas, int position, int type) {        float d = (float) (MARGIN_ALPHA * mMinTextSize * position + type                * mMoveLen);        float scale = parabola(mViewHeight / 4.0f, d);        float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;        mPaint.setTextSize(textSizeDown);        mPaint.setColor(0x333333);        mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));        float y = (float) (mViewHeight / 2.0 + type * d);        Paint.FontMetricsInt fmi = mPaint.getFontMetricsInt();        float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));        canvas.drawText(mDataList.get(mCurrentSelected + type * position),                (float) (mViewWidth / 2.0), baseline, mPaint);    }    /**     * parabola     *     * @param zero     *            Zero coordinates     * @param x     *            Offset     * @return scale     */    private float parabola(float zero, float x) {        float f = (float) (1 - Math.pow(x / zero, 2));        return f < 0 ? 0 : f;    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getActionMasked()) {            case MotionEvent.ACTION_DOWN:                doDown(event);                break;            case MotionEvent.ACTION_MOVE:                doMove(event);                break;            case MotionEvent.ACTION_UP:                doUp(event);                break;        }        return true;    }    private void doDown(MotionEvent event) {        if (mTask != null) {            mTask.cancel();            mTask = null;        }        mLastDownY = event.getY();    }    private void doMove(MotionEvent event) {        mMoveLen += (event.getY() - mLastDownY);        if (mMoveLen > MARGIN_ALPHA * mMinTextSize / 2) {            // Slide down            moveTailToHead();            mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize;        } else if (mMoveLen < -MARGIN_ALPHA * mMinTextSize / 2) {            // Slide up            moveHeadToTail();            mMoveLen = mMoveLen + MARGIN_ALPHA * mMinTextSize;        }        mLastDownY = event.getY();        invalidate();    }    private void doUp(MotionEvent event) {        // Raise the position after mCurrentSelected from the current position to the middle of the selected position        if (Math.abs(mMoveLen) < 0.0001) {            mMoveLen = 0;            return;        }        if (mTask != null) {            mTask.cancel();            mTask = null;        }        mTask = new MyTimerTask(updateHandler);        timer.schedule(mTask, 0, 10);    }    class MyTimerTask extends TimerTask {        Handler handler;        public MyTimerTask(Handler handler) {            this.handler = handler;        }        @Override        public void run() {            handler.sendMessage(handler.obtainMessage());        }    }    public interface onSelectListener {        void onSelect(String text);    }}
2:应用

package com.arch.datetimepicker;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import com.arch.datetimepicker.PickerView.onSelectListener;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private PickerView mHourPicker;    private PickerView mMinutePicker;    List hour = new ArrayList<>();    List minute = new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mHourPicker = (PickerView) findViewById(R.id.choose_hour);        mMinutePicker = (PickerView) findViewById(R.id.choose_minute);        mHourPicker.setPaintTextSizeDivide(140,140,2.8f);        mMinutePicker.setPaintTextSizeDivide(140,140,2.8f);        mHourPicker.setOnSelectListener(new onSelectListener() {            @Override            public void onSelect(String hour) {                android.util.Log.i("PickerView","hour "+hour);            }        });        mMinutePicker.setOnSelectListener(new onSelectListener() {            @Override            public void onSelect(String minute) {                android.util.Log.i("PickerView","minute "+minute);            }        });        for (int i = 0; i < 24; i++) {            hour.add(i < 10 ? "0" + i : "" + i);        }        mHourPicker.setData(hour);        for (int i = 0; i < 60; i++) {            minute.add(i < 10 ? "0" + i : "" + i);        }        mMinutePicker.setData(minute);        mHourPicker.setSelected(0);        mMinutePicker.setSelected(0);    }}

3:布局

<?xml version="1.0" encoding="utf-8"?>        





更多相关文章

  1. android左右滑动翻页查看图片
  2. Android内存缓存图片的标准方法
  3. Android Studio UI布局
  4. Android根据不同语言切换图片
  5. Android 图片处理工具类汇总
  6. android里图片下载工具类AsyncImageLoader分析
  7. android 自由缩放图片
  8. android中实现图片的上下移动
  9. android图片压缩并转为base64字符串

随机推荐

  1. android 中LayoutInflater 的使用
  2. Android上调用WebService
  3. android中ListActivity的使用
  4. Android深入浅出之Audio 第二部分 AudioF
  5. Android(安卓)UI 开发进阶――Dialog
  6. android JNI 系列 一
  7. 定制dialog的方式
  8. Android(安卓)App的运行环境及Android系
  9. Android微信智能心跳方案
  10. Android下SD卡文件操作与数据读写