zoukankan      html  css  js  c++  java
  • 深度自定义的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里面的涂鸦,根据当前进度分别画背景,画进度条,画滑块。代码应该还是很好理解的就不做详细说明了。




  • 相关阅读:
    洛谷【P1177】【模板】归并排序
    洛谷【P1177】【模板】快速排序
    洛谷【P1104】生日(冒泡排序版)
    洛谷【P1104】生日(插入排序版)
    洛谷【P1104】生日(选择排序版)
    BZOJ5443:[CEOI2018]Lottery
    ReactNative---ref的用法和技巧
    ios---运用MJRefresh组件设置下拉刷新
    ReactNative---setState与性能的平衡
    ios---设置UITabBarController的字体颜色和大小
  • 原文地址:https://www.cnblogs.com/xiaomo8086/p/4262382.html
Copyright © 2011-2022 走看看