Android动画——仿vivo指纹动画效果


Google在发布Android 5.0的时候,提供了对Vector的支持,实现了矢量图中Path部分,当然,这不是主要的,主要的是矢量图动画的支持,让我们的app更是充满乐趣!


先上下仿指纹动画的效果图:


从效果图上我们看出,这每一条线都是贝塞尔曲线,由起点,控制点和终点决定着每一条线,对应着矢量图中的path。


1.矢量图xml

看代码片断(在drawable中建一个bezier_svg.xml文件):

        <path
            android:name="line_13"
            android:pathData="M250, 155 C 255, 171 260, 204 247, 234"
            android:strokeColor="@android:color/holo_red_dark"
            android:strokeLineCap="round"
            android:strokeWidth="4" />


解析:

pathData由一串字母组成,有大小写区别,大写是基于原点坐标的位置,小写是基于当前坐标每户的位置。

M(250,155):相当于path中的moveTo方法,将画笔移动到对应的坐标。

C(255,171 || 260,204 || 247,234)(竖线是特意加进去以便观察):这里面有三个坐标,对应着三次贝塞尔曲线的控制点1,控制点2,终点。对贝塞尔曲线有疑问的可以百度。

另外,还有其他的字母,但这里没用到,也一并解析一下:

Q(x, y  z, w):对应着二次贝塞尔曲线的控制点(x,y)、终点(z,w)。

L(x,y):以x,y点为终点画一条直线

A(rx,ry,rotation,large_arc_flag,sweep_flag,x,y):这里面参数较多,对应着一个椭圆的各个参数,rx ry为x和y轴的半径,rotation为x轴的旋转角度,两个flat对应的是弧度和绘画方向,最后的x,y是本次椭圆绘画的终点坐标(画到这个点结束,并不是把椭圆画完整)。


贝塞尔曲线示例:



有了贝塞尔曲线的所有path,这还不算完,关键是要让它动起来。

2.动画xml

既然要创建动画,我们在res下建立animator文件夹,建一个anim_trim_path_end.xml文件:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="700"
    android:interpolator="@android:interpolator/linear"
    android:propertyName="trimPathEnd"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType" />

这里面有个新的东西trimPathEnd,这个是android矢量图做动画的关键,从0到1,0代表着从空白的开始画path,1即为百分之百的画完了。如果不明白,直接看网上的一个图,一个正方形trimPathEnd从0到1:



当然,对path动画除了这个属性外还有个对应的trimPathStart,这个和trimPathEnd刚好相反,代表着擦除动画,0代表着一画完整的path,0.5表示擦了一半,即只显示path的后半段路径,1表示擦除完全,将会什么也不显示。


有了动画xml之外,还得有一个东西,关连动画xml和矢量图xml。那就是


3.关连xml

在res/drawable中建一个bezier_anim12.xml,对应代码:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/bezier_svg">
    <target
        android:name="line_121"
        android:animation="@animator/anim_trim_path_end" />
    <target
        android:name="line_122"
        android:animation="@animator/anim_trim_path_end" />
    <target
        android:name="line_123"
        android:animation="@animator/anim_trim_path_end" />
</animated-vector>

name对应着矢量图path中的name,animation对应着动画中的xml,不同的target对应着不同的path。

有了这个xml,我们可以在布局文件里使用它:

    <ImageView
        android:id="@+id/bezier"
        android:layout_width="400dp"
        android:layout_height="400dp"
        android:layout_centerHorizontal="true"
        android:background="#88aa88"
        android:src="@drawable/bezier_anim12" />


有了这些,我们便可以在activity里作动画了,通过AnimatedVectorDrawable的start方法,可以让它动起来。

Activity代码:

public class MainActivity extends AppCompatActivity {

    public @BindView(R.id.bezier) ImageView bezier;
    public @BindView(R.id.text) TextView text;
    public int stage = 1;
    public HashMap<Integer, AnimatedVectorDrawable> vectorDrawableHashMap = new HashMap<>();
    public AnimatedVectorDrawable bezierAnimator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initVectorDrawable();
    }

    public void initVectorDrawable() {
        text.setText(String.valueOf(stage));
        vectorDrawableHashMap.put(1, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim01, null));
        vectorDrawableHashMap.put(2, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim02, null));
        vectorDrawableHashMap.put(3, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim03, null));
        vectorDrawableHashMap.put(4, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim04, null));
        vectorDrawableHashMap.put(5, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim05, null));
        vectorDrawableHashMap.put(6, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim06, null));
        vectorDrawableHashMap.put(7, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim07, null));
        vectorDrawableHashMap.put(8, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim08, null));
        vectorDrawableHashMap.put(9, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim09, null));
        vectorDrawableHashMap.put(10, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim10, null));
        vectorDrawableHashMap.put(11, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim11, null));
        vectorDrawableHashMap.put(12, (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bezier_anim12, null));
    }

    private void drawFingerprint() {
        if (bezierAnimator != null && bezierAnimator.isRunning()) {
            return;
        }
        text.setText(String.valueOf(stage));
        bezierAnimator = vectorDrawableHashMap.get(stage);
        bezier.setImageDrawable(bezierAnimator);
        bezierAnimator.start();
        stage++;
        if (stage > 12) {
            stage = 1;
        }
    }

    @OnClick({R.id.bezier, R.id.text})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bezier:
                drawFingerprint();
                break;
            case R.id.text:
                drawFingerprint();
                break;
        }
    }
}

这里使用了butterknife插件,可以支持对资源、事件等的绑定,在这里我就不具体讲了,可以百度一下,这个插件可以让我们不用再去什么findViewById,不用去setXXXLestener啥的。


具体代码已上传到github:https://github.com/jxr202/VivoFingerprintAnimator


有兴趣大家一块讨论。


上学的时候,老师曾教导了我一句话,挺深刻的:不积跬步,无以至千里。。。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值