用于做Path动画的自定义View。 I have a path.I have a view. (Oh~),Path(Anim)View.

Related tags

UI/UX PathAnimView
Overview

PathAnimView

用于做Path动画的自定义View。

I have a path.I have a view. (Oh~),Path(Anim)View.

现已经找到图片->SVG->PATH的正确姿势,

Now i have a pic.I have a view. Oh~,Path(Anim)View.

相关博文:

实现详解:

http://blog.csdn.net/zxt0601/article/details/53040506

图片->SVG->Path的正确姿势 ,用法进阶:

http://blog.csdn.net/zxt0601/article/details/54018970

使用:

Step 1. 在项目根build.gradle文件中增加JitPack仓库依赖。

    allprojects {
		repositories {
			...
			maven { url "https://jitpack.io" }
		}
	}

Step 2. Add the dependency

	dependencies {
	        compile 'com.github.mcxtzhang:PathAnimView:V1.0.0'
	}

一 概述

原本只是想模仿一下我魂牵梦萦的StoreHouse效果,没想到意外撸出来一个工具库。

最简单用法,给我一个path,我还你一个动画。

I have a path.I have a view. (Oh~),Path(Anim)View.

    <com.mcxtzhang.pathanimlib.PathAnimView
        android:id="@+id/pathAnimView1"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:background="@color/blue"
        android:padding="5dp"/>
    Path sPath = new Path();
    sPath.moveTo(0, 0);
    sPath.addCircle(40, 40, 30, Path.Direction.CW);
    pathAnimView1.setSourcePath(sPath);

先看效果图:(真机效果很棒哦,我自己的手机是去年某款599的手机,算是低端的了,6个View一起动画,不会卡,查看GPU呈现模式,95%时间都处于16ms线以下。性能还可以的)

其中 图1 是普通逐渐填充的效果,无限循环。 图2 是仿StoreHouse 残影流动效果。(但与原版并不是完全一模一样,估计原版不是用Path做的) 图3 是逐渐填充的效果,设置了只执行一次。 图4 是仿StoreHouse效果。数据源来自R.array.xxxx 图5 是另一种自定义PathAnimHelper实现的自定义动画效果。类似Android L+ 系统进度条效果。 图6 是仿StoreHouse效果,但是将动画时长设置的很大,所以能看到它逐渐的过程。


2017 01 05 更新:

I have a pic.I have a view. Oh~,Path(Anim)View. 效果先随便上几个图,以后你找到的图有多精彩,gif就有多精彩

随便搜了一个铅笔画的图,丢进去

支付成功动画

随手复制的二维码icon

来自大佬wing的铁塔


StoneHouse效果如下简单使用:

    <com.mcxtzhang.pathanimlib.StoreHouseAnimView
        android:id="@+id/pathAnimView1"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:background="@android:color/black"
        android:padding="5dp"/>
        pathAnimView1 = (StoreHouseAnimView) findViewById(R.id.pathAnimView1);
        Path sPath = new Path();
        sPath.moveTo(0, 0);
        sPath.addCircle(40, 40, 30, Path.Direction.CW);
        pathAnimView1.setSourcePath(PathParserUtils.getPathFromArrayFloatList(StoreHousePath.getPath("McXtZhang")));
        pathAnimView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pathAnimView1.startAnim();
            }
        });

参数

目前可配参数: 1 绘制方面,支持绘制Path的前景 背景色。

    //设置颜色
    fillView2.setColorBg(Color.WHITE).setColorFg(Color.BLACK);

2 动画方面,目前支持设置动画的时长,是否无限循环等。

    //设置了动画总时长,只执行一次的动画
    fillView2.setAnimTime(3000).setAnimInfinite(false).startAnim();

3 仿StoreHouse风格的View,还支持设置残影的长度

//设动画时长,设置了stoneHouse残影长度
    storeView3.setPathMaxLength(1200).setAnimTime(20000).startAnim();

4 当然你可以拿到Paint自己搞事情:

    //当然你可以自己拿到Paint,然后搞事情,我这里设置线条宽度
    pathAnimView1.getPaint().setStrokeWidth(10);

数据源:

PathAnimView的数据源是Path。(给我一个Path,还你一个动画View) 所以内置了几种将别的资源->Path的方法。 1 直接传string。 StoreHouse风格支持的A-Z,0-9 "." "- " " "(源自百万大神的库文末也有鸣谢,)

    //根据String 转化成Path
    setSourcePath(PathParserUtils.getPathFromArrayFloatList(StoreHousePath.getPath("ZhangXuTong", 1.1f, 16)));

2 定义在R.array.xxx里

    //动态设置 从StringArray里取
    storeView2.setSourcePath(PathParserUtils.getPathFromStringArray(this, R.array.storehouse, 3));

3 简单的SVG(半成品) 以前从gayHub上找了一个SVG-PATH的转换类:SvgPathParser,现在派上了用场,简单的SVG-PATH,可以,复杂的还有问题,还需要继续寻找更加方案。

        //SVG转-》path
        //还在完善中,我从github上找了如下工具类,发现简单的SVG可以转path,复杂点的 就乱了
/*        SvgPathParser svgPathParser = new SvgPathParser();
        try {
            Path path = svgPathParser.parsePath("M1,1 L1,50 L50,50 L50,50 L50,1 Z");
            storeView3.setSourcePath(path);
        } catch (ParseException e) {
            e.printStackTrace();
        }*/

简单用法API

1 xml定义

普通PathAnimView 效果如图1 3。动画是 进度填充直到满的效果。

    <com.mcxtzhang.pathanimlib.PathAnimView
        android:id="@+id/pathAnimView1"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:background="@color/blue"
        android:padding="5dp"/>

高仿StoreHouse风格AnimView: 这种View显示出来的效果如图2 4 6 。动画是 残影流动的效果。

    <com.mcxtzhang.pathanimlib.StoreHouseAnimView
        android:id="@+id/storeView3"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:background="@android:color/black"
        android:padding="5dp"/>

2 开始动画

    fillView1.startAnim();

3 停止动画

    fillView1.stopAnim();

4 清除并停止动画

    fillView1.clearAnim();

稍微 搞基 高级点的用法预览

看到这里细心的朋友可能会发现,上一节,我没有提第5个图View是怎么定义的, 而且第五个View的效果,貌似和其他的不一样,仔细看动画是不是像Android L+的系统自带进度条ProgressBar的效果? 那说明它的动画效果和我先前提到的两种不一样,是的,一开始我撸是照着StoreHouse那种效果撸的,这是我第二天才扩展的。 高级的用法,就是本控件动画的扩展性。 你完全可以通过继承PathAnimHelper类,重写onPathAnimCallback()方法,扩展动画,图5就是这么来的。 先讲用法预览,稍后章节会详解。 用法: 对任意一个普通的PathAnimView,设置一个自定义的PathAnimHelper类即可:

        //代码示例 动态对path加工,通过Helper
        pathAnimView1.setPathAnimHelper(new CstSysLoadAnimHelper(pathAnimView1, pathAnimView1.getSourcePath(), pathAnimView1.getAnimPath()));

自定义的PathAnimHelper类:

/**
 * 介绍:自定义的PathAnimHelper,实现类似Android L+ 进度条效果
 * 作者:zhangxutong
 * 邮箱:[email protected]
 * 时间: 2016/11/3.
 */

public class CstSysLoadAnimHelper extends PathAnimHelper {
    public CstSysLoadAnimHelper(View view, Path sourcePath, Path animPath) {
        super(view, sourcePath, animPath);
    }

    public CstSysLoadAnimHelper(View view, Path sourcePath, Path animPath, long animTime, boolean isInfinite) {
        super(view, sourcePath, animPath, animTime, isInfinite);
    }

    @Override
    public void onPathAnimCallback(View view, Path sourcePath, Path animPath, PathMeasure pathMeasure, ValueAnimator animation) {
        float value = (float) animation.getAnimatedValue();
        //获取一个段落
        float end = pathMeasure.getLength() * value;
        float begin = (float) (end - ((0.5 - Math.abs(value - 0.5)) * pathMeasure.getLength()));
        animPath.reset();
        animPath.lineTo(0, 0);
        pathMeasure.getSegment(begin, end, animPath, true);
    }
}

二 逐个介绍

这里我简单画了一下本文介绍的几个类的类图: 对于重要方法和属性标注了一下。

我们的主角PathAnimView继承自View,是一个自定义View。 它内部持有一个PathAnimHelper,专注做Path动画。它默认的实现是 逐渐填充 的动画效果。

一般情况下只需要更换PathAnimHelper,PathAnimView即可做出不同的动画。(图1第5个View)

但是如果需要扩充一些动画属性供用户设置,例如仿StoreHouse风格的动画View,想暴露 残影长度 属性供设置。 我这里采用的是:继承自PathAnimView,并增加属性get、set 方法,并重写getInitAnimHeper()方法,返回自定义的PathAnimHelper。 如StoreHouseAnimView继承自PathAnimView,增加了残影长度的get、set方法。并重写getInitAnimHeper()方法,返回StoreHouseAnimHelper对象。 StoreHouseAnimHelper类继承的是PathAnimHelper

先看PathAnimView: 这里我将一些不重要的get、set方法和构造方法剔除,留下比较重要的方法。

/**
 * 介绍:一个路径动画的View
 * 利用源Path绘制“底”
 * 利用动画Path 绘制 填充动画
 * <p>
 * 一个SourcePath 内含多段Path,循环取出每段Path,并做一个动画,
 * <p>
 * 作者:zhangxutong
 * 邮箱:[email protected]
 * 时间: 2016/11/2.
 */

public class PathAnimView extends View {
    protected Path mSourcePath;//需要做动画的源Path
    protected Path mAnimPath;//用于绘制动画的Path
    protected Paint mPaint;
    protected int mColorBg = Color.GRAY;//背景色
    protected int mColorFg = Color.WHITE;//前景色 填充色
    protected PathAnimHelper mPathAnimHelper;//Path动画工具类

    protected int mPaddingLeft, mPaddingTop;

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

    /**
     * 这个方法可能会经常用到,用于设置源Path
     *
     * @param sourcePath
     * @return
     */
    public PathAnimView setSourcePath(Path sourcePath) {
        mSourcePath = sourcePath;
        initAnimHelper();
        return this;
    }

    /**
     * INIT FUNC
     **/
    protected void init() {
        //Paint
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);

        //动画路径只要初始化即可
        mAnimPath = new Path();

        //初始化动画帮助类
        initAnimHelper();

    }

    /**
     * 初始化动画帮助类
     */
    protected void initAnimHelper() {
        mPathAnimHelper = getInitAnimHeper();
        //mPathAnimHelper = new PathAnimHelper(this, mSourcePath, mAnimPath, 1500, true);
    }

    /**
     * 子类可通过重写这个方法,返回自定义的AnimHelper
     *
     * @return
     */
    protected PathAnimHelper getInitAnimHeper() {
        return new PathAnimHelper(this, mSourcePath, mAnimPath);
    }

    /**
     * draw FUNC
     **/
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移
        canvas.translate(mPaddingLeft, mPaddingTop);

        mPaint.setColor(mColorBg);
        canvas.drawPath(mSourcePath, mPaint);


        mPaint.setColor(mColorFg);
        canvas.drawPath(mAnimPath, mPaint);
    }

    /**
     * 设置动画 循环
     */
    public PathAnimView setAnimInfinite(boolean infinite) {
        mPathAnimHelper.setInfinite(infinite);
        return this;
    }

    /**
     * 设置动画 总时长
     */
    public PathAnimView setAnimTime(long animTime) {
        mPathAnimHelper.setAnimTime(animTime);
        return this;
    }

    /**
     * 执行循环动画
     */
    public void startAnim() {
        mPathAnimHelper.startAnim();
    }

    /**
     * 停止动画
     */
    public void stopAnim() {
        mPathAnimHelper.stopAnim();
    }

    /**
     * 清除并停止动画
     */
    public void clearAnim() {
        stopAnim();
        mAnimPath.reset();
        mAnimPath.lineTo(0, 0);
        invalidate();
    }
}

代码本身不难,注释也比较详细,核心的话,就是onDraw()方法咯: 我这里用平移做的paddingLeft、paddingTop。 先利用源Path绘制底边的样子。 再利用animPath绘制前景,这样animPath不断变化,并且重绘View->onDraw(),前景就会不断变化,形成动画效果。 那么核心就是animPath的的变化了,animPath的变化交由 mPathAnimHelper去做。

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移
        canvas.translate(mPaddingLeft, mPaddingTop);
        
        //先绘制底,
        mPaint.setColor(mColorBg);
        canvas.drawPath(mSourcePath, mPaint);
        
        //再绘制前景,mAnimPath不断变化,不断重绘View的话,就会有动画效果。
        mPaint.setColor(mColorFg);
        canvas.drawPath(mAnimPath, mPaint);
    }
You might also like...
Provides 9-patch based drop shadow for view elements. Works on API level 9 or later.
Provides 9-patch based drop shadow for view elements. Works on API level 9 or later.

Material Shadow 9-Patch This library provides 9-patch based drop shadow for view elements. Works on API level 14 or later. Target platforms API level

Snake View is a simple and animated linear chart for Android.
Snake View is a simple and animated linear chart for Android.

Snake View Snake library is a simple and animation line chart for Android. Latest Version How to use Configuring your project dependencies Add the lib

Helper class to make any view rotatable
Helper class to make any view rotatable

Rotatable This is a helper class actually, it simplifies having a view as rotatable by setting touch events and handling a lot of boilerplate works! S

(Deprecated) A custom view component that mimics the new Material Design Bottom Navigation pattern.
(Deprecated) A custom view component that mimics the new Material Design Bottom Navigation pattern.

BottomBar (Deprecated) I don't have time to maintain this anymore. I basically wrote the whole library in a rush, without tests, while being a serious

[] A simple way to
[] A simple way to "badge" any given Android view at runtime without having to cater for it in layout

Android ViewBadger A simple way to "badge" any given Android view at runtime without having to cater for it in layout. Note: If your aim is to replica

A horizontal view scroller library for Android
A horizontal view scroller library for Android

View Flow for Android ViewFlow is an Android UI widget providing a horizontally scrollable ViewGroup with items populated from an Adapter. Scroll down

TourGuide is an Android library that aims to provide an easy way to add pointers with animations over a desired Android View

TourGuide TourGuide is an Android library. It lets you add pointer, overlay and tooltip easily, guiding users on how to use your app. Refer to the exa

A cool Open Source CoverFlow view for Android with several fancy effects.
A cool Open Source CoverFlow view for Android with several fancy effects.

FancyCoverFlow THIS PROJECT IS NO LONGER MAINTAINED! What is FancyCoverFlow? FancyCoverFlow is a flexible Android widget providing out of the box view

A simple, customizable and easy to use swipeable view stack for Android.
A simple, customizable and easy to use swipeable view stack for Android.

SwipeStack A simple, customizable and easy to use swipeable view stack for Android. QuickStart Include the Gradle dependency dependencies { compil

Comments
  • 考虑添加动画监听回调

    考虑添加动画监听回调

    动画状态监听可以在 动画不同状态(onAnimationStart, onAnimationEnd)开始其他逻辑,这在动画使用中非常普遍。

    例子中有个PathAnimView设置PathAnimHelper实现类的做法,可以添加Listener,但当PathAnimView的实现类Path值为 PathParserUtils.getPathFromArrayFloatList(StoreHousePath.getPath(""))时,该方法不可用。

    最后使用如下方式实现:

    private Animator.AnimatorListener animatorListener = new Animator.AnimatorListener() {
    
            @Override
            public void onAnimationStart(Animator animator) {
    
            }
    
            @Override
            public void onAnimationEnd(Animator animator) {
    
            }
    
            @Override
            public void onAnimationCancel(Animator animator) {
    
            }
    
            @Override
            public void onAnimationRepeat(Animator animator) {
                // TODO 下一步操作
            }
        };
    
        private void initAnimView(){
            fillView = findViewById(R.id.fillView);
            // 获取并设置Path
            Path sourcePath = PathParserUtils.getPathFromArrayFloatList(StoreHousePath.getPath("Thank you mcxzhang"));
            fillView.setSourcePath(sourcePath);
            fillView.setAnimTime(1500).setAnimInfinite(true);
            // 设置颜色
            fillView.setColorBg(Color.WHITE).setColorFg(Color.YELLOW);
            fillView.startAnim();
            // 获取Helper并添加动画监听器
            PathAnimHelper helper = fillView.getPathAnimHelper();
            helper.getAnimator().addListener(animatorListener);
        }
    
    

    实现思路:

    startAnim() 后获取helper添加Listener,因为在startAnim()之前helper.getAnimator值为空,看完源码可以理解。

    如果mcxzhang抛出个接口的话,实现这个功能可能就是几行代码。

    opened by lufengdie 1
TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.

This project isn't maintained anymore. It is now recommended to use https://github.com/peterLaurence/MapView. MapView is maintained by Peter, one of o

Mike Dunn 1.5k Dec 29, 2022
Android-ScrollBarPanel allows to attach a View to a scroll indicator like it's done in Path 2.0

Path 2.0 like ScrollBarPanel for Android Android-ScrollBarPanel allows to attach a View to a scroll indicator like it's done in Path 2.0. Features Sup

Arnaud Vallat 551 Dec 22, 2022
Path like scrollbar panel with clock.

ScrollBarPanelWithClock Path 2.0 like scrollbar with clock widget for Android. This is an open source library which uses the scroll bar library. I hav

learnNcode 170 Feb 20, 2021
An Android application which visualizes some of the famous Algorithms for finding path from Source to Destination in a 2D grid.

Pathfinding-Visualizer An Android application which visualizes some of the famous Algorithms for finding path from Source to destination in a 2D grid.

Pranjal Mishra 37 Aug 8, 2022
Highly customizable SlidingLayer as you have seen in Wunderlist

6Wunderkinder SlidingLayer for Android This repository hosts a library that provides an easy way to include an autonomous layer/view that slides from

Microsoft Archive 942 Nov 28, 2022
Highly customizable SlidingLayer as you have seen in Wunderlist

6Wunderkinder SlidingLayer for Android This repository hosts a library that provides an easy way to include an autonomous layer/view that slides from

Microsoft Archive 942 Nov 28, 2022
Have a look at Job Allocation app build with SQLite database and Kotlin support

Job Allocation Overview Do you remember or forget sometimes to whom you allocated a task ?? Have a look at Job Allocation app build with SQLite databa

null 0 Dec 13, 2021
FloatingView can make the target view floating above the anchor view with cool animation

FloatingView FloatingView can make the target view floating above the anchor view with cool animation Links 中文版 README Blog about FloatingView demo.ap

UFreedom 1.8k Dec 27, 2022
Android View for displaying and selecting values in a circle-shaped View, with animations and touch gestures.

CircleDisplay Android View for displaying and selecting (by touch) values / percentages in a circle-shaped View, with animations. Features Core featur

Philipp Jahoda 287 Nov 18, 2022
A view that allows to paint and saves the result as a bitmap

Android Drawable View Sample app: An Android view that allows to paint with a finger in the screen and saves the result as a Bitmap. Importing to your

Christian Panadero 581 Dec 13, 2022