自定义拖拽IndicatorView

来源:互联网 发布:淘宝店铺粉丝最多 编辑:程序博客网 时间:2024/05/22 23:55

1. 效果图

这里写图片描述

2. 根据效果,定义需要属性:

其中模式下: 手动不可点击, 风速时: 最低和最高不可点击, 定时模式: 全部可以点击设置.

<declare-styleable name="IndicatorView">        <attr name="units" format="integer|reference"/>        <attr name="lightColor" format="reference|color"/>        <attr name="lightBitmap" format="reference"/>        <attr name="indicators" format="reference|string"/>        <attr name="controlStyle" format="enum">            <enum name="mode" value="0"/>            <enum name="wind" value="1"/>            <enum name="time" value="2"/>        </attr>    </declare-styleable>
 private void parserAttrs(Context context, AttributeSet attrs) {        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);        mLightColor = ta.getColor(R.styleable.IndicatorView_lightColor,                     Color.argb(0xFF, 0xFF, 0xC1, 0x00));        int resourceId = ta.getResourceId(R.styleable.IndicatorView_lightBitmap, 0);        mLightBitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);        mText = ta.getString(R.styleable.IndicatorView_indicators);        mIndicators = mText.split(",");        mUnits = mText.split(",").length - 1;        int mode = ta.getInt(R.styleable.IndicatorView_controlStyle, TIME);        switch (mode) {            case MODE:                mType = MODE;                break;            case WIND:                mType = WIND;                break;            case TIME:                mType = TIME;                break;        }        ta.recycle();    }

2. 初始化控件的一些默认值:

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    mLeftX = getPaddingLeft();    mAvailableWidth = w - getPaddingLeft() - getPaddingRight();    float unit = mAvailableWidth / mUnits;    mThumbX = mLeftX + unit * mPosition;//粘近position}

3. 测量控件的宽高:

    /*简单测量,只支持为match_parent或者固定值*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width;        int height;        final int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);        final int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);        final int measureWidth = MeasureSpec.getSize(widthMeasureSpec);        final int measureHeight = MeasureSpec.getSize(heightMeasureSpec);        /*布局width为match_parent或者固定值*/        if (measureWidthMode == MeasureSpec.EXACTLY) {            width = measureWidth;        } else {            width = mDefaultWidth;        }        /*布局height为match_parent或者固定值*/        if (measureHeightMode == MeasureSpec.EXACTLY) {            height = measureHeight;        } else {            height = mDefaultHeight;        }        setMeasuredDimension(width, height);    }

4.绘制thumb, 文本,及其tracker

 @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawTrack(canvas);        drawIndicatorTexts(canvas);        drawThumb(canvas);    }    /**     * 绘制thumb所在的track     *     * @param canvas     */    private void drawTrack(Canvas canvas) {        Rect rect = new Rect(mLeftX, getHeight() * 2 / 3 - mTrackHeight / 2, mLeftX + mAvailableWidth,         getHeight() * 2 / 3 + mTrackHeight / 2);        mPaint.setColor(Color.parseColor("#ededed"));        canvas.drawRect(rect, mPaint);    }    /**     * 绘制indicators     *     * @param canvas     */    private void drawIndicatorTexts(Canvas canvas) {        int count = mUnits;        Paint paint;        for (int i = 0; i <= count; i++) {            final float x = mAvailableWidth / count * i + mLeftX;            if (i == mPosition) {//当前选中的position                paint = mTextPaint;                mTextPaint.setColor(mLightColor);            } else {//没选中的position                paint = mTextPaint;                mTextPaint.setColor(Color.argb(0xFF, 0xBB, 0xBB, 0xBB));            }            paint.getTextBounds(mIndicators[i], 0, mIndicators[i].length(), mTextRect);            String text = mIndicators[i];            canvas.drawText(text, x - mTextRect.width() / 2, getHeight() / 3, paint);        }    }    /**     * 绘制thumb     *     * @param canvas     */    private void drawThumb(Canvas canvas) {        Bitmap bitmap = mLightBitmap;        mThumbX = getThumbX(mPosition);        if (bitmap != null) {            canvas.drawBitmap(bitmap, mThumbX - bitmap.getWidth() / 2,             getHeight() * 2 / 3 - bitmap.getHeight() / 2, null);        }    }

5. 构建点击事件的监听器:

@Override    public boolean onTouchEvent(MotionEvent event) {        if (!isEnabled()) {            return false;        }        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_MOVE: {                this.getParent().requestDisallowInterceptTouchEvent(true);                float x = event.getX();                moveThumb(x);                break;            }            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL: {                if (mListener != null) {                    mListener.onPositionChange(mPosition);                }                float x = event.getX();                moveThumb(x);                this.getParent().requestDisallowInterceptTouchEvent(false);                break;            }        }        return true;    }    private void moveThumb(float x) {        if (mPosition == getPosition(x)) {            return;        }        mPosition = getPosition(x);        switch (mType) {            case MODE:                if (mPosition == 0) {                    mPosition = 1;                }                break;            case WIND:                if (mPosition == 0) {                    mPosition = 1;                } else if (mPosition == 4) {                    mPosition = 3;                }                break;            case TIME:                break;        }        mThumbX = getThumbX(mPosition);        invalidate();    }    /**     * 根据thumb的坐标获取thumb的位置     *     * @param x     * @return     */    private int getPosition(float x) {        float unitWidth = mAvailableWidth / mUnits;        float originX = (x - mLeftX + unitWidth / 2f) / unitWidth;        return (int) originX;    }    /**     * 根据thumb的位置获取thumb的坐标     *     * @param position     * @return     */    private float getThumbX(int position) {        float unit = mAvailableWidth / mUnits;        return mLeftX + unit * position;    }

6.保存与恢复自定义view的状态信息:

在屏幕旋转等情况要保存view的状态, 防止一些状态信息丢失,如thumb图标消失.

 @Override    protected void onRestoreInstanceState(Parcelable state) {        if (!(state instanceof Bundle)) {            super.onRestoreInstanceState(state);            return;        }        Bundle bundle = (Bundle) state;        mLightBitmap = bundle.getParcelable("bitmap");        mText = bundle.getString("indicators");        mPosition = bundle.getInt("position");        mThumbX = bundle.getFloat("thumbX");        mType = bundle.getInt("mType");        mTrackHeight = bundle.getInt("trackHeight");        super.onRestoreInstanceState(bundle.getParcelable("instance"));    }    //##### 对外公布的方法###########################//    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable("bitmap", mLightBitmap);        bundle.putInt("position", mPosition);        bundle.putString("indicators", mText);        bundle.putFloat("thumbX", mThumbX);        bundle.putInt("mType", mType);        bundle.putInt("trackHeight", mTrackHeight);        bundle.putParcelable("instance", super.onSaveInstanceState());        return bundle;    }

完整代码:

package ****import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.os.Parcelable;import android.text.TextPaint;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.view.View;import com.bugull.yft_airclean.R;/** * @ author: showdy * @ time: 2016/5/21 14:20 * @ des: 用于控件界面的indicatorView */public class IndicatorView extends View {    private static final int MODE = 0;    private static final int WIND = 1;    private static final int TIME = 2;    private OnPositionChangedListener mListener;    private int mUnits;    private int mLightColor;    private Bitmap mLightBitmap;    private String mText;    private Paint mPaint;    private Paint mTextPaint; //文字画笔    private int mDefaultWidth;    private int mDefaultHeight;    private int mLeftX;    private int mAvailableWidth;    private float mThumbX; //thumb的起始横坐标    private int mPosition = 0; //当前位置    private String[] mIndicators;    private Rect mTextRect;    private int mTrackHeight = 0;    private int mType = TIME;    private Context mContext;    public IndicatorView(Context context) {        this(context, null);    }    public IndicatorView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mContext = context;        mTrackHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4,         context.getResources().getDisplayMetrics());        mDefaultWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 260,         context.getResources().getDisplayMetrics());        mDefaultHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70,         context.getResources().getDisplayMetrics());        parserAttrs(context, attrs);        initPaint();    }    private void initPaint() {        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);        mPaint.setColor(Color.argb(0xFF, 0xBB, 0xBB, 0xBB));        mPaint.setStyle(Paint.Style.FILL);        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);        mTextPaint.setColor(Color.argb(0xFF, 0xBB, 0xBB, 0xBB));        mTextPaint.setStyle(Paint.Style.FILL);        mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14,         getResources().getDisplayMetrics()));        mTextRect = new Rect();    }    private void parserAttrs(Context context, AttributeSet attrs) {        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);        mLightColor = ta.getColor(R.styleable.IndicatorView_lightColor, Color.argb(0xFF, 0xFF, 0xC1, 0x00));        int resourceId = ta.getResourceId(R.styleable.IndicatorView_lightBitmap, 0);        mLightBitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);        mText = ta.getString(R.styleable.IndicatorView_indicators);        mIndicators = mText.split(",");        mUnits = mText.split(",").length - 1;        int mode = ta.getInt(R.styleable.IndicatorView_controlStyle, TIME);        switch (mode) {            case MODE:                mType = MODE;                break;            case WIND:                mType = WIND;                break;            case TIME:                mType = TIME;                break;        }        ta.recycle();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width;        int height;        final int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);        final int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);        final int measureWidth = MeasureSpec.getSize(widthMeasureSpec);        final int measureHeight = MeasureSpec.getSize(heightMeasureSpec);        if (measureWidthMode == MeasureSpec.EXACTLY) {            width = measureWidth;        } else {            width = mDefaultWidth;        }        if (measureHeightMode == MeasureSpec.EXACTLY) {            height = measureHeight;        } else {            height = mDefaultHeight;        }        setMeasuredDimension(width, height);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mLeftX = getPaddingLeft();        mAvailableWidth = w - getPaddingLeft() - getPaddingRight();        float unit = mAvailableWidth / mUnits;        mThumbX = mLeftX + unit * mPosition;//粘近position    }    @Override    public boolean onTouchEvent(MotionEvent event) {        if (!isEnabled()) {            return false;        }        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_MOVE: {                this.getParent().requestDisallowInterceptTouchEvent(true);                float x = event.getX();                moveThumb(x);                break;            }            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL: {                if (mListener != null) {                    mListener.onPositionChange(mPosition);                }                float x = event.getX();                moveThumb(x);                this.getParent().requestDisallowInterceptTouchEvent(false);                break;            }        }        return true;    }    private void moveThumb(float x) {        if (mPosition == getPosition(x)) {            return;        }        mPosition = getPosition(x);        switch (mType) {            case MODE:                if (mPosition == 0) {                    mPosition = 1;                }                break;            case WIND:                if (mPosition == 0) {                    mPosition = 1;                } else if (mPosition == 4) {                    mPosition = 3;                }                break;            case TIME:                break;        }        mThumbX = getThumbX(mPosition);        invalidate();    }    /**     * 根据thumb的坐标获取thumb的位置     *     * @param x     * @return     */    private int getPosition(float x) {        float unitWidth = mAvailableWidth / mUnits;        float originX = (x - mLeftX + unitWidth / 2f) / unitWidth;        return (int) originX;    }    /**     * 根据thumb的位置获取thumb的坐标     *     * @param position     * @return     */    private float getThumbX(int position) {        float unit = mAvailableWidth / mUnits;        return mLeftX + unit * position;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawTrack(canvas);        drawIndicatorTexts(canvas);        drawThumb(canvas);    }    /**     * 绘制thumb所在的track     *     * @param canvas     */    private void drawTrack(Canvas canvas) {        Rect rect = new Rect(mLeftX, getHeight() * 2 / 3 - mTrackHeight / 2,         mLeftX + mAvailableWidth, getHeight() * 2 / 3 + mTrackHeight / 2);        mPaint.setColor(Color.parseColor("#ededed"));        canvas.drawRect(rect, mPaint);    }    /**     * 绘制indicators     *     * @param canvas     */    private void drawIndicatorTexts(Canvas canvas) {        int count = mUnits;        Paint paint;        for (int i = 0; i <= count; i++) {            final float x = mAvailableWidth / count * i + mLeftX;            if (i == mPosition) {//当前选中的position                paint = mTextPaint;                mTextPaint.setColor(mLightColor);            } else {//没选中的position                paint = mTextPaint;                mTextPaint.setColor(Color.argb(0xFF, 0xBB, 0xBB, 0xBB));            }            paint.getTextBounds(mIndicators[i], 0, mIndicators[i].length(), mTextRect);            String text = mIndicators[i];            canvas.drawText(text, x - mTextRect.width() / 2, getHeight() / 3, paint);        }    }    /**     * 绘制thumb     *     * @param canvas     */    private void drawThumb(Canvas canvas) {        Bitmap bitmap = mLightBitmap;        mThumbX = getThumbX(mPosition);        if (bitmap != null) {            canvas.drawBitmap(bitmap, mThumbX - bitmap.getWidth() / 2, getHeight() * 2 / 3 - bitmap.getHeight() / 2, null);        }    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (!(state instanceof Bundle)) {            super.onRestoreInstanceState(state);            return;        }        Bundle bundle = (Bundle) state;        mLightBitmap = bundle.getParcelable("bitmap");        mText = bundle.getString("indicators");        mPosition = bundle.getInt("position");        mThumbX = bundle.getFloat("thumbX");        mType = bundle.getInt("mType");        mTrackHeight = bundle.getInt("trackHeight");        super.onRestoreInstanceState(bundle.getParcelable("instance"));    }    //##### 对外公布的方法###########################//    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable("bitmap", mLightBitmap);        bundle.putInt("position", mPosition);        bundle.putString("indicators", mText);        bundle.putFloat("thumbX", mThumbX);        bundle.putInt("mType", mType);        bundle.putInt("trackHeight", mTrackHeight);        bundle.putParcelable("instance", super.onSaveInstanceState());        return bundle;    }    public void setPosition(int position) {        mPosition = position;        invalidate();    }    public void setLightColor(Context context, int resId, int color) {        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);        mLightBitmap = bitmap;        mLightColor = color;        invalidate();    }    public void setOnPositionChangedListener(OnPositionChangedListener listener) {        mListener = listener;    }    @Override    public void setEnabled(boolean enabled) {        if (!enabled) {            setPosition(0);            setLightColor(mContext, R.mipmap.fsk_thumb_black, Color.parseColor("#bbbbbb"));        }        super.setEnabled(enabled);    }    public interface OnPositionChangedListener {        void onPositionChange(int position);    }}
0 0
原创粉丝点击