Android Custom View --- Continuous Slider(连续滑动器)

4 篇文章 0 订阅
3 篇文章 0 订阅

Android Custom View — Continuous slider

先上一张Continuous slider的图片吧

Continuous slider

官方链接

先从最简单的开始实现
在实现的过程中,我是将圆形和线分成两个View来实现,包括进一个ViewGroup里

第一步我们先定义大体框架,如下

public class Continuousslider extends ViewGroup {
    public Continuousslider(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

    }

    class Line extends View {

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

    class Circle extends View {

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

}

接下来我们绘制 Circle 和 Line,在这儿只贴出Circle的代码了,Line 的代码可以去github上看,网址会在文末放出

class Circle extends View {
        Paint paint;
        float x;//x轴坐标
        public void moveto(float x){
            this.x=x;
            invalidate();
        }

        public Circle(Context context) {
            super(context);
            paint=new Paint();
            paint.setColor(getResources().getColor(R.color.blue));
            paint.setStyle(Paint.Style.FILL);
            x=getLeft()+20;
        }
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(x>getRight()-20)x=getRight()-20;
            else if(x<=getLeft()+20) {//超出左边界时加以限制,并设置灰色
                x = getLeft() + 20;
                paint.setColor(getResources().getColor(R.color.gray));
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5);
            }else{
                paint.setColor(getResources().getColor(R.color.blue));
                paint.setStyle(Paint.Style.FILL);

            }
            canvas.drawCircle(x, (getTop()+getBottom())/2 , 15, paint);
        }

    }

定义好了Line后我们就要来完善 Continuousslider 了,这一步就是简单的把 Circle 和 Line 添加进 Continuousslider ,并且计算一下大小, 很简单

    Line line;
    Circle circle;
    public Continuousslider(Context context) {
        super(context);
        init();
    }
    public Continuousslider(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    void init(){
        line=new Line(getContext());
        circle=new Circle(getContext());
        addView(line);
        addView(circle);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        float xpad = (float) (getPaddingLeft() + getPaddingRight());
        float ypad = (float) (getPaddingTop() + getPaddingBottom());
        float ww = (float) w - xpad;
        float hh = (float) h - ypad;
        circle.layout(0, 0, (int) ww, (int) hh);
        line.layout(0, 0, (int) ww, (int) hh);
    }

现在我们得到了这样的一个东西
enter image description here

但是它对我们的拖动还不会有任何的响应,所以接下来的一步就是添加点击事件了

@Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("AAA",event.toString());
        if(event.getAction()==MotionEvent.ACTION_MOVE||event.getAction()==MotionEvent.ACTION_UP||
                event.getAction()==MotionEvent.ACTION_DOWN
                ){
            moveto(event.getX());
            return true;
        }
        return false;
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    void moveto(float x){
        line.moveto(x);
        circle.moveto(x);
    }

这儿的moveto就是移动组件的代码,接下来会给出。

Circle 和 Line 的moveto()都很简单,只需要改变一下横坐标值,然后重新绘制一下就行了

public void moveto(float x){
            this.x=x;
            invalidate();
        }

现在我们已经基本实现了拖动的功能了
;

但是感觉这样有点儿单调,我们希望可以给它加一点动画效果,让它看起来更酷炫,就像第一张图里的focus那样

我们采用了ValueAnimator来实现Circle 的动画效果,先上代码

class Circle extends View implements ValueAnimator.AnimatorUpdateListener{
        Paint paint;
        Paint bg;//透明外圈
        float x;
        int radius;
        int radius2;//外圈半径
        boolean temp;//temp 为true则圆圈变大,否则变小
        ValueAnimator animator;
        public void moveto(float x){
            this.x=x;
            invalidate();
        }
        public Circle(Context context) {
            super(context);
            paint=new Paint();
            paint.setColor(getResources().getColor(R.color.blue));
            bg=new Paint();
            bg.setStyle(Paint.Style.FILL);
            bg.setColor(getResources().getColor(R.color.blue));
            bg.setAlpha(26);
            paint.setStyle(Paint.Style.FILL);
            x=getLeft()+20;
            radius=15;
            radius2=15;
            animator=new ValueAnimator();
        }
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(x>getRight()-30)x=getRight()-30;
            else if(x<=getLeft()+30) {
                x = getLeft() + 30;
                paint.setColor(getResources().getColor(R.color.gray));
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5);
                bg.setColor(getResources().getColor(R.color.gray));
                bg.setAlpha(80);
            }else{
                paint.setColor(getResources().getColor(R.color.blue));
                paint.setStyle(Paint.Style.FILL);
                bg.setColor(getResources().getColor(R.color.blue));
                bg.setAlpha(80);
            }
            canvas.drawCircle(x, (getTop()+getBottom())/2 , radius2, bg);
            canvas.drawCircle(x, (getTop()+getBottom())/2 , radius, paint);
        }
        public void scalel() {
            temp=true;
        }
        public void scales() {
            temp=false;
        }
        public void startAnimation(int duration){
            ValueAnimator v=ValueAnimator.ofInt(0,100);
            v.setStartDelay(0);
            v.setDuration(duration);
            v.addUpdateListener(this);
            v.start();
        }
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int test = (int) animation.getAnimatedValue();//0-100中的一个数字,会不断的增加,进行重新绘制
            if(temp){
                radius=15+(15*test)/100;
                radius2=15+(35*test)/100;
            }else{
                radius2=50-(35*test)/100;
                radius=30-(15*test)/100;
            }
            invalidate();
        }
    }

在Continuousslider中调用 startAnimation方法

circle.startAnimation(200);

好了,到此所有的工作都完成了,我们已经实现了想要的结果

源码可以到我的github上查看,别忘了给个星 点击进入

转载请注明出处

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值