Android动画图标——I am not a gif maker,I am a developer

简介: 最早在git上发现一个很酷眩的动画图标效果:https://github.com/xuyisheng/tickplusdrawable不得不说,国外的程序员在细节的考虑上,确实比我们要好很多,ok,今天我们就来模仿下这个:现来看看我们的效果,别喷我,就写了个把小时,很多细节还没考虑全,代码也还没重构,希望大家能提出修改意见,thx~gif效果不一定好,大家可以参考github的gif。

最早在git上发现一个很酷眩的动画图标效果:

https://github.com/xuyisheng/tickplusdrawable


不得不说,国外的程序员在细节的考虑上,确实比我们要好很多,ok,今天我们就来模仿下这个:

现来看看我们的效果,别喷我,就写了个把小时,很多细节还没考虑全,代码也还没重构,希望大家能提出修改意见,thx~


gif效果不一定好,大家可以参考github的gif。




代码如下:


首先我们要来了解下原理:


1、我们首先来确定一些关键点的坐标,也就是我们要显示的图形的所有出现的顶点

2、线条的移动效果,我们使用属性动画来控制,不熟悉的朋友可以看看http://blog.csdn.net/eclipsexys/article/details/38401641,通过这个例子大家应该会对属性动画有更深的理解了

3、对于没有提供get、set方法的属性,我们通过重写Property来帮助这个属性增加get、set方法


了解了以上内容,就可以来看具体的代码了:

package com.example.yishengxu.canvas;

import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by yisheng.xu on 10/30/14.
 */
public class CanvasView extends View {

    private float mPaddingW;
    private float mPaddingH;

    private float mRotation;

    private List<PointF> mAllPoints = new ArrayList<PointF>();

    private PointF mPoint0;
    private PointF mPoint1;
    private PointF mPoint2;
    private PointF mPoint3;
    private PointF mPoint4;
    private PointF mPoint5;
    private PointF mPoint6;
    private PointF mPoint7;

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private int touchFlag = 0;

    public CanvasView(Context context) {
        super(context);
    }

    public CanvasView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mPaddingW = w / 4;
        mPaddingH = h / 4;

        mAllPoints.add(new PointF(mPaddingW, mPaddingH));
        mAllPoints.add(new PointF(mPaddingW * 3, mPaddingH));
        mAllPoints.add(new PointF(mPaddingW, mPaddingH * 2));
        mAllPoints.add(new PointF(mPaddingW * 3, mPaddingH * 2));
        mAllPoints.add(new PointF(mPaddingW, mPaddingH * 3));
        mAllPoints.add(new PointF(mPaddingW * 3, mPaddingH * 3));
        mAllPoints.add(new PointF(mPaddingW * 2, mPaddingH));
        mAllPoints.add(new PointF(mPaddingW * 2, mPaddingH * 3));

        initPoints();

        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(20);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        super.onSizeChanged(w, h, oldw, oldh);
    }

    private void initPoints() {
        mPoint0 = new PointF(mAllPoints.get(0).x, mAllPoints.get(0).y);
        mPoint1 = new PointF(mAllPoints.get(1).x, mAllPoints.get(1).y);
        mPoint2 = new PointF(mAllPoints.get(2).x, mAllPoints.get(2).y);
        mPoint3 = new PointF(mAllPoints.get(3).x, mAllPoints.get(3).y);
        mPoint4 = new PointF(mAllPoints.get(4).x, mAllPoints.get(4).y);
        mPoint5 = new PointF(mAllPoints.get(5).x, mAllPoints.get(5).y);
        mPoint6 = new PointF();
        mPoint7 = new PointF();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.rotate(180 * mRotation, mPaddingW * 2, mPaddingH * 2);
        drawLine(canvas, mPoint0, mPoint1);
        drawLine(canvas, mPoint2, mPoint3);
        drawLine(canvas, mPoint4, mPoint5);
        drawLine(canvas, mPoint6, mPoint7);
        canvas.restore();
    }

    private void drawLine(Canvas canvas,PointF start,PointF end) {
        if (start.x!=0 && end.x !=0) {
            canvas.drawLine(start.x, start.y, end.x, end.y, mPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (touchFlag == 0) {
            animPoints(mPoint0, mAllPoints.get(2));
            animPoints(mPoint4, mAllPoints.get(2));
            animPoints(mPoint1, mAllPoints.get(6));
            animPoints(mPoint5, mAllPoints.get(7));
            touchFlag += 1;
        }else if (touchFlag == 1) {
            resetPoints();
            touchFlag += 1;
        }else if (touchFlag == 2) {
            animPoints(mPoint0, mAllPoints.get(4));
            animPoints(mPoint4, mAllPoints.get(0));
            mPoint2 = new PointF(0, 0);
            mPoint3 = new PointF(0, 0);
            invalidate();
            touchFlag += 1;
        } else if (touchFlag == 3) {
            resetPoints();
            touchFlag += 1;
        } else {
            animPoints(mPoint0, mAllPoints.get(6));
            animPoints(mPoint1, mAllPoints.get(3));
            animPoints(mPoint5, mAllPoints.get(6));
            mPoint2 = new PointF(0, 0);
            mPoint3 = new PointF(0, 0);
            invalidate();
            touchFlag = 1;
        }

        return super.onTouchEvent(event);
    }

    private void resetPoints() {
        animPoints(mPoint0, mAllPoints.get(0));
        animPoints(mPoint1, mAllPoints.get(1));
        animPoints(mPoint2, mAllPoints.get(2));
        animPoints(mPoint3, mAllPoints.get(3));
        animPoints(mPoint4, mAllPoints.get(4));
        animPoints(mPoint5, mAllPoints.get(5));
    }

    private void animPoints(final PointF start, final PointF end) {
        ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
            @Override
            public PointF evaluate(float v, PointF o, PointF o2) {
                start.x = start.x + (end.x - start.x) * v;
                start.y = start.y + (end.y - start.y) * v;
                invalidate();
                return null;
            }
        }, start, end);
        animator.setDuration(1000);
        animator.start();
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, mRotationProperty, 0, 1F);
        animator1.setDuration(500);
        animator1.start();
    }

    private Property<CanvasView, Float> mRotationProperty = new Property<CanvasView, Float>(Float.class, "rotation") {
        @Override
        public Float get(CanvasView object) {
            return object.mRotation;
        }

        @Override
        public void set(CanvasView object, Float value) {
            object.mRotation = value;
        }
    };
}

布局文件和主文件很简单:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="50dp"
    android:paddingRight="50dp"
    android:paddingTop="150dp"
    android:paddingBottom="150dp"
    tools:context=".MainActivity">

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        class="com.example.yishengxu.canvas.CanvasView"
        android:id="@+id/view"
        android:layout_alignParentStart="true" />
</RelativeLayout>

package com.example.yishengxu.canvas;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends Activity {

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

OK,关键还是要有脑子,有idea,在现有知识的基础上,加工、创造。

现在,5.0来了,新增了Vector Drawable,以及对SVG的支持,让我们对实现更复杂的路径轨迹动画效果,有了更强大的工具。


最后,打个广告——友情链接 HZTalk~非常好的,说科技、聊电影、游戏,真独立,非客观,第三方.


以上。



目录
相关文章
|
Android开发 开发者
Android利用SVG实现动画效果
本文介绍了如何在Android中利用SVG实现动画效果。首先通过定义`pathData`参数(如M、L、Z等)绘制一个简单的三角形SVG图形,然后借助`objectAnimator`实现动态的线条绘制动画。文章详细讲解了从配置`build.gradle`支持VectorDrawable,到创建动画文件、关联SVG与动画,最后在Activity中启动动画的完整流程。此外,还提供了SVG绘制原理及工具推荐,帮助开发者更好地理解和应用SVG动画技术。
608 30
|
Android开发 UED 计算机视觉
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
本文介绍了一款受游戏“金铲铲之战”启发的Android自定义View——线条等待动画的实现过程。通过将布局分为10份,利用`onSizeChanged`测量最小长度,并借助画笔绘制动态线条,实现渐变伸缩效果。动画逻辑通过四个变量控制线条的增长与回退,最终形成流畅的等待动画。代码中详细展示了画笔初始化、线条绘制及动画更新的核心步骤,并提供完整源码供参考。此动画适用于加载场景,提升用户体验。
708 5
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
|
API Android开发 开发者
Android颜色渐变动画效果的实现
本文介绍了在Android中实现颜色渐变动画效果的方法,重点讲解了插值器(TypeEvaluator)的使用与自定义。通过Android自带的颜色插值器ArgbEvaluator,可以轻松实现背景色的渐变动画。文章详细分析了ArgbEvaluator的核心代码,并演示了如何利用Color.colorToHSV和Color.HSVToColor方法自定义颜色插值器MyColorEvaluator。最后提供了完整的源码示例,包括ColorGradient视图类和MyColorEvaluator类,帮助开发者更好地理解和应用颜色渐变动画技术。
396 3
|
9月前
|
存储 消息中间件 人工智能
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
555 4
|
9月前
|
XML 存储 Java
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
228 3
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
|
9月前
|
XML 编解码 Android开发
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
740 0
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
|
Android开发 开发者
Android SVG动画详细例子
本文详细讲解了在Android中利用SVG实现动画效果的方法,通过具体例子帮助开发者更好地理解和应用SVG动画。文章首先展示了动画的实现效果,接着回顾了之前的文章链接及常见问题(如属性名大小写错误)。核心内容包括:1) 使用阿里图库获取SVG图形;2) 借助工具将SVG转换为VectorDrawable;3) 为每个路径添加动画绑定属性;4) 创建动画文件并关联SVG;5) 在ImageView中引用动画文件;6) 在Activity中启动动画。文末还提供了完整的代码示例和源码下载链接,方便读者实践操作。
578 65
|
XML Java Maven
Android线条等待动画JMWorkProgress(可添加依赖直接使用)
这是一篇关于Android线条等待动画JMWorkProgress的教程文章,作者计蒙将其代码开源至GitHub,提升可读性。文章介绍了如何通过添加依赖库使用该动画,并详细讲解了XML与Java中的配置方法,包括改变线条颜色、宽度、添加文字等自定义属性。项目已支持直接依赖集成(`implementation &#39;com.github.Yufseven:JMWorkProgress:v1.0&#39;`),开发者可以快速上手实现炫酷的等待动画效果。文末附有GitHub项目地址,欢迎访问并点赞支持!
385 26
|
XML Android开发 数据格式
Android中SlidingDrawer利用透明动画提示效果
本文介绍了在Android中使用`SlidingDrawer`实现带有透明动画提示效果的方法。通过XML布局配置`SlidingDrawer`的把手(handle)和内容(content),结合Activity中的代码实现动态动画效果。最终实现了交互性强、视觉效果良好的滑动抽屉功能。
176 1
Android中SlidingDrawer利用透明动画提示效果
|
Android开发 开发者
Android自定义view之围棋动画(化繁为简)
本文介绍了Android自定义View的动画实现,通过两个案例拓展动态效果。第一个案例基于`drawArc`方法实现单次动画,借助布尔值控制动画流程。第二个案例以围棋动画为例,从简单的小球直线运动到双向变速运动,最终实现循环动画效果。代码结构清晰,逻辑简明,展示了如何化繁为简实现复杂动画,帮助读者拓展动态效果设计思路。文末提供完整源码,适合初学者和进阶开发者学习参考。
230 0
Android自定义view之围棋动画(化繁为简)

热门文章

最新文章