seekBar的分段显示

来源:互联网 发布:centos 设备管理器 编辑:程序博客网 时间:2024/05/22 05:13

自定义seekBar的分段显示,这个以后也会用的到。下面的这个代码是自己在网上搜的(源链接:http://blog.csdn.net/lyj1005353553/article/details/77099578),然后自己把需要添加注释的代码都添加了注释,方便大家理解,自己也做了一些小改动现在可以直接拿去用,用的时候只需要在XML文件和代码中写几句代码就可以了。

首先需要在attr文件中添加

<declare-styleable name="RangeSliderView">  <attr name="rangeCount" format="integer"/>  <attr name="filledColor" format="color"/>  <attr name="emptyColor" format="color"/>  <attr name="barHeightPercent" format="float"/>  <attr name="circleRadiusPercent" format="float"/>  <attr name="sliderRadiusPercent" format="float"/></declare-styleable>
  1. XML文件中配置属性,需要在根布局中声明xmlns:rsv=”http://schemas.android.com/apk/res-auto”
    rsv:emptyColor=”#自定义” //一级背景颜色
    rsv:filledColor=”#自定义” //二级背景颜色
  2. Activity中
    rangeSliderBar = (RangeSliderBar) findViewById(R.id.rsv_custom);
    rangeSliderBar.setRangeCount(mDatas.length); //设置分段的个数
    rangeSliderBar.setContext(this);
    rangeSliderBar.setNums(mDatas); //设置分段的数据
    //实现的接口
    rangeSliderBar.setOnSelectRangeBarListener(new RangeSliderBar.OnSelectRangeBarListener() {
    @Override
    public void OnSelectRange(int rangeNum) {
    Toast.makeText(MainActivity.this,
    “我现在的位置是” + rangeNum,
    Toast.LENGTH_SHORT).show();
    }
    });

    自定义控件完整代码:

public class RangeSliderBar extends View {    private static final String TAG = "RangeSliderBar";    private Context context;    /**    画笔的默认的宽度    */    private static final int DEFAULT_PAINT_STROKE_WIDTH = 8;    /**    seekBar的默认二级背景    */    private static final int DEFAULT_FILLED_COLOR = Color.parseColor("#FFA500");    /**    seekBar的默认一级背景    */    private static final int DEFAULT_EMPTY_COLOR = Color.parseColor("#ff0000");    /**     * rangebar粗细     */    private static final float DEFAULT_BAR_HEIGHT_PERCENT = 0.10f;    /**     * 设置自定义seekBar的长度     * 这个长度要与传进来数组的长度一致     */    private static final int DEFAULT_RANGE_COUNT = 6;    /**     * rangebar高度     */    private static final int DEFAULT_HEIGHT_IN_DP = 90;    /**     * seekBar的画笔     */    protected Paint paint;     /**     * 分段显示的画笔     */    protected Paint mPaint;    /**     * 当前的索引位置     */    private int currentIndex;    /**     * 当前的X坐标     */    private float currentSlidingX;    /**     * 当前的Y坐标     */    private float currentSlidingY;     /**     * 具体分段显示的数值     */    private int[] circlePositions;    /**     * 分段显示的距离数组     */    private float[] circlePositions2 = new float[DEFAULT_RANGE_COUNT];    /**     * 填充颜色     */    private int filledColor = DEFAULT_FILLED_COLOR;    /**     * 空白颜色     */    private int emptyColor = DEFAULT_EMPTY_COLOR;    private float barHeightPercent = DEFAULT_BAR_HEIGHT_PERCENT;    /**     * 分段显示的数量     */    private int rangeCount = DEFAULT_RANGE_COUNT;    private int barHeight, locationY;    private float downX;    private float downY;    /**     * seekBar滑块的图片     */    private Bitmap bitmap_point;    private int layoutHeight;//    private boolean mPopupStyle;//是否显示pop    private PopupWindow mPopup;    View popView;    TextView tv;    int indexNum; //位置数值    private int[] mPosition;    public RangeSliderBar(Context context) {        this(context, null);        this.context = context;        initPop();    }    public RangeSliderBar(Context context, AttributeSet attrs) {        this(context, attrs, -1);        this.context = context;        initPop();    }    public void setContext(Context context) {        this.context = context;    }    public void setShowPopText(String str) {        tv.setText(str);    }    void initPop() {        mPosition = new int[2];//        popView = LayoutInflater.from(context).inflate(R.layout.seekbar_pop, null);//        mPopup = new PopupWindow(popView, popView.getWidth(), popView.getHeight(), true);//        tv = (TextView) popView.findViewById(R.id.tv_showtxt);    }    public RangeSliderBar(Context context, AttributeSet attrs, int            defStyleAttr) {        super(context, attrs, defStyleAttr);        //自定义属性        if (attrs != null) {            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable                    .RangeSliderView);            TypedArray sa = context.obtainStyledAttributes(attrs, new                    int[]{android.R.attr.layout_height});            try {                layoutHeight = sa.getLayoutDimension(                        0, 0);                rangeCount = a.getInt(                        R.styleable.RangeSliderView_rangeCount,                        DEFAULT_RANGE_COUNT);                filledColor = a.getColor(                        R.styleable.RangeSliderView_filledColor,                        DEFAULT_FILLED_COLOR);                emptyColor = a.getColor(                        R.styleable.RangeSliderView_emptyColor,                        DEFAULT_EMPTY_COLOR);                barHeightPercent = a.getFloat(                        R.styleable.RangeSliderView_barHeightPercent,                        DEFAULT_BAR_HEIGHT_PERCENT);                barHeightPercent = a.getFloat(                        R.styleable.RangeSliderView_barHeightPercent,                        DEFAULT_BAR_HEIGHT_PERCENT);            } finally {                a.recycle();                sa.recycle();            }        }        setBarHeightPercent(barHeightPercent);        setRangeCount(rangeCount);        paint = new Paint(Paint.ANTI_ALIAS_FLAG);        paint.setStrokeWidth(DEFAULT_PAINT_STROKE_WIDTH);        paint.setStyle(Paint.Style.FILL_AND_STROKE);        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(Color.WHITE);        mPaint.setTextSize(30);//        mPaint.setAntiAlias(true);        //自定义控件UI的监听器        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver                .OnPreDrawListener() {            @Override            public boolean onPreDraw() {                getViewTreeObserver().removeOnPreDrawListener(this);                // Update radius after we got new height                updateRadius(getHeight());                // Compute drawing position again                preComputeDrawingPosition();                // Ready to draw now                return true;            }        });        //设置默认选中第二个位置        currentIndex = 2;//        setShowPopText(circlePositions[currentIndex] + "");    }    private void updateRadius(int height) {        barHeight = (int) (height * barHeightPercent);        locationY = barHeight + DEFAULT_HEIGHT_IN_DP; //Y位置    }    /**     * 设置分段显示的数据     */    public void setNums(int[] nums) {        this.circlePositions = nums;    }    /**     * 设置分段显示的长度,必须与数据的大小一致!     * @param rangeCount     */    public void setRangeCount(int rangeCount) {        if (rangeCount < 2) {            throw new IllegalArgumentException("rangeCount must be >= 2");        }        this.rangeCount = rangeCount;    }    public void setBarHeightPercent(float percent) {        if (percent <= 0.0 || percent > 1.0) {            throw new IllegalArgumentException("Bar height percent must be in" +                    " (0, 1]");        }        this.barHeightPercent = percent;    }    /**     * Perform all the calculation before drawing, should only run once     * 计算各分段显示的位置,这里采取均匀分开!     */    private void preComputeDrawingPosition() {        int w = getWidthWithPadding();        int h = getHeightWithPadding();        initPop();        /** Space between each circle */        int spacing = w / rangeCount;        /** Center vertical */        int y = getPaddingTop() + h / 2;        currentSlidingY = y;        int x = getPaddingLeft() + (spacing / 2);        /** Store the position of each circle index */        for (int i = 0; i < circlePositions.length; ++i) {            circlePositions2[i] = x;            Log.e("--------->", "circlePositions[i]==" + circlePositions[i]);            if (i == currentIndex) {                currentSlidingX = x;            }            //这里采用均匀距离,若是想根据值来显示距离,这里需要自己修改!            x += spacing;        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight                (heightMeasureSpec));    }    /**     * Measures height according to the passed measure spec     *     * @param measureSpec int measure spec to use     * @return int pixel size     */    private int measureHeight(int measureSpec) {        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        int result;        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            final int height;            if (layoutHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {                height = dpToPx(getContext(), DEFAULT_HEIGHT_IN_DP);            } else if (layoutHeight == ViewGroup.LayoutParams.MATCH_PARENT) {                height = getMeasuredHeight();            } else {                height = layoutHeight;            }            result = height + getPaddingTop() + getPaddingBottom() + (2 *                    DEFAULT_PAINT_STROKE_WIDTH);            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }    /**     * Measures width according to the passed measure spec     *     * @param measureSpec int measure spec to use     * @return int pixel size     */    private int measureWidth(int measureSpec) {        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        int result;        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            result = specSize + getPaddingLeft() + getPaddingRight() + (2 *                    DEFAULT_PAINT_STROKE_WIDTH);            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }    private void updateCurrentIndex() {        float min = Float.MAX_VALUE;        int j = 0;        /** Find the closest to x */        for (int i = 0; i < rangeCount; ++i) {            float dx = Math.abs(currentSlidingX - circlePositions2[i]);            if (dx < min) {                min = dx;                j = i;            }        }        currentIndex = j;        /** Correct position */        currentSlidingX = circlePositions2[j];        Log.e("updateCurrentIndex==", "currentSlidingX=" + currentSlidingX);        downX = currentSlidingX;        downY = currentSlidingY;        invalidate();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        float y = event.getY();        float x = event.getX();        final int action = event.getActionMasked();        switch (action) {            case MotionEvent.ACTION_DOWN:                downX = x;                downY = y;                this.getLocationOnScreen(mPosition);//                mPopup.showAsDropDown(this, (int) downX, -170 - bitmap_point.getHeight());                break;            case MotionEvent.ACTION_MOVE:                if (x >= circlePositions2[0] && x <=                        circlePositions2[rangeCount - 1]) {                    currentSlidingX = x;                    currentSlidingY = y;                    invalidate();                }                break;            case MotionEvent.ACTION_UP:                currentSlidingX = x;                currentSlidingY = y;//                mPopup.dismiss();                updateCurrentIndex();                invalidate();                if (onSelectRangeBarListener != null) {                    int range = circlePositions[currentIndex];//                    setShowPopText(range + "");                    onSelectRangeBarListener.OnSelectRange(range);                }                break;        }        return true;    }    private void drawDefaultCircle(Canvas canvas) {        paint.setColor(emptyColor);        int h = getHeightWithPadding();        int y = getPaddingTop() + (h >> 1);        for (int i = 0; i < circlePositions.length; ++i) {            //每个对应数字下画竖线            /**             * 画线参数:startX,startY,endX,endY             * 画文字参数:文字,起始坐标X,起始坐标Y             */            canvas.drawLine(circlePositions2[i], y + barHeight + 5, circlePositions2[i], y + barHeight + 20, mPaint);            canvas.drawText(circlePositions[i] + "s", circlePositions2[i] - 10, y + barHeight + 50, mPaint);        }    }    private void drawSlidRangeCircle(Canvas canvas, int x0, int spc) {        paint.setColor(filledColor);        int h = getHeightWithPadding();        int y = getPaddingTop() + (h >> 1);        for (int i = 0; i < circlePositions.length; ++i) {            canvas.drawText(circlePositions[i] + "", circlePositions2[i] - 10, y + barHeight + 50, mPaint);        }    }    /**     * 画rangebar     *     * @param canvas     * @param from     * @param to     * @param color     */    private void drawBar(Canvas canvas, int from, int to, int color) {        paint.setColor(color);        int half = (barHeight >> 1);        int y = getPaddingTop() + barHeight + DEFAULT_HEIGHT_IN_DP; //设置bar位置        /**         * 画长方形         *///        canvas.drawRect(from, y - half, to, y + half, paint);        /**         * 画圆角矩形         *///        RectF oval3 = new RectF(from, y - half, to, y + half);//        canvas.drawRoundRect(oval3, 3, 3, paint);//画圆角矩形        /**         * 画线         */        canvas.drawLine(from, y, to, y, paint);    }    private int getViewWidth(View v) {        int w = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        int h = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        v.measure(w, h);        return v.getMeasuredWidth();    }    private int getViewHeight(View v) {        int w = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        int h = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        v.measure(w, h);        return v.getMeasuredHeight();    }    public void onDraw(Canvas canvas) {        super.onDraw(canvas);        int w = getWidthWithPadding();        int spacing = w / rangeCount;        int border = (spacing >> 1);        int x0 = getPaddingLeft() + border;        if (mPopup != null) {            try {                this.getLocationOnScreen(mPosition);                mPopup.update((int) downX, -170, getViewWidth(popView)                        , getViewHeight(popView));            } catch (Exception e) {            }        }//        bitmap_point = BitmapFactory.decodeResource(getResources(), AppMgr.iDraw("dot_chart"));        bitmap_point = BitmapFactory.decodeResource(getResources(), R.mipmap.seekbar_yelloe);        /** Draw empty bar 画一级背景*/        drawBar(canvas, (int) circlePositions2[0], (int)                circlePositions2[rangeCount - 1], emptyColor);        /** Draw filled bar 画二级背景*/        drawBar(canvas, x0, (int) currentSlidingX, filledColor);        int bitmap_pointHeight = bitmap_point.getHeight();        Log.e(TAG,bitmap_pointHeight+""); //56        //seekBar滑块的位置,这里根据自己的需要进行调整        //画移动背景图        canvas.drawBitmap(bitmap_point, (int) currentSlidingX - 30, x0 , null);        /** Draw the selected range circle */        paint.setColor(filledColor);        drawDefaultCircle(canvas);//        drawSlidRangeCircle(canvas, (int) currentSlidingX, spacing);    }    public int getHeightWithPadding() {        return getHeight() - getPaddingBottom() - getPaddingTop();    }    public int getWidthWithPadding() {        return getWidth() - getPaddingLeft() - getPaddingRight();    }    @Override    public Parcelable onSaveInstanceState() {        Parcelable superState = super.onSaveInstanceState();        SavedState ss = new SavedState(superState);        ss.saveIndex = this.currentIndex;        return ss;    }    @Override    public void onRestoreInstanceState(Parcelable state) {        if (!(state instanceof SavedState)) {            super.onRestoreInstanceState(state);            return;        }        SavedState ss = (SavedState) state;        super.onRestoreInstanceState(ss.getSuperState());        this.currentIndex = ss.saveIndex;    }    /**     * 保存状态的类,横竖屏切换的时候用来保存切换之前的状态     */    static class SavedState extends BaseSavedState {        int saveIndex;        SavedState(Parcelable superState) {            super(superState);        }        private SavedState(Parcel in) {            super(in);            this.saveIndex = in.readInt();        }        @Override        public void writeToParcel(Parcel out, int flags) {            super.writeToParcel(out, flags);            out.writeInt(this.saveIndex);        }        //required field that makes Parcelables from a Parcel        public static final Creator<SavedState> CREATOR =                new Creator<SavedState>() {                    public SavedState createFromParcel(Parcel in) {                        return new SavedState(in);                    }                    public SavedState[] newArray(int size) {                        return new SavedState[size];                    }                };    }    /**     * Helper method to convert dp to pixel     *     * @param context     * @param dp     * @return     */    static int dpToPx(final Context context, final float dp) {        return (int) (dp * context.getResources().getDisplayMetrics().density);    }    OnSelectRangeBarListener onSelectRangeBarListener;    /**     * 自定义接口,提供接口让外部实现处理自己的逻辑     */    public interface OnSelectRangeBarListener {        /**         * 实现接口需要实现的方法,这里的参数rangeNum就是seekBar滑动停止后的位置所对应的数据         */        void OnSelectRange(int rangeNum);    }    public void setOnSelectRangeBarListener(OnSelectRangeBarListener                                                    onSelectRangeBarListener) {        this.onSelectRangeBarListener = onSelectRangeBarListener;    }}

最后再次注明一下源链接:http://blog.csdn.net/lyj1005353553/article/details/77099578

原创粉丝点击