自定义view,垂直seekbar

话不多说,公司接到的项目中有个效果是上下拉的窗帘,本来是用seekbar旋转90°做的,但是seekbar的属性太多,而且seekbar的滑块会直接显示最底层的颜色(我也不知道为什么), 所有就写了一个自定义view,其实就是一个垂直的seekbar,实现一些简单的操作,例如设置进度,设置前景色和背景色、滑块图片。

首先先看看这个最终效果是什么样的:

然后我们再分析一下这个效果的构成:

1.最底层是白色的。

2.上一层是绿色的(管他什么绿,反正就是绿)。

    3.在上层颜色的底部中间有一个滑块。

分析之后,我们就可以开始考虑怎么写了,下面直接上代码。

<declare-styleable name="WindowBarView">

        <!--bgcolor:背景颜色-->
        <!--cendiagram:中心原点的图片-->
        <!--foreground:前景颜色-->
        <!--maxprogress:最大进度-->
        <!--nowrogress:当前进度-->

        <attr name="bgcolor" format="color" />
        <attr name="cendiagram" format="color|reference" />
        <attr name="foreground" format="color" />
        <attr name="maxprogress" format="integer" />
        <attr name="nowrogress" format="integer" />

    </declare-styleable>
因为需要给控件设置一些属性,我们就先在attrs文件中加入属性(没有这个文件就先创建一个)。

然后就是java文件了,我们让这个自定义view集成自view,代码是酱婶儿的。

public class WindowBarView extends View {

    private int progress = 0;
    private int maxprogress = 0;
    private int nowrogress = 0;
    private int bgcolor = 0;
    private int Foreground = 0;     //窗帘下拉的覆盖的颜色
    private Paint paint;
    private Paint foregrodpaint;
    private Drawable cendiagram = null;     //中心圆点的图片
    private Bitmap cendiagrambp = null;

    // 获得图片的宽高
    int widthbm = 0;
    int heightbm = 0;
    // 取得想要缩放的matrix参数
    Matrix matrix;
    Bitmap newbm;

    private float mPreX, mPreY;

    int width, height;
    Rect rect;
    Rect rectforegroud;

    public setonBarTouthnListener touthnListener = null;

    public interface setonBarTouthnListener {
        public void GetProgress(int progress);
    }

    public void getonBarProgressListener(setonBarTouthnListener touthnListener) {
        this.touthnListener = touthnListener;
    }

    public WindowBarView(Context context) {
        super(context);
    }

    public WindowBarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public WindowBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    public WindowBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        paint = new Paint();
        foregrodpaint = new Paint();
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.WindowBarView);
        Foreground = array.getInteger(R.styleable.WindowBarView_foreground, Color.WHITE);
        cendiagram = array.getDrawable(R.styleable.WindowBarView_cendiagram);
        maxprogress = array.getInteger(R.styleable.WindowBarView_maxprogress, 100);
        nowrogress = array.getInteger(R.styleable.WindowBarView_nowrogress, 0);
        bgcolor = array.getInteger(R.styleable.WindowBarView_bgcolor, Color.WHITE);
        setProgress(array.getInteger(R.styleable.WindowBarView_nowrogress, nowrogress));
        array.recycle();
        cendiagrambp = drawableToBitmap(cendiagram);

        // 获得图片的宽高
        widthbm = cendiagrambp.getWidth();
        heightbm = cendiagrambp.getHeight();
        // 设置想要的大小
        int newWidth = 100;
        int newHeight = 100;
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / widthbm;
        float scaleHeight = ((float) newHeight) / heightbm;
        // 取得想要缩放的matrix参数
        matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        newbm = Bitmap.createBitmap(cendiagrambp, 0,
                0, widthbm, heightbm, matrix, true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int wideSize = MeasureSpec.getSize(widthMeasureSpec);
        int wideMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (wideMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
            width = wideSize;
        } else {
            width = getPaddingLeft() + getPaddingRight();
            if (wideMode == MeasureSpec.AT_MOST) {
                width = Math.min(width, wideSize);
            }

        }

        if (heightMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
            height = heightSize;
        } else {
            height = getPaddingTop() + getPaddingBottom();
            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(height, heightSize);
            }

        }
        setMeasuredDimension(width, height);
        rect = new Rect(0, 0, width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        rectforegroud = new Rect(0, 0, width, (int) mPreY);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(bgcolor);
        paint.setAntiAlias(true);
        canvas.drawRect(rect, paint);
        foregrodpaint.setStyle(Paint.Style.FILL);
        foregrodpaint.setAntiAlias(true);
        foregrodpaint.setColor(Foreground);
        canvas.drawRect(rectforegroud, foregrodpaint);
        canvas.drawBitmap(newbm, width / 2 - newbm.getWidth() / 2, (int) mPreY - newbm.getHeight() / 2, paint);     //绘制滑块
    }

    /**
     * 获取当前位置
     */
    public int getProgress() {
        if(mPreY==0){
            progress = (int) ((float) nowrogress / (float) maxprogress * 100);  //当前进度
        }else{
            progress = Math.round(mPreY / height*(float) maxprogress);  //当前进度
        }
        return progress;
    }

    /**
     * 设置当前进度
     */
    public synchronized void setProgress(final int nowrogress) {
        if(height != 0){
            mPreY = ((int) ((float) nowrogress / (float) maxprogress * height));
            invalidate();
        }else{
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    try {
                        Thread.sleep(100);
                        if (height != 0) {
                            mPreY = ((int) ((float) nowrogress / (float) maxprogress * height));
                            postInvalidate();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }

    /**
     * 判断,如果滑动的位置大于控件的高度,说明此事滑块已经滑到下面
     * 如果小于0说明在上面
     *
     * @param event
     * @return
     */

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPreX = event.getX();
                mPreY = event.getY();
                touthnListener.GetProgress((int) (mPreY / height * maxprogress));
                invalidate();
                return true;
            case MotionEvent.ACTION_MOVE:
                mPreY = event.getY();
                if (mPreY < 0) {
                    mPreY = 0;
                } else if (mPreY > height) {
                    mPreY = height;
                } else {
                    mPreY = event.getY() + 8;
                }
                touthnListener.GetProgress((int) (mPreY / height * maxprogress));
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * drawable转bitmap
     *
     * @param drawable
     * @return
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {

        Bitmap bitmap = Bitmap.createBitmap(

                drawable.getIntrinsicWidth(),

                drawable.getIntrinsicHeight(),

                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888

                        : Bitmap.Config.RGB_565);

        Canvas canvas = new Canvas(bitmap);

        //canvas.setBitmap(bitmap);

        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

        drawable.draw(canvas);

        return bitmap;

    }
}

主要就是onDraw中的内容。

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        rectforegroud = new Rect(0, 0, width, (int) mPreY);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(bgcolor);
        paint.setAntiAlias(true);
        canvas.drawRect(rect, paint);
        foregrodpaint.setStyle(Paint.Style.FILL);
        foregrodpaint.setAntiAlias(true);
        foregrodpaint.setColor(Foreground);
        canvas.drawRect(rectforegroud, foregrodpaint);
        canvas.drawBitmap(newbm, width / 2 - newbm.getWidth() / 2, (int) mPreY - newbm.getHeight() / 2, paint);     //绘制滑块
    }
这个控件我将它分为了三层,这样我就需要在画布上画三次,第一次,绘制最底层颜色,第二次,绘制上一层颜色,第三次绘制滑块,这样才能得到想要的效果。

下面就是使用方法。

<com.tianer.dooya.weight.WindowBarView
                    android:id="@+id/timeline"
                    android:layout_width="200dp"
                    android:layout_height="300dp"
                    app:bgcolor="@color/white"
                    app:foreground="@color/windowbar"
                    app:cendiagram="@drawable/bgg"
                    app:maxprogress="100"/>

最后,上个效果图。

上个源码地址

https://github.com/dzghxs/WindowBarView点击打开链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值