android的materialDesignLibrary源代码分析

android的materialDesignLibrary源代码分析

   最近使用了一个框架materialDesignLibrary,发现它能做出很炫的ui,比如按钮,一点击就会有水波荡开的效果,非常有意思!所以就想读一读它的源码,看一些开源框架的源码能学到很多东西。首先先贴一下使用该框架做的一个登陆注册界面吧。

一,CustomView分析

    上面的是两个ButtonRectangle,点击一下可以看到很明显的水波!那么首先看看ButtonRectangle源码。一开始我想,它是一个button,想必是继承自android.widget.Button的吧?点开一看,发现是确实是继承自Button,不过这个Button是作者自己定义的,它继承自作者重写的一个view,叫做CustomView,而CustomerView继承自我们非常熟悉的RelativeLayout,显然CustomView就是所有有特效的控件的父类了。它直接继承自RelativeLayout。现在看看它对动画的操作,代码如下
public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        if(enabled) {
            this.setBackgroundColor(this.beforeBackground);
        } else {
            this.setBackgroundColor(this.disabledBackgroundColor);
        }

        this.invalidate();
    }

    protected void onAnimationStart() {
        super.onAnimationStart();
        this.animation = true;
    }

    protected void onAnimationEnd() {
        super.onAnimationEnd();
        this.animation = false;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(this.animation) {
            this.invalidate();
        }

    }
按钮不可用的时候设置成#E2E2E2,动画一开始,animation就设置成true,ondraw就可以调用重绘方法了,动画结束,animation变成false,而ondraw方法也就不重绘。这个父类主要就是控制动画的。

二,ButtonRectangle类

    我比较喜欢的就是这个按钮,水波效果,现在开始分析一下这个类。首先看它的构造方法。代码如下
public ButtonRectangle(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setDefaultProperties();
    }

里面有一个初始化属性的方法setDefaultProperties(),在点开看看setDefaultProperties(),代码如下
protected void setDefaultProperties() {
        super.minWidth = 80;
        super.minHeight = 36;
        super.background = drawable.background_button_rectangle;
        super.setDefaultProperties();
    }

初始化的时候把按钮最小宽高背景都设置了,比较简单,但是这个类的另外两个方法值得分析分析的,第一个当然就是ondraw类了,代码如下
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(this.x != -1.0F) {
            Rect src = new Rect(0, 0, this.getWidth() - Utils.dpToPx(6.0F, this.getResources()), this.getHeight() - Utils.dpToPx(7.0F, this.getResources()));
            Rect dst = new Rect(Utils.dpToPx(6.0F, this.getResources()), Utils.dpToPx(6.0F, this.getResources()), this.getWidth() - Utils.dpToPx(6.0F, this.getResources()), this.getHeight() - Utils.dpToPx(7.0F, this.getResources()));
            canvas.drawBitmap(this.makeCircle(), src, dst, (Paint)null);
            this.invalidate();
        }

    }

这个方法就是为什么我们看到的效果就是这个按钮是四四方方的,要是x!=-1.0f就执行重绘,那么什么时候会改变x的值呢?这就要看上面提过的Button类了。主要是有个ontouch事件,在Button里面,看看,代码
public boolean onTouchEvent(MotionEvent event) {
        this.invalidate();
        if(this.isEnabled()) {
            this.isLastTouch = true;
            if(event.getAction() == 0) {
                this.radius = (float)(this.getHeight() / this.rippleSize);
                this.x = event.getX();
                this.y = event.getY();
            } else if(event.getAction() == 2) {
                this.radius = (float)(this.getHeight() / this.rippleSize);
                this.x = event.getX();
                this.y = event.getY();
                if(event.getX() > (float)this.getWidth() || event.getX() < 0.0F || event.getY() > (float)this.getHeight() || event.getY() < 0.0F) {
                    this.isLastTouch = false;
                    this.x = -1.0F;
                    this.y = -1.0F;
                }
            } else if(event.getAction() == 1) {
                if(event.getX() <= (float)this.getWidth() && event.getX() >= 0.0F && event.getY() <= (float)this.getHeight() && event.getY() >= 0.0F) {
                    ++this.radius;
                    if(!this.clickAfterRipple && this.onClickListener != null) {
                        this.onClickListener.onClick(this);
                    }
                } else {
                    this.isLastTouch = false;
                    this.x = -1.0F;
                    this.y = -1.0F;
                }<pre name="code" class="java"> <span style="font-family: Arial, Helvetica, sans-serif;">    } else if(event.getAction() == 3) {</span>
this.isLastTouch = false; this.x = -1.0F; this.y = -1.0F; } } return true; }
 
 
这其实是监听了按钮的点击事件,按下和不按.。有意思的是,还可以设置水波的速度。
public float getRippleSpeed() {
        return this.rippleSpeed;
    }

三,ProgressBarIndeterminateDeterMinate

这个类使用了属性动画objectanimation,构造函数创建一个线程以启动动画。代码如下

 public ProgressBarIndeterminateDeterminate(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.post(new Runnable() {
            public void run() {
                ProgressBarIndeterminateDeterminate.this.setProgress(60);
                ViewHelper.setX(ProgressBarIndeterminateDeterminate.this.progressView, (float)(ProgressBarIndeterminateDeterminate.this.getWidth() + ProgressBarIndeterminateDeterminate.this.progressView.getWidth() / 2));
                ProgressBarIndeterminateDeterminate.this.animation = ObjectAnimator.ofFloat(ProgressBarIndeterminateDeterminate.this.progressView, "x", new float[]{(float)(-ProgressBarIndeterminateDeterminate.this.progressView.getWidth() / 2)});
                ProgressBarIndeterminateDeterminate.this.animation.setDuration(1200L);
                ProgressBarIndeterminateDeterminate.this.animation.addListener(new AnimatorListener() {
                    int cont = 1;
                    int suma = 1;
                    int duration = 1200;

                    public void onAnimationEnd(Animator arg0) {
                        if(ProgressBarIndeterminateDeterminate.this.runAnimation) {
                            ViewHelper.setX(ProgressBarIndeterminateDeterminate.this.progressView, (float)(ProgressBarIndeterminateDeterminate.this.getWidth() + ProgressBarIndeterminateDeterminate.this.progressView.getWidth() / 2));
                            this.cont += this.suma;
                            ProgressBarIndeterminateDeterminate.this.animation = ObjectAnimator.ofFloat(ProgressBarIndeterminateDeterminate.this.progressView, "x", new float[]{(float)(-ProgressBarIndeterminateDeterminate.this.progressView.getWidth() / 2)});
                            ProgressBarIndeterminateDeterminate.this.animation.setDuration((long)(this.duration / this.cont));
                            ProgressBarIndeterminateDeterminate.this.animation.addListener(this);
                            ProgressBarIndeterminateDeterminate.this.animation.start();
                            if(this.cont == 3 || this.cont == 1) {
                                this.suma *= -1;
                            }
                        }

                    }

                    public void onAnimationStart(Animator arg0) {
                    }

                    public void onAnimationRepeat(Animator arg0) {
                    }

                    public void onAnimationCancel(Animator arg0) {
                    }
                });
                ProgressBarIndeterminateDeterminate.this.animation.start();
            }
        });
    }

四,总结

了解了一些重写view的方法,以及认识到一些优秀的开源框架可以从中学到很多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值