码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-30 17:33:29      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:

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

标签:

原文地址:http://www.cnblogs.com/xiaomo8086/p/4262382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!