Android动画进阶

这篇具有很好参考价值的文章主要介绍了Android动画进阶。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Android中,实现动画的方式通常有两种:视图动画和属性动画。然而这两种方式只能实现一些较为简单动画,仅仅通过改变这些控件属性的方式实现一些复杂的动画效果是比较有难度的,那么我们该如何实现复杂的动画。这里介绍两种实现方式:PathMeasure和SVG。

利用PathMeasure实现路径动画

PathMeasure是Android提供给开发者的一个API用于实现一个Path路径点的坐标追踪功能,类似于一个计算器,可以计算出指定路径的一些信息,比如路径总长、指定长度所对应的坐标点等。

常用方法介绍

  • 初始化
    PathMeasure有两种初始化方式:
 PathMeasure pathMeasure = new PathMeasure();
 setPath(Path path, boolean forceClosed)

初始化pathMeasure后,可以通过调用PathMeasure.setPath()函数来将Path和PathMeasure进行绑定。这样就已经初始化完成了,可以调用pathMeasure来返回路径的相关信息。
也可以通过PathMeasure的另一个构造函数直接完成初始化。

PathMeasure(Path path, boolean forceClosed)

在setPath函数和PathMeasure的第二个构造函数中都有一个参数boolean forceClosed,表示Path最终是否需要闭合,如果问true,则不管关联的Path是否是闭合的,都会被闭合。但是forceClosed参数对绑定的Path不会产生任何影响,例如一个折现段的Path,本身没有闭合,当forceClosed设置为true的时候,PathMeasure计算的Path是闭合的,但Path本身绘制出来的是不会闭合的。

  • getLength函数
public float getLength();

PathMeasure.getLength()函数的作用就是获取计算的路径长度。如果forceClosed为false,则测量的是当前Path状态的长度;如果forceClosed为true,则不论Path是否闭合,测量的都是Path的闭合长度。

  • isClosed函数
public boolean isClosed()

该函数用于判断测量Path时是否计算闭合。所以,如果在关联Path的时候设置forceClosed为true,则这个函数的返回值一定为true。

  • nextContour
    Path可以由多条曲线构成,但不论是getLength、getSegment还是其他函数,都只会针对其中第一条线段进行计算。而nextContour就是用于跳转到下一条曲线的函数。如果跳转成功,则返回true;如果跳转失败,则返回false。通过该函数获取得到的曲线的顺序与Path中添加的顺序相同。

  • getSegment

public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)

这个API用于截取整个Path中的某个片段,通过参数startD和stopD来控制截取的长度,并将截取后的Path保存到参数dst中。最后一个参数startWithMoveTo表示起始点是否使用moveTo将路径的新起始点移到结果Path的起始点,通常设置为true,以保证每次截取的Path都是正常的、完整的,通常和dst一起使用,因为dst中保存的Path是被不断添加的,而不是每次被覆盖的;如果设置为false,则新增的片段会从上一次Path终点开始计算,这样可以保证截取的Path片段是连续的。
注意:1.如果startD、stopD的数值不在取值范围[0,getLength]内,或者在startD==stopD,则返回值为false,而且不会改变dst中的内容。2.开启硬件加速功能后,绘图会出现问题。因此,在使用getSegment函数时需要禁用硬件加速功能。目前可以在自定义View的构造函数中调用setLayerType(LAYER_TYPE_SOFTWARE,null)函数来禁用硬件加速功能。
Android动画进阶
Android动画进阶
Android动画进阶
Android动画进阶

  • getPosTan
    该函数用于得到路径上某一长度的位置以及该位置的正切值。该函数的声明如下:
    public boolean getPosTan(float distance, float pos[], float tan[]) {
        if (pos != null && pos.length < 2 ||
            tan != null && tan.length < 2) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return native_getPosTan(native_instance, distance, pos, tan);
    }
  1. distance:距离Path起始点的长度,取值范围为[0,getLength]
  2. pos:该点的坐标值。当前点在画布上的位置有两个数值,分别为x,y坐标。pos[0]表示x坐标,pos[1]表示y坐标。
  3. tan:该点的正切值。
    Android动画进阶
    Android动画进阶
    Android动画进阶
  • getMatrix
    该函数用于得到路径上某一长度的位置以及该位置的正切值的矩阵。
public boolean getMatrix(float distance, Matrix matrix, int flags) {
        return native_getMatrix(native_instance, distance, matrix.ni(), flags);
    }
  1. distance:距离Path起始点的长度。
  2. matrix:根据flags封装好的matrix会根据flags的设置而存入不同的内容。
  3. flags:用于指定哪些内容会存入matrix中。flags的值有两个:PathMeasure.POSITION_MATRIX_FLAG表示获取位置信息; PathMeasure.TANGENT_MATRIX_FLAG表示获取切边信息,使得图片按Path旋转。可以只指定一个,也可以使用“|”同时指定。
    很明显,getMatrix函数只是getPosTan函数的另一种实现而已。getPosTan函数把获取到的位置信息和切边信息分别保存在pos和tan数组中;而getMatrix函数则直接将其保存到matrix数组中。
  • 案例如下:
package com.mvp.vpnapplication;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class GetPosTanView extends View {
    private Path mCirclePath, mDstPath;
    private Paint mPaint;
    private PathMeasure mPathMeasure;
    private Float mCurAnimValue;
    private Bitmap mArrawBmp;

    public GetPosTanView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mArrawBmp = BitmapFactory.decodeResource(getResources(), R.drawable.arrow_right);//不能时svg类型的图片,拿不到宽高,必须是位图

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(4);
        mPaint.setColor(Color.BLACK);

        mDstPath = new Path();
        mCirclePath = new Path();
        mCirclePath.addCircle(100, 100, 50, Path.Direction.CW);

        mPathMeasure = new PathMeasure(mCirclePath, true);

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurAnimValue = (Float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.setDuration(2000);
        animator.start();
    }

    private float[] pos = new float[2];
    private float[] tan = new float[2];

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);

        float length = mPathMeasure.getLength();
        float stop = length * mCurAnimValue;
        float start = (float) (stop - ((0.5 - Math.abs(mCurAnimValue - 0.5)) * length));

        mDstPath.reset();
        mPathMeasure.getSegment(start, stop, mDstPath, true);
        canvas.drawPath(mDstPath, mPaint);

        //getPosTan方法实现
        //旋转箭头图片,并绘制
        mPathMeasure.getPosTan(stop, pos, tan);
        float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
        Matrix matrix = new Matrix();
        matrix.postRotate(degrees, mArrawBmp.getWidth() / 2, mArrawBmp.getHeight() / 2);
        matrix.postTranslate(pos[0] - mArrawBmp.getWidth() / 2, pos[1] - mArrawBmp.getHeight() / 2);
        canvas.drawBitmap(mArrawBmp, matrix, mPaint);
    }
}

SVG动画

SVG是矢量图,而且是专门用于网络的矢量图形标准。与矢量图相对应的是位图,Bitmap就是位图,它由一个个像素点组成,当图片放大到一定大小时,就会出现马赛克现象。ps就是常用的位图处理软件。而矢量图则由一个个点组成,经过数学计算利用直线和曲线绘制而成,无论如何放大,都不会出现马赛克现象,Illustrator就是常用的矢量图绘图软件。
Android动画进阶
Android动画进阶

vector标签与图像显示

在Android中,SVG矢量图是使用标签定义的,并放在res/drawable目录下。

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000000"
        android:pathData="M19.35,10.04 C18.67,6.59,15.64,4,12,4 C9.11,4,6.6,5.64,5.35,8.04
C2.34,8.36,0,10.91,0,14 C0,17.31,2.69,20,6,20 L19,20 C21.76,20,24,17.76,24,15
C24,12.36,21.95,10.22,19.35,10.04 Z M19,18 L6,18 C3.79,18,2,16.21,2,14
S3.79,10,6,10 L6.71,10 C7.37,7.69,9.48,6,12,6 C15.04,6,17.5,8.46,17.5,11.5
L17.5,12 L19,12 C20.66,12,22,13.34,22,15 S20.66,18,19,18 Z" />
    <path
        android:strokeColor="#000000"
        android:strokeWidth="2"
        android:pathData="M6.58994,13.1803 C6.58994,13.1803,8.59173,15.8724,12.011,15.8726
C15.2788,15.8728,17.3696,13.2502,17.3696,13.2502" />
</vector>
  • width和height属性:表示该SVG图形的具体大小。
  • viewportWidth与viewportHeight属性:表示SVG图形划分的比例。具体理解的是,定义了一张SVG图片,它的宽度和高度分别是24dp和24dp。在这里,width和height类似于指定画布的大小,而viewportWidth与viewportHeight则是指将画布的宽、高分为多少个点,而Path中的点坐标都是以viewportWidth与viewportHeight的点数为坐标的,而不是dp值。很明显,vector标签指定的是画布大小,而path标签指定的是路径内容。
    Android动画进阶
    Android动画进阶
    Android动画进阶
    Android动画进阶
    Android动画进阶
    Android动画进阶

动态Vector

Android动画进阶
Android动画进阶文章来源地址https://www.toymoban.com/news/detail-405895.html

到了这里,关于Android动画进阶的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Activity 动画如何实现

    在 Android 中,你可以使用 Activity 转场动画来实现 Activity 之间的切换动画效果。以下是一些常见的 Activity 转场动画的实现方法: 1. 使用 XML 文件定义动画效果: 首先,在 res/anim 目录下创建 XML 文件来定义你的动画效果。例如,你可以创建 fade_in.xml 和 fade_out.xml 文件来定义淡入

    2024年02月09日
    浏览(49)
  • 全网最全!!Qt实现图片旋转及图片旋转动画的几种方式

    第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: 第二种方案 使用 QPainter 这位“画家”,示例程序如下:  一、借助QPixmap实现旋转动画 第二种方案 使用 QPainter 这位“画家”,示例程序如下:

    2024年02月11日
    浏览(48)
  • Android 实现账号诊断动画效果,逐条检测对应的项目

    Dialog中的项目 逐条检测效果: 依赖库: 1、item_account_check.xml 2、实体类 3、AccountCheckAdapter .kt 4、dialog_account_check.xml 5、AccountCheckDialog.kt 6、使用Dialog:

    2024年02月14日
    浏览(37)
  • 【动画进阶】当路径动画遇到滚动驱动!

    我的小册 《CSS 技术揭秘与实战通关》上线了,想了解更多有趣、进阶、系统化的 CSS 内容,可以猛击 - LINK。 本文,我们将一起利用纯 CSS,实现如下这么个酷炫的效果: 在一年前,我介绍了 CSS 中非常新奇有趣的一个新特性 -- @scroll-timeline :革命性创新,动画杀手锏 @scro

    2024年02月08日
    浏览(38)
  • Three.js 进阶之旅:滚动控制模型动画和相机动画 ?

    声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。 专栏上篇文章《Three.js 进阶之旅:页面*滑滚动-王国之泪》 讲解并实现了如何使用 R3F 进行页面图片*滑滚动,本文内容在上节的基础上,学习

    2024年02月06日
    浏览(52)
  • 【动画进阶】单标签下多色块随机文字随机颜色动画

    我的小册 《CSS 技术揭秘与实战通关》上线了,想了解更多有趣、进阶、系统化的 CSS 内容,可以猛击 - LINK。 在 CSS 还原拉斯维加斯球数字动画 - 掘金 一文中,我们利用纯 CSS,实现了一个非常 Amazing 的动画效果: 其中一个核心点就是,我们利用了如下的代码,在一个 DIV 平

    2024年02月07日
    浏览(42)
  • 20231103-黑马web进阶-动画

    1、定义动画 2、使用动画 3、案例 animation: 动画名称 动画时长 速度曲线 延迟时间 重复次数 动画方向 执行完毕时状态; 注意: ①动画名称和动画时长必须赋值 ②取值不分先后顺序 ③如果有两个时间值,第一个时间表示动画时长,第二个时间表示延迟时间 无限循环:animati

    2024年02月05日
    浏览(34)
  • Flutter开发进阶之动画

    在Flutter中,动画是至关重要的一个部分,它能够为应用程序提供更加丰富和生动的用户体验,Flutter中的动画系统是UI框架的核心功能之一,也是开发者学习Flutter框架的重要部分,由于动画原理在所有程序中都是相同的,即视觉暂留,因此理解这一原理对于更好地使用Flutter的

    2024年01月21日
    浏览(44)
  • 【动画进阶】神奇的背景,生化危机4日食 Loading 动画还原

    最近,在 Steam 玩一款老游戏(生化危机 4 重置版),其中,每当游戏转场的过程中,都有这么一个有趣的 Loading 动画: 整个效果有点类似于 日食效果 ,中间一圈黑色,向外散发着太阳般的光芒。 本文,我们将尝试使用 CSS,还原这个效果。 整个效果做出来,类似于如下两个

    2024年02月08日
    浏览(46)
  • android 窗口级模糊实现方式

    在Android上实现窗口级模糊效果有多种方法,下面列出了其中两种常用的实现方式: RenderScript模糊效果: 使用 ScriptIntrinsicBlur 类在RenderScript中实现模糊效果。 创建一个RenderScript实例并将要模糊的图像传递给它。 创建一个 ScriptIntrinsicBlur 实例并设置模糊的半径。 使用 setInput

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包