SeekBar实现实现进度提示随thum移动,自定义View

来源:互联网 发布:张予曦淘宝店铺不开 编辑:程序博客网 时间:2024/06/05 15:21

SeekBar在低版本并没有提供随着进度移动的而跟着移动的进度显示,如下图所示:


转载请保留原文链接:http://blog.csdn.net/u010593680/article/details/50967608

所以只能自己动手了,百度了一下,发现SeekBar并没有提供当前thumb的位置的方法,所以只能自己看看源码来设计了,我们关键是要知道thum位于SeekBar的位置就可以了,我们知道SeekBar可以设置最大进度max,但是thumb位于SeekBar的位置并不是增加1就移动1/max ,一开始简单的测试过了,不同的SeekBar误差挺大的,经常是前面的正常在thumb上显示,后面的进度却相差越来越大,经常是thumb(原点)上方都没字了。

懒办法不太好,只能从源码入手了,好在源码并不多,并且代码风格很好,一开始看到SeekBar.java中只有一些父类AbsSeekBar虚方法的实现代码,具体的thum的控制并不在此,继续深入继承的类AbsSeekBar,AbsSeekBar继承自ProgressBar,只是在ProgressBar的基础上多画一个Thumb而已, 在这个类里找到了mThumbOffset这个变量,从命名可以看出是有关系的,于是查看相关代码,最后发现进度的每一步的长度为: (SeekBar.getWidth() - Thumb.getWidth()) / max , (SeekBar的Padding也有影响,这里没考虑,可以设置SeekBar的paddingLeft和Right为0dp,消除影响)

/** * Created by chenxiaoxuan */public class ProgressTextView extends View {    private static final String TAG = ProgressTextView.class.getSimpleName();    private int mTextColor = Color.WHITE;    private int mHeight;    private int mWidth;    private double mOneProgressWidth;    private int mCurProgress = 0;    private String mProgressText = "";    private int mMaxProgress = 100;    private Paint mPaint;    private float mThumbOffset;    private int mTextSize = 36;    public ProgressTextView(Context context, AttributeSet attrs) {        super(context, attrs);        if (null != context && attrs != null) {            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressTextView);            mTextColor = array.getColor(R.styleable.ProgressTextView_ptv_textColor, Color.WHITE);            mTextSize = array.getDimensionPixelSize(R.styleable.ProgressTextView_ptv_thumWidth, 36);            float thumWidth = array.getDimension(R.styleable.ProgressTextView_ptv_thumWidth, 20);            Log.e(TAG, " thum width " + thumWidth);            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(mTextColor);    }    private void initData() {        mOneProgressWidth = (double) (mWidth - 2 * mThumbOffset) / (mMaxProgress);    }    @Override    protected void onDraw(Canvas canvas) {        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();    }}
使用:

<com.utils.widget.ProgressTextView            android:id="@+id/ptv_open_persentage"            custom:ptv_textColor="@color/default_white"            custom:ptv_textSize="12sp"             custom:ptv_thumWidth="16dp"//设置thum的大小            android:layout_width="219dp"            android:layout_height="20dp"            android:layout_above="@+id/sb_open_persentage"            android:layout_alignParentEnd="true"            android:layout_marginBottom="-5dp" />        <SeekBar            android:id="@+id/sb_open_persentage"            android:layout_width="219dp"            android:layout_height="wrap_content"            android:layout_alignParentEnd="true"            android:layout_centerVertical="true"            android:max="100"            android:maxHeight="2dp"            android:minHeight="2dp"            android:paddingEnd="0dp"            android:paddingStart="0dp"            android:progress="0"            android:progressDrawable="@drawable/seekbar_define_color_style"            android:thumb="@drawable/seekbar_thumb_padding"            android:thumbOffset="0dp" />
在SeekBar进度改变的地方写上需要设置的内容:

@Override        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {            if (fromUser) {                mProgress = progress;            }            mProgressTextView.setProgress(progress, progress + "%");        }

转载请保留原文链接:http://blog.csdn.net/u010593680/article/details/50967608


1 0
原创粉丝点击