Android自定义SeekBar,带开始值结束值和Thumb上方滑动的Text

来源:互联网 发布:阿里云服务器怎么续费 编辑:程序博客网 时间:2024/05/29 12:28

之前根据网友的博文写了一个Demo(点击打开链接)但是这个Demo用到attr,layout color,还有其他的类,给使用者造成很多麻烦,我想,这样的自定义控件为啥不用一个类来完成呢,这样直接复制过来就能用,于是我彻底的封装了这个自定义的SeekBar,做到了一个类完成所有功能,而且代码量也不多。效果图:


    原理,其实我不是自定义SeekBar,我是自定义了一个RelativeLayout,里面放了三个TextView和一个SeekBar,用代码控制他们的位置,实现动态显示值。

    首先,向自定义的RelativeLayout用代码添加子控件,这样就不用XML来布局了

private void addChildens() {        textView = new ProgressTextView(mContext);        textView.setId(View.generateViewId());        LayoutParams lpTextView = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);        textView.setLayoutParams(lpTextView);        addView(textView);        mSeekBar = new SeekBar(mContext);        mSeekBar.setId(View.generateViewId());        mSeekBar.setMax(seekBarMax);        mSeekBar.setMinimumHeight(12);        if (thumDrawable > 0) {            mSeekBar.setThumb(ContextCompat.getDrawable(mContext, thumDrawable));        }        if (seekBarDrawable > 0) {            mSeekBar.setBackgroundResource(seekBarDrawable);        }        mSeekBar.setPadding(0, 0, 0, 0);        mSeekBar.setThumbOffset(0);        LayoutParams lpSeekBar = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        lpSeekBar.addRule(RelativeLayout.BELOW, textView.getId());        mSeekBar.setLayoutParams(lpSeekBar);        addView(mSeekBar);        mTvStart = new TextView(mContext);        LayoutParams lpStart = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        lpStart.addRule(ALIGN_PARENT_LEFT);        lpStart.addRule(RelativeLayout.BELOW, mSeekBar.getId());        mTvStart.setLayoutParams(lpStart);        addView(mTvStart);        mTvEnd = new TextView(mContext);        LayoutParams lpEnd = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        lpEnd.addRule(ALIGN_PARENT_RIGHT);        lpEnd.addRule(RelativeLayout.BELOW, mSeekBar.getId());        mTvEnd.setLayoutParams(lpEnd);        addView(mTvEnd);    }
    然后就是自定义的一个浮标并显示SeekBar的值:

class ProgressTextView extends View {        private int mHeight;        private int mWidth;        private double mOneProgressWidth;        private int mCurProgress = 0;        private String mProgressText = "";        private Paint mPaint;        private float mThumbOffset;        private int mTextSize = 12;        private float thumWidth;        private String mTextColor = "#303F9F";//default color of column        public ProgressTextView(Context context) {            super(context);            initObserver();        }        @RequiresApi(api = Build.VERSION_CODES.M)        public ProgressTextView(Context context, AttributeSet attrs) {            super(context, attrs);            if (null != context && attrs != null) {                mThumbOffset = thumWidth / 2;            }            initObserver();        }        private void initObserver() {            ViewTreeObserver vto = getViewTreeObserver();            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {                @Override                public boolean onPreDraw() {                    mHeight = getMeasuredHeight();                    mWidth = getMeasuredWidth();                    initPaint();                    initData();                    return true;                }            });        }        private void initPaint() {            mPaint = new Paint();            mPaint.setTextSize(mTextSize);            mPaint.setTextAlign(Paint.Align.CENTER);            mPaint.setColor(Color.parseColor(mTextColor));        }        private void initData() {            mOneProgressWidth = (double) (mWidth - 2 * mThumbOffset) / (seekBarMax);        }        public void setTextSize(int mTextSize) {            this.mTextSize = mTextSize;            invalidate();        }        @Override        protected void onDraw(Canvas canvas) {            initPaint();            drawText(canvas);            super.onDraw(canvas);        }        //设置字体居中显示        private void drawText(Canvas canvas) {            float x = (float) (mCurProgress * mOneProgressWidth);            float textWidth = mPaint.measureText(mProgressText);            float textOffset = textWidth / 2;            if (x + textOffset > mWidth - mThumbOffset) {//超过view的右边                float exWidth = x + textOffset - (mWidth - mThumbOffset);                x -= exWidth;//避免超过右边            }            if (x + mThumbOffset < textOffset) {//超过左边                float exWidth = textOffset - (x + mThumbOffset);                x += exWidth;//避免超过左边            }            canvas.translate(mThumbOffset, 0);            canvas.drawText(mProgressText, x, mHeight, mPaint);        }        //设置显示的进度位置和字符串        public void setProgress(int progress, String showText) {            mCurProgress = progress;            mProgressText = showText;            invalidate();        }    }
我还写了监听器和各种setter,保证这个自定义View的可操作性

Demo源码

阅读全文
0 0