1.xml如何自定义圆角 shapeDrawable?环形?三角形?

2.drawable有多少种?用法是什么?

上面的都不说,只说一个关于Drawable不常用到的用法

-----------------------------------------------------我是分割线--------------------------------------------------------

半屏动画实际效果如下图:

Android自定义条形ProgressBar_自定义

第一个想法你想用什么来实现?在view 的 onDraw中实现?这也许是很多人的第一个想法,我也是,

但想起之前在github上翻看某大神源码时看到用自定义Drawable + 动画器插值实现了一个太阳冉冉升起的动画,就想采用类似的做法来做,

具体思路如下:

1.gif图片中的弧形动画以及阻尼动画,说白了也就是canvas绘制圆弧等的组合,即根据时间变化计算绘制相应图形即可

2.Drawable中有draw(Canvas canvas)方法,在此方法中可通过canvas进行绘制,

3.View实现TranslationAnimation,可实现整体的上移或者下移,同时创建时间插值

4.把View动画创建的时间插值动态传递给Drawable,Drawable根据时间插值,动态计算并绘制图形

好处:

1.使用Drawable而不是在View中来绘制,不会影响到之前View中onDraw的代码和逻辑

2.Drawable一般当做背景,与view耦合很小

3.Animation产生插值,可设置不同加速器 产生不同效果

可见,我们所有需要的前置条件都已经满足了,现在开始 实现

1.创建TranslationAnimation产生时间插值,如下图interpolatedTime

final AnimationSet as = new AnimationSet(true);
        as.setDuration(600);
        TranslateAnimation translateAnimation = new TranslateAnimation(
                ScaleAnimation.RELATIVE_TO_SELF,0,
                ScaleAnimation.RELATIVE_TO_SELF,0,
                ScaleAnimation.RELATIVE_TO_SELF,1.0f,
                ScaleAnimation.RELATIVE_TO_SELF,0){
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                super.applyTransformation(interpolatedTime, t);
                myDrawable.setPercent(interpolatedTime, true);
            }
        };
        as.addAnimation(translateAnimation);
        return as;

2.自定义Drawable及讲解

public class MyAnimationDrawable3 extends Drawable implements Drawable.Callback {
    private Paint mPaint;
    private int mWidth;
    private int mHeight;

    public MyAnimationDrawable3(int width,int height) {
        mPaint = new Paint();
        mWidth = width;
        mHeight = height;
    }

    @Override
    public void draw(Canvas canvas) {
        // 主要绘制代码
//        canvas.drawRoundRect(rectF, 30, 30, mPaint);
    }

    @Override
    public int getIntrinsicWidth() {
        return mWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mHeight;
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void invalidateDrawable(Drawable who) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    }

    @Override
    public void scheduleDrawable(Drawable who, Runnable what, long when) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.scheduleDrawable(this, what, when);
        }
    }

    @Override
    public void unscheduleDrawable(Drawable who, Runnable what) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.unscheduleDrawable(this, what);
        }
    }
}

其中draw中负责具体绘制,getIntrinsicWidth,getIntrinsicHeight为指定宽高,setAlpha,setColorFilter等都很简单,最后,该类实现Drawable.CallBack,实现最后三个方法,作用是“把你实现的该接口注册到动画Drawable上可以实现动态Drawable的调度和执行”

3.传递时间插值进入Drawable

/**
     * @param percent 时间插值
     */
    public void setPrecent(float percent){
        if (percent > 0.5f){
            //逻辑代码,计算弧度等
        }else{
            //逻辑代码,计算弧度等
        }
        // 刷新 draw 图形
        invalidateSelf();
    }


传递进去时间插值后,即可根据时间插值计算相关弧度,在draw中进行绘制即可完成动态图中的效果(绘制逻辑 就不说了,大概为插值0-1绘制向上半圆弧,到顶点根据阻尼振动函数绘制半径变化的圆弧)