首页 > 代码库 > 深度自定义的propressBar和seekBar,可竖直显示,继承自View

深度自定义的propressBar和seekBar,可竖直显示,继承自View

android本身提供的progressBar和seekBar也可以自定义很多属性和样式,可是有时候在面对产品的诸多UI和功能要求时,我们会发现系统控件有时候并不是那么好用,功能不能做到随心所欲。

 

楼主最近在做电视上的设置项目,需要用到各种各样的propressBar和seekBar,横着的,竖着的,样式千奇百怪,实在是很蛋疼,最后自己继承自View写了一个比较统一且样式设置灵活的progressBar。

 

首先自定义了几个xml属性

    <declare-styleable name="TvProgressBar">        <!-- 背景图片 -->        <attr name="background" format="reference" />        <!-- 已走过的进度图片 -->        <attr name="progress" format="reference" />        <!-- 滑块图片 -->        <attr name="thumb" format="reference" />        <!-- 滑块宽度 -->        <attr name="thumbWidth" format="reference|dimension" />        <!-- 进度条宽度 -->        <attr name="progressWidth" format="reference|dimension" />        <!-- 进度条方向       0:水平      1:竖直 -->        <attr name="orientation" format="reference|integer" />    </declare-styleable>

自定义了6个xml属性,分别代表:

background: 进度条的背景图片
progress:  进度条中已经走过的进度用什么图片显示
thumb:针对seekBar的属性,即滑块用什么什么图片显示
thumbWidth:针对seekBar的属性,滑块的宽度
progressWidth:进度条的宽度(已走过的进度宽度)
orientation:进度条的方向(水平或者竖直)

xml中的调用示例

    <com.pptv.tv.view.base.CustomSeekBar        android:id="@+id/progressbar"        android:layout_width="100dp"        android:layout_height="350dp"        tv:background="@drawable/sound_progress_bg"        tv:orientation="@integer/pptv_orientation_vertical"        tv:progressWidth="2dp"        tv:thumb="@drawable/sound_progress_point"        tv:thumbWidth="12dp" />

出来的效果如下图所示:

技术分享

图片资源就不列了,

sound_progress_point就是那个圆形蓝色的滑块,
sound_progress_bg就是那条白色的细线
pptv_orientation_vertical = 1,表示方向竖直。


下面附上类的代码

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.View;import com.pptv.tv.R;public class CustomSeekBar extends View {    public static final int HORIZONTAL = 0;    public static final int VERTICAL = 1;    private Drawable mBackGroundDrawable;    private Drawable mProgressDrawable;    private Drawable mThumbDrawable;    private int mOrientation = 0;    private int mProgressWidth = 0;    private int mThumbWidth = 0;    private int maxProgress = 100;    private int mProgress = 50;    private OnSeekBarChangeListener mSeekBarChangeListener;    public CustomSeekBar(Context context) {        this(context, null);    }    public CustomSeekBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.obtainStyledAttributes(attrs,                R.styleable.TvProgressBar, defStyle, 0);        mBackGroundDrawable = a                .getDrawable(R.styleable.TvProgressBar_background);        mProgressDrawable = a.getDrawable(R.styleable.TvProgressBar_progress);        mThumbDrawable = a.getDrawable(R.styleable.TvProgressBar_thumb);        mProgressWidth = a.getDimensionPixelSize(                R.styleable.TvProgressBar_progressWidth, 0);        mThumbWidth = a.getDimensionPixelSize(                R.styleable.TvProgressBar_thumbWidth, 0);        mOrientation = a.getInteger(R.styleable.TvProgressBar_orientation, 0);        a.recycle();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int width = getWidth();        int height = getHeight();        if (width <= 0 || height <= 0) {            return;        }        float rate = ((float) mProgress) / maxProgress;        // 画背景        if (mBackGroundDrawable != null) {            int bgleft = 0,bgright=0,bgtop=0,bgbottom=0;            if (mOrientation == HORIZONTAL){                bgleft = mThumbWidth / 2;                bgright = width - mThumbWidth / 2;                bgtop = (height - mProgressWidth) / 2;                bgbottom = bgtop + mProgressWidth;            }else if (mOrientation == VERTICAL){                bgleft = (width - mProgressWidth) / 2;                bgright = bgleft + mProgressWidth;                bgtop = mThumbWidth / 2;                bgbottom = height - mThumbWidth / 2;            }            mBackGroundDrawable.setBounds(bgleft, bgtop, bgright, bgbottom);            mBackGroundDrawable.draw(canvas);        }        // 画进度条        if (mProgressDrawable != null) {            int progressleft=0,progressright=0,progresstop=0,progressbottom=0;            if (mOrientation == HORIZONTAL){                progressleft = mThumbWidth / 2;                progressright = (int) (progressleft + rate                        * (width - mThumbWidth));                progresstop = (height - mProgressWidth) / 2;                progressbottom = progresstop + mProgressWidth;            }else if (mOrientation == VERTICAL){                progressleft = (width - mProgressWidth) / 2;                progressright = progressleft + mProgressWidth;                progressbottom = height - mThumbWidth / 2;                progresstop = (int) (progressbottom - rate                        * (height - mThumbWidth));            }            mProgressDrawable.setBounds(progressleft, progresstop,                    progressright, progressbottom);            mProgressDrawable.draw(canvas);        }        // 画滑块        if (mThumbDrawable != null) {            int thumbleft=0,thumbright=0,thumbtop=0,thumbbottom=0;            if (mOrientation == HORIZONTAL){                thumbleft = (int) ((width - mThumbWidth) * rate);                thumbright = thumbleft + mThumbWidth;                thumbtop = (height - mThumbWidth) / 2;                thumbbottom = thumbtop + mThumbWidth;            }else if (mOrientation == VERTICAL){                thumbleft = (width - mThumbWidth) / 2;                thumbright = thumbleft + mThumbWidth;                thumbbottom = (int) (height - rate * (height - mThumbWidth));                thumbtop = thumbbottom - mThumbWidth;            }            mThumbDrawable.setBounds(thumbleft, thumbtop, thumbright,                    thumbbottom);            mThumbDrawable.draw(canvas);        }    }    public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {        mSeekBarChangeListener = listener;    }    public interface OnSeekBarChangeListener {        public abstract void onProgressChanged();    }        public void setOrientation(int orientation){        mOrientation = orientation;        invalidate();    }    public void setProgress(int progress) {        if (progress < 0 || progress > maxProgress) {            return;        }        mProgress = progress;        invalidate();        if (mSeekBarChangeListener != null) {            mSeekBarChangeListener.onProgressChanged();        }    }    public int getProgress() {        return mProgress;    }    public int getMaxProgress() {        return maxProgress;    }    public boolean increase() {        if (mProgress < maxProgress) {            mProgress++;            setProgress(mProgress);            return true;        }        return false;    }    public boolean reduce() {        if (mProgress > 0) {            mProgress--;            setProgress(mProgress);            return true;        }        return false;    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (mOrientation == HORIZONTAL) {            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {                if (mProgress > 0) {                    mProgress--;                    setProgress(mProgress);                    return true;                }            }            if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {                if (mProgress < maxProgress) {                    mProgress++;                    setProgress(mProgress);                    return true;                }            }        }        if (mOrientation == VERTICAL) {            if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {                if (mProgress > 0) {                    mProgress--;                    setProgress(mProgress);                    return true;                }            }            if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {                if (mProgress < maxProgress) {                    mProgress++;                    setProgress(mProgress);                    return true;                }            }        }        return super.onKeyDown(keyCode, event);    }}
重点是在onDraw里面的涂鸦,根据当前进度分别画背景,画进度条,画滑块。代码应该还是很好理解的就不做详细说明了。




深度自定义的propressBar和seekBar,可竖直显示,继承自View