Giter VIP home page Giter VIP logo

animationshare's Introduction

动画总结demo

#细说Android动画#

动画感觉说白了就是一句话
在触发范围内 循环的修改view特点后 使view重新绘制 展示新的效果

所以只要有满足三个条件就能完成一个效果

  • 触发范围

比如给个时间 在范围内做个事,或者是给个滑动距离 手指在范围内跟随滑动做个事。

  • 能改变一个值

比如View基本属性 或者布局的某个属性,或者自己写的某个效果 画个水波,翻页,做个扩散

  • 循环触发绘制

只要能循环触发 View.invalidate就可以了

触发条件 范围 一般都是产品,交互给定的,触发绘制是系统的, 所以关键是 怎么去改好这个值


##属性动画## 要说属性动画必须提到 nineOld( JakeWharton 大牛作品)。nineOld和Android系统里面的类 名称,功能也一样,所以使用起来 没啥区别。同事还支持3.0以下版本的,还提供了ViewHelper支持通过set,get方法修改View基本属性。(3.0以上 可以支持set get方法去修改)

###基本使用###

  1. 最简单写法

  1. 支持的基本属性 可以在 nineOld源码中得 ObjectAnimator 查看支持的属性

  1. viewHelper支持低版本 可以直接set,get操作VIEW属性

  2. AnimatorSet 控制多个动画设置执行顺序

 AnimatorSet  animation = new AnimatorSet();
 1 animation.playTogether(AA,BB); 
 2 animation.playSequentially(AA,BB);
 3 animation.play(AA).with(BB).after(CC).before(DD);

代码块1 同时执行AA和BB

代码块2 线性执行AA和BB

代码块3 自己构建执行顺序

  1. 一个view多个属性同时变化完成动画
  • PropertyValuesHolder使用

PropertyValuesHolder.ofFloat("width", A,B;

PropertyValuesHolder.ofFloat("height", c,D);

通过objectAnimator的 PropertyValues借口实现多个属性同时修改
ObjectAnimator.ofPropertyValuesHolder(view, PropertyValuesHolder... )


  • ViewPropertyAnimator.animate连缀写

    左右翻转着 平移到(A,B)

 ViewPropertyAnimator.animate(view).rotationYBy(720).x(xValue).y(yValue)

###nineOld实现原理及其自定义实现###

  1. 自定义实现 demo挤出效果

有时候完成一个效果 已经不是view基本属性的范围 就需要自定义一个“属性”。

例如 做一个挤出 收回 VIEW的动画 需要动态调整属性是 布局属性 layout_marginBottom

自定属性包含三部分

  • viewHolder 被操作的VIEW

  • dataHolder 要操作的数据

  • Evaluator 数据怎么变

  1. nineOld怎么改值 怎么实现的
  • API 11以上 通过反射修改

    核心类 PropertyValuesHolder

    PropertyValuesHolder来反射修改属性值 最关键的 是获取方法

     private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) {
        // TODO: faster implementation...
        Method returnVal = null;
        String methodName = getMethodName(prefix, mPropertyName);
        Class args[] = null;
        if (valueType == null) {
            try {
                returnVal = targetClass.getMethod(methodName, args);
            } catch (NoSuchMethodException e) {
                /* The native implementation uses JNI to do reflection, which allows access to private methods.
                 * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
                 */
                try {
                    returnVal = targetClass.getDeclaredMethod(methodName, args);
                    returnVal.setAccessible(true);
                } catch (NoSuchMethodException e2) {
                    Log.e("PropertyValuesHolder",
                            "Couldn't find no-arg method for property " + mPropertyName + ": " + e);
                }
            }
        } else {
            args = new Class[1];
            Class typeVariants[];
            if (mValueType.equals(Float.class)) {
                typeVariants = FLOAT_VARIANTS;
            } else if (mValueType.equals(Integer.class)) {
                typeVariants = INTEGER_VARIANTS;
            } else if (mValueType.equals(Double.class)) {
                typeVariants = DOUBLE_VARIANTS;
            } else {
                typeVariants = new Class[1];
                typeVariants[0] = mValueType;
            }
            for (Class typeVariant : typeVariants) {
                args[0] = typeVariant;
                try {
                    returnVal = targetClass.getMethod(methodName, args);
                    // change the value type to suit
                    mValueType = typeVariant;
                    return returnVal;
                } catch (NoSuchMethodException e) {
                    /* The native implementation uses JNI to do reflection, which allows access to private methods.
                     * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
                     */
                    try {
                        returnVal = targetClass.getDeclaredMethod(methodName, args);
                        returnVal.setAccessible(true);
                        // change the value type to suit
                        mValueType = typeVariant;
                        return returnVal;
                    } catch (NoSuchMethodException e2) {
                        // Swallow the error and keep trying other variants
                    }
                }
            }
            // If we got here, then no appropriate function was found
            Log.e("PropertyValuesHolder",
                    "Couldn't find setter/getter for property " + mPropertyName +
                            " with value type "+ mValueType);
        }
    
        return returnVal;
    }
    
    
  • API 11以下 view矩阵变化

    核心类 AnimatorProxy

    AnimatorProxy矩阵变换

      private void transformMatrix(Matrix m, View view) {
         final float w = view.getWidth();
         final float h = view.getHeight();
         final boolean hasPivot = mHasPivot;
         final float pX = hasPivot ? mPivotX : w / 2f;
         final float pY = hasPivot ? mPivotY : h / 2f;
    
         final float rX = mRotationX;
         final float rY = mRotationY;
         final float rZ = mRotationZ;
         if ((rX != 0) || (rY != 0) || (rZ != 0)) {
             final Camera camera = mCamera;
             camera.save();
             camera.rotateX(rX);
             camera.rotateY(rY);
             camera.rotateZ(-rZ);
             camera.getMatrix(m);
             camera.restore();
             m.preTranslate(-pX, -pY);
             m.postTranslate(pX, pY);
         }
    
         final float sX = mScaleX;
         final float sY = mScaleY;
         if ((sX != 1.0f) || (sY != 1.0f)) {
             m.postScale(sX, sY);
             final float sPX = -(pX / w) * ((sX * w) - w);
             final float sPY = -(pY / h) * ((sY * h) - h);
             m.postTranslate(sPX, sPY);
         }
    
         m.postTranslate(mTranslationX, mTranslationY);
     }
     
    
  1. 触发绘制

    关键类 ValueAnimator

    关键方法 animationFrame 控制run

    关键方法 handleMessage 处理一些状态 start stop

###组合使用 flyRefrsh ###

flyRefrsh 使用系统属性动画来组合做出来的 没有使用nineOld做低版本支持,拿来主要看组合使用。

github项目地址 传送门

实现分析传送门


##自定义动画##

我们也可以像Android官方提供动画一样 自己去复写一个类似于ScaleAnimation一样

主要方法

  • applyTransformation 实现动画的效果变化(官方都是改矩阵 也可以改其他)
  • initialize 初始化数据

###对于属性操作###

demo挤出效果 自定义动画实现

ObjectAnimation 关键方法


 @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float temp = startValue + (endValue - startValue) * interpolatedTime;
        if (temp != value) {
            value = temp;
            if(onInvalidateImp != null){
                onInvalidateImp.onInvalidate(view,value);
            }
            view.invalidate();
        }
        //super.applyTransformation(interpolatedTime,t);
    }
    

在实现效果方法里面 丢出借口 onInvalidate(view,value),外部使用中间量 实现对应效果(改属性或者改矩阵)

关于动画绘制过程 有哪些方法 都是干什么的 可以关注啊下

android 动画执行流程分析 传送门

###复写draw实现###

说到draw就必须说这三个类

最关键类 canvas画布 paint画笔 matrix矩阵

  • canvas 整体性操作 类型 翻转,平移,缩放,扭曲,裁剪

canvas操作中 不受到其他操作影响 一定要 save()、restore()

  • paint 效果细节 颜色,粗细,重叠方式,空实心等 比较多写不过来

  • matrix 存储view基本特征属性(位置,大小,2D/3D旋转角度,倾斜角度)

可以通过修改这些属性实现效果

可以百度下 很多基础功能类介绍,

对于3D翻转,使用camera构建一个矩阵添加到画布上去 类似于nineOld中对于API 11以下版本实现方式

demo简单出票

主要完成一个画布的裁剪 实现一个“吐出来”效果 有使用一些动画上 原有功能 RepeatCount RepeatMode 实现往复


     		canvas.save();
            canvas.translate(0,currentHeight - ticketH);
            canvas.clipRect(ticketL, ticketT + ticketH - currentHeight,ticketR,ticketB);
            ticket.draw(canvas);
            canvas.restore();
 

demo圆环

复杂点 2个状态切换的 圆环翻转 和 圆环弧度变化

翻转

生成翻转矩阵 添加到画布上

XX 矩阵操作生成翻转 matrix  XX
canvas.concat(matrix);

跟弧度 画对应长度圆弧标示百分比

canvas.drawArc(mBigOval, -90, mCurrentSweep, false, mPaint);

优化点

讲两个view合成为一个 在objectionAnimation 存储状态值 判断状态值 进行不同操作

  @Override
    public float getValue() {
        return value;
    }

    @Override
    public int getStep() {
        return 0;
    }

###控件动画实现###

控件每个都不一样 主要是找到你要进行动画的view 添加对应的效果

  1. listView item添加效果

demo jazzyListView 实现核心代码

  1. viewGourp item 添加效果

demoe sortGridView 实现核心代码


interpolator 插值器##

原来收藏过的 比较详细的一个 图比较多 很清楚直观

介绍文档传送门

一个github项目传送门

sortGrid github 地址

jazzyListView github 地址

animationshare's People

Contributors

jiedang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.