关闭

Android动画之旅(三)----6个小球移动的轨迹动画

标签: android动画
1796人阅读 评论(0) 收藏 举报
分类:

6个小球移动的轨迹动画

动画组成:

1.贝塞尔曲线和PathMeasure结合使用。

2. mPathMeasure.getPosTan(float v,float [] pos ,float[] tan)的使用。

3.通过动画01形成轨迹动画。
package com.example.administrator.animationworkdemo.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

/**
 * Created by SuperD on 2017/2/18.
 * 小球加载的运动轨迹
 */

public class BallLoadingPathView extends View implements View.OnClickListener {
    private static final int POINT_DISTANCE = 50;
    private static final int ANIM_RUNNING_TIME = 1000;

    //小球相关的描述
    private int mPointCount = 6;
    private int mPointRadius = 20;

    //中心点
    private int centerX;
    private int centerY;
    //首尾点之前的长度(加上隐藏的那个点,实际上有7个点)
    private float mWidth;

    //起始点,结束点
    private float mPointStartX;
    private float mPointEndX;
    private float mPointY;

    //绘制路径
    private PathMeasure mPathMeasure;
    //储存在路径移动过程中的点
    private float[] mPos = new float[2];
    private Path mPath;
    private float mPathLength;
    //轨迹动画的比率
    private float mPathRatio;

    private Paint mPaint;

    private ValueAnimator mPathAnim;


    //小球运动的标签  True的时候mPointFlag--向下 False的时候mPointFlag--- 向上
    private int mPointFlag = 1;


    public BallLoadingPathView(Context context) {
        this(context, null);
    }

    public BallLoadingPathView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BallLoadingPathView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPathMeasure = new PathMeasure();
        mPath = new Path();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStrokeWidth(5);

        mPathAnim = ValueAnimator.ofFloat(0, 1);
        mPathAnim.setDuration(ANIM_RUNNING_TIME);
        mPathAnim.setRepeatCount(ValueAnimator.INFINITE);
        mPathAnim.setInterpolator(new DecelerateInterpolator());
        mPathAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mPathRatio = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mPathAnim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationRepeat(Animator animation) {
                super.onAnimationRepeat(animation);
                mPointFlag = -mPointFlag;
            }
        });
        setOnClickListener(this);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        centerX = w / 2;
        centerY = h / 2;
        mWidth = (mPointCount - 1) * mPointRadius * 2 + (mPointCount - 1) * POINT_DISTANCE;
        mPointStartX = centerX - mWidth / 2;
        mPointEndX = centerX + mWidth / 2;
        mPointY = centerY;
        mPath.moveTo(mPointStartX, mPointY);
        mPath.quadTo(centerX, centerY + mWidth / 2, mPointEndX, mPointY);
        mPathMeasure.setPath(mPath, false);
        mPathLength = mPathMeasure.getLength();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mPointCount; i++) {
            if (i == 0) {
                mPathMeasure.getPosTan(mPathRatio * mPathLength, mPos, null);
                if (mPointFlag == 1) {
                    canvas.drawCircle(mPos[0], mPos[1], mPointRadius, mPaint);
                } else {
                    canvas.drawCircle(mPos[0], getSymmetryPointY(mPos[1]), mPointRadius, mPaint);
                }
            } else {
                float startPoint = mPointStartX + (POINT_DISTANCE + 2 * mPointRadius) * i;
                canvas.drawCircle(
                        startPoint - (POINT_DISTANCE + 2 * mPointRadius) * mPathRatio,
                        mPointY,
                        mPointRadius, mPaint);
            }
        }
    }

    /**
     * 获得当前Y坐标关于屏幕中心Y轴的对称点
     *
     * @param pointY
     * @return
     */
    private float getSymmetryPointY(float pointY) {
        float symmetryPointY = 2 * centerY - pointY;
        return symmetryPointY;
    }

    @Override
    public void onClick(View view) {
        mPathAnim.start();
    }
}
2
0
查看评论

Android 属性动画:实现小球坠落

一、要做什么项目需要实现的效果:小球坠落 1. 首先绘制小球--自定义View 绘制圆; 2. 模拟小球坠落--属性动画,重绘小球轨迹; 3. 修改小球颜色--实现自定义TypeEvaluator; 实现的简单效果如下:二、思考怎么做实现步骤如下:1、自定义 AnimPointView:/**...
  • happy_horse
  • happy_horse
  • 2017-03-21 20:46
  • 1456

Android利用vectordrawable实现轨迹动画

Google终于在Android5.0中引入了矢量图,矢量图的特点很多,比如不管怎么放大都不会变形,大小也比png小很多,而且利用矢量图我们可以很简单的实现一些看似很复杂的动画效果 虽然动画看着挺复杂,但有了vectordrawable,建3个xml文件就能实现这种效果 第一步: 更改a...
  • u012835548
  • u012835548
  • 2016-12-14 15:20
  • 1600

Android Animation实现元素在屏幕上按照指定轨迹运动,以及出现NullPointerException的解决方案

因项目需要,在Android中实现了一个动画,当在Activity中点击特定按钮时,会在屏幕上添加一个ImageView,并按照指定的起点、终点,沿着特定的轨迹运动(例如直线)。 实现方法 实现思路是在Activity的DecorView中添加一个FrameLayout,然后在FrameLayo...
  • jzj1993
  • jzj1993
  • 2015-11-19 14:19
  • 1273

自定义控件-绕着圆形轨迹旋转的小球

一. 概述用过华为手机的人应该知道华为手机系统应用中的加载动画是一个小球绕着圆圈旋转,之前有一个项目用过类似的功能,所以写了一个自定义的控件,记录一下。希望能给需要这个功能的同志们提供一些思路。先上效果图: 二. 思路我们分析一下,一个小球绕着圆运动,首先需要一个小球,那么自定义控件绘制一个小球。...
  • xingxing_yan
  • xingxing_yan
  • 2017-01-25 16:16
  • 2503

Android 动画--使用Path来规划动画的轨迹

使用Path来规划动画的轨迹 public void testPathAnimator(){ final FrameLayout l = (FrameLayout) findViewById(R.id.root_view); final ImageView ima...
  • heqiangflytosky
  • heqiangflytosky
  • 2016-07-11 10:35
  • 5512

【第1165期】H5动画:轨迹移动

前言前一段时间被各种H5总结刷屏,除了内容以及设计之外在动画方面在其表现方面也起到了很大的加持作用,渐渐的动画也成为了一个产品所不可缺少的一个元素。2017年1月11号早读文章由凹凸实验室@Avin授权分享。正文从这开始~动画,是指由许多帧静止的画面,以一定的速度(如每秒16张)连续播放时,肉眼因视...
  • wGL3k77y9fR1k61T1aS
  • wGL3k77y9fR1k61T1aS
  • 2018-01-10 00:00
  • 452

属性动画实现控件类似贝塞尔曲线轨迹移动效果

前段时间工作中需要实现一种控件类似贝塞尔曲线轨迹运动的效果,也是折腾了几天,刚开始本着不重复造轮子的想法,去网上搜类似的效果,结果没搜到,后来自己实现了,抽成一个Demo,希望有需要的朋友以后可以直接用到而不用再折腾。 关于贝塞尔曲线的概念可以移步到这儿贝塞尔曲线的介绍 。 原理其实很简单,...
  • zqdnurese
  • zqdnurese
  • 2016-04-17 16:40
  • 831

安卓动画系列之属性动画实现跳起落下圆圈运动

最近看了淘宝手机端的有些页面是类似下面这个小球的加载效果。后来了解了下,淘宝是直接一个gif图片实现效果的,这当然是最简单的方法。为了加深了解属性动画,这次就做个类似的效果。这依旧由几个简单的属性动画组合在一起,所有动画都在代码里实现了。看注释就好。 上个效果图: 实现代...
  • stzy00
  • stzy00
  • 2015-03-22 23:14
  • 1129

Android动画之旅(二)----两个小球旋转的动画,形成视觉差的效果

第二个 两个小球旋转的动画,形成视觉差的效果动画组成:主要是左右两个小球的位移和体积变化动画.1.要利用ObjectAnimator的target,target可以是控件,也可以是类,只要包装类存在需要你动画改变的方法. package com.example.administrator.anima...
  • l540675759
  • l540675759
  • 2017-02-28 16:56
  • 555

css3做圆形轨迹移动动画

css3圆形轨迹动画 @keyframes animX{ 0% {left: 0px;} 100% {left: 500px;} } @keyframes animY{ 0% {top: 0px;} 100% {top: 500px;} } #ball { width: 20...
  • jslang
  • jslang
  • 2016-09-30 14:19
  • 4348
    个人资料
    • 访问:62666次
    • 积分:1243
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:0篇
    • 译文:3篇
    • 评论:123条
    博客专栏