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

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


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值