动画库android_android 动画库 - CSDN
  • Android 动画库

    2019-07-13 09:56:13
    简介:Lottie是一个可以播放由AE打包的json动画文件的开源,使用它,你可以简单实现播放利用AE制作的动画。(其实Lottie的本质就是解析.json文件并通过Canvas方式进行绘制动画) Start: 2.6 k 支持类型:...

    目录

    一:Lottie

    二:Spruce Android Animation Library

    三:InfiniteCards

     

    一:Lottie

    简介:Lottie是一个可以播放由AE打包的json动画文件的开源库,使用它,你可以简单实现播放利用AE制作的动画。(其实Lottie的本质就是解析.json文件并通过Canvas方式进行绘制动画)

    Start: 2.6 k

    支持类型:Anddroid , IOS ,Web

    支持功能:支持 Android 系统动画,还可以制作不同的复杂类型动画。

     

    二:优缺点

    优点:

    1. 能够解析渲染通过 AE 上的 Bodymovin 插件将 AE 中制作好的动画导出成的 json 文件
      (2)数据源多样性—可从assets,sdcard,网络加载动画资源,动态更新
      (3)跨平台—设计稿导出一份动画描述文件,android,ios,react native通用(android使用的api不能低于16)

    (4) 同一个通话文件可以在不同的品台上实现动画,极大的加少了开发成本和开发人员的工作量。

     

    缺点:开始倒入配置和设置配置比较容易出错;太多层级的时候会出现偶尔的卡顿。

     

     

    二:Spruce Android Animation Library

    简介:Spruce 是一个轻量级的动画库,可以帮助排版屏幕上的动画。使用有很多不同的动画库时,开发人员需要确保每个视图都能够在适当的时间活动。 Spruce 可以帮助设计师获得复杂的多视图动画,而不是让开发人员在原型阶段就感到畏惧

    Start:3.1k

    支持类型:Android  IOS

    支持功能:可完成复杂的多视图动画

     

    二:优缺点

    优点:

    1. 能完成复杂类型的动画效果

    (2)框架比较轻量级,占用的内存较少

    缺点:实现多试图动画添没有处理好排版问题,有可能出现卡顿。

     

     

    三:InfiniteCards

    简介:可自定义动效的卡片切换试图,该库有助于实现卡片UI ,然后用一个漂亮的动画切换它们。

    Start:1.4k

    支持类型:Android  

    支持功能:单独的实现卡片切换动画效果

     

    优点:一个专门实现卡片切换的库,使用简单,效果较好,可实现左右切换和上下切换。

    展开全文
  • 目前支持android上gif动画主要存在两种方式:第一种为将动画做成一张张图片然后进行快速切换,从而形成动画效果,第二种将动画变成json字符串,利用开源进行解析,然后进行显示从而达到动画效果。其中两种方式的...

            目前支持android上gif动画主要存在两种方式:第一种为将动画做成一张张图片然后进行快速切换,从而形成动画效果,第二种将动画变成json字符串,利用开源库进行解析,然后进行显示从而达到动画效果。其中两种方式的典型代表库为:android-gif-drawable和Lottie。

    android-gif-drawable开源库地址:https://github.com/koral--/android-gif-drawable

    Lottie开源库地址:https://github.com/airbnb/lottie-android


    Lottie是Airbnb最近开源的一个动画库,它能够同时支持iOS,Android与ReactNative的开发.它的原理是利用Adobe After Effects软件做出动画,然后再用bodyMovin插件将动画导出成为一个json字符串,最后用Airbnb的开源库Lottie进行json文件解析最后绘制到设备上面,显而易见这个动画库的好处就是将动画变成了json字符串,极大地减少了文件大小,从而对apk进行了“瘦身”,所以下面总结了一下使用Lottie动画库进行动画显示的好处:

    1、由于将动画变成了json字符串,极大地减少了应用大小。

    2、因为Lottie是利用json文件生成动画,从而避免了不同分辨率、不同设备尺寸上面动画效果存在差异的问题。

    3、只需要进行一动画绘制,生成一次json文件,从而可以在所有端进行使用(android,ios,web)


           上面介绍了Lottie动画库的好处,那么现在我们来具体了解Lottie动画库的工作原理和使用流程:

    首先我们需要有一个用AE生成的json动画文件,这个文件由UI美工进行提供,不需要我们程序员进行生成(感兴趣的可以自己试试,反正我是不知道怎么弄),我们尝试打开json文件,得到如下的结果:


            发现和普通的json文件没有任何区别,它是由layers数组和其他关键数组组成,学过ps的知道一张图片是有多个图层叠加而成,这里的动画也是如此,通过AE做成动画,然后由插件将图层、图片大小、动画时间、关键帧等信息输出到json字符串中,所以我们只需要解析json文件,将关键信息解析出来然后把图层一层一层绘制上去,然后一帧一帧的切换就形成了动画。

    我们将Lottie动画下载下来阅读源码,得出Lottie的大致框架图如下:


    从图中可以看出Lottie库主要有三个重要的类型:AnimatableValue、KeyframeAnimation、AnimatableLayer,其中AnimatableLayer是继承Drawable类,所以真正进行动画绘制是依靠Drawable机制进行处理的,所有的关键数组最后都会封装到对应的AnimatableLayer中进行处理,其中流程图大致如下:

    接下来我们从源码角度来了解Lottie的工作过程,首先我们知道Lottie显示动画主要有两种方式:

    第一种方式是在xml中配置:

    <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/animation_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:lottie_fileName="hello-world.json"
            app:lottie_loop="true"
            app:lottie_autoPlay="true" />


    第二种方式是在代码中进行动态设置:

    LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view);
    animationView.setAnimation("hello-world.json");
    animationView.loop(true);
    animationView.playAnimation();


    首先我们看一下LottieAnimationView类的初始化,发现在构造方法中调用了init方法,下面就是init方法的实现:

    private void init(@Nullable AttributeSet attrs) {
            TypedArray ta = getContext().obtainStyledAttributes(attrs,
                    R.styleable.LottieAnimationView);
            String fileName = ta
                    .getString(R.styleable.LottieAnimationView_lottie_fileName);
            if (!isInEditMode() && fileName != null) {
                setAnimation(fileName);
            }
            if (ta.getBoolean(R.styleable.LottieAnimationView_lottie_autoPlay,
                    false)) {
                lottieDrawable.playAnimation();
            }
            lottieDrawable.loop(ta.getBoolean(
                    R.styleable.LottieAnimationView_lottie_loop, false));
            ta.recycle();
            setLayerType(LAYER_TYPE_SOFTWARE, null);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                float systemAnimationScale = Settings.Global.getFloat(
                        getContext().getContentResolver(),
                        Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f);
                if (systemAnimationScale == 0f) {
                    lottieDrawable.systemAnimationsAreDisabled();
                }
            }
        }


    我们发现在init方法中读取了xml中的配置信息,然后调用setAnimation()方法,最后调用LottieDrawable的playAnimation()方法开始播放动画,其中setAnimation()有多个重载方法,我们就看最核心的方法:

    public void setAnimation(final String animationName,
                final CacheStrategy cacheStrategy) {
            this.animationName = animationName;
            if (weakRefCache.containsKey(animationName)) {
                WeakReference<LottieComposition> compRef = weakRefCache
                        .get(animationName);
                if (compRef.get() != null) {
                    setComposition(compRef.get());
                    return;
                }
            } else if (strongRefCache.containsKey(animationName)) {
                setComposition(strongRefCache.get(animationName));
                return;
            }
    
            this.animationName = animationName;
            lottieDrawable.cancelAnimation();
            cancelLoaderTask();
            compositionLoader = LottieComposition.fromAssetFileName(getContext(),
                    animationName,
                    new LottieComposition.OnCompositionLoadedListener() {
                        @Override
                        public void onCompositionLoaded(
                                LottieComposition composition) {
                            if (cacheStrategy == CacheStrategy.Strong) {
                                strongRefCache.put(animationName, composition);
                            } else if (cacheStrategy == CacheStrategy.Weak) {
                                weakRefCache.put(animationName,
                                        new WeakReference<>(composition));
                            }
    
                            setComposition(composition);
                        }
                    });
        }


    在这个方法中有两个参数一个是AnimationName,一个是CacheStrategy,毫无疑问AnimationName就是json文件的路径,而CacheStragy是什么呢?我们跟踪代码发现这个是缓存工具类,它是一个枚举类型,它提供了三种缓存技巧:Weak(弱引用缓存)、Strong(直接缓存在内存中)、None(不缓存),他们分别缓存在两个map中:

    private static final Map<String, LottieComposition> strongRefCache = new HashMap<>();
    private static final Map<String, WeakReference<LottieComposition>> weakRefCache = new HashMap<>();


    在检查缓存之后利用LottieComposition的静态方法fromAssetFileName()去加载json文件,最后调用了fromInputStream()方法。

    public static Cancellable fromInputStream(Context context,
                InputStream stream, OnCompositionLoadedListener loadedListener) {
            FileCompositionLoader loader = new FileCompositionLoader(
                    context.getResources(), loadedListener);
            loader.execute(stream);
            return loader;
        }


    其中FileCompositionLoader是AyscTask的子类,所以利用它进行了数据的异步加载(因为读取文件是耗时操作),当数据读取完成之后剩下来就是进行json字符串的解析了。

    static LottieComposition fromJsonSync(Resources res, JSONObject json) {
            LottieComposition composition = new LottieComposition(res);
    
            int width = -1;
            int height = -1;
            try {
                width = json.getInt("w");
                height = json.getInt("h");
            } catch (JSONException e) {
                // ignore.
            }
            if (width != -1 && height != -1) {
                int scaledWidth = (int) (width * composition.scale);
                int scaledHeight = (int) (height * composition.scale);
                if (Math.max(scaledWidth, scaledHeight) > MAX_PIXELS) {
                    float factor = (float) MAX_PIXELS
                            / (float) Math.max(scaledWidth, scaledHeight);
                    scaledWidth *= factor;
                    scaledHeight *= factor;
                    composition.scale *= factor;
                }
                composition.bounds = new Rect(0, 0, scaledWidth, scaledHeight);
            }
    
            try {
                composition.startFrame = json.getLong("ip");
                composition.endFrame = json.getLong("op");
                composition.frameRate = json.getInt("fr");
            } catch (JSONException e) {
                //
            }
    
            if (composition.endFrame != 0 && composition.frameRate != 0) {
                long frameDuration = composition.endFrame - composition.startFrame;
                composition.duration = (long) (frameDuration
                        / (float) composition.frameRate * 1000);
            }
    
            try {
                JSONArray jsonLayers = json.getJSONArray("layers");
                for (int i = 0; i < jsonLayers.length(); i++) {
                    Layer layer = Layer.fromJson(jsonLayers.getJSONObject(i),
                            composition);
                    addLayer(composition, layer);
                }
            } catch (JSONException e) {
                throw new IllegalStateException("Unable to find layers.", e);
            }
    
            // These are precomps. This naively adds the precomp layers to the main
            // composition.
            // TODO: Significant work will have to be done to properly support them.
            try {
                JSONArray assets = json.getJSONArray("assets");
                for (int i = 0; i < assets.length(); i++) {
                    JSONObject asset = assets.getJSONObject(i);
                    JSONArray layers = asset.getJSONArray("layers");
                    for (int j = 0; j < layers.length(); j++) {
                        Layer layer = Layer.fromJson(layers.getJSONObject(j),
                                composition);
                        addLayer(composition, layer);
                    }
                }
            } catch (JSONException e) {
                // Do nothing.
            }
    
            return composition;
        }



    从上面方法的返回值可以发现将json字符串中的所有信息都封装在LottieCompositon类中,在这个类中保存了动画时长、帧率等关键信息,其中将json文件中的图层layer封装成了Layer对象并保存在图层list列表layers中,而Layer类负责对图层JsonObject对象进行解析,阅读源码发现Layer类中解析出了scale、rotation、opacity、shape等动作,并将这些动作用对应的AnimatableValue类进行封装,至此json文件的解析过程就已经完成了,接下里就是如何实现动画的绘制了。

    至此我们来总结一下json文件的解析过程,首先在LottieAnimationView的init方法中读取xml属性中动画文件,然后解析成LottieComposition对象,其中的解析过程是利用LottieCompostion类的静态方法进行json字符串的第一次基本解析,然后利用Layer对象将每个图层字符串解析变成一个Layer对象并保存在LottieComposition的成员变量layer集合中。在前面提到过我是利用AysncTask子类进行异步解析json字符串的,所以解析完成之后就会调用onPostExecute()方法

    protected void onPostExecute(LottieComposition composition) {
         loadedListener.onCompositionLoaded(composition);
    }
    
    //这个类是在LottieAnimationView中进行定义的
    private final LottieComposition.OnCompositionLoadedListener loadedListener = new LottieComposition.OnCompositionLoadedListener() {
            @Override
            public void onCompositionLoaded(LottieComposition composition) {
                setComposition(composition);
                compositionLoader = null;
            }
        };


    所以解析完成之后开始调用LottieAnimationView的setComposition()方法,将LottieComposition对象设置到LottieDrawable对象

    @Override
    public void setComposition(@NonNull LottieComposition composition) {
            if (L.DBG) {
                Log.v(TAG, "Set Composition \n" + composition);
            }
            lottieDrawable.setCallback(this);
            lottieDrawable.setComposition(composition);
            // If you set a different composition on the view, the bounds will not
            // update unless
            // the drawable is different than the original.
            setImageDrawable(null);
            setImageDrawable(lottieDrawable);
    
            this.composition = composition;
    
            requestLayout();
        }

    将LottieComposition设置个lottieDrawable对象之后,这个框架就会将之前解析完成的数据变成一个个图层对象集合,每个图层中又包含了关于本图层的一系列操作的集合

    void setComposition(LottieComposition composition) {
        if (getCallback() == null) {
          throw new IllegalStateException(
              "You or your view must set a Drawable.Callback before setting the composition. This " +
                  "gets done automatically when added to an ImageView. " +
                  "Either call ImageView.setImageDrawable() before setComposition() or call " +
                  "setCallback(yourView.getCallback()) first.");
        }
        clearComposition();
        this.composition = composition;
        setSpeed(speed);
        setBounds(0, 0, composition.getBounds().width(), composition.getBounds().height());
        buildLayersForComposition(composition);
    
        setProgress(getProgress());
      }

    到此为止我们就将整个动画设置给了View,接下来就是分析如何将动画运行起来了,我们发现在LottieAnimationView提供了playAnimation()方法,我们跟进去之后发现最终调用到了LottieDrawable对象的playAnimation()方法,我们分析一下LottieDrawable对象的playAnimation()是如何实现的:

    void playAnimation() {
        if (layers.isEmpty()) {
          playAnimationWhenLayerAdded = true;
          reverseAnimationWhenLayerAdded = false;
          return;
        }
        animator.setCurrentPlayTime((long) (getProgress() * animator.getDuration()));
        animator.start();
      }
    我们发现在LottieDrawable中实际上调用的是ValueAnimator属性动画,但是这个与我们说讲述的动画有什么关联呢?我们接下来发现了ValueAnimator中添加了一个动画的监听器,在监听器中我们的动画随着属性动画的值改变而发生改变。

    LottieDrawable() {
        super(null);
    
        animator.setRepeatCount(0);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
          @Override public void onAnimationUpdate(ValueAnimator animation) {
            if (systemAnimationsAreDisabled) {
              animator.cancel();
              setProgress(1f);
            } else {
              setProgress((float) animation.getAnimatedValue());
            }
          }
        });
      }
    public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
        this.progress = progress;
        for (int i = 0; i < animations.size(); i++) {
          animations.get(i).setProgress(progress);
        }
    
        for (int i = 0; i < layers.size(); i++) {
          layers.get(i).setProgress(progress);
        }
      }
    
    
    接下来的处理就交给了每个图层进行处理,然后进行绘制,后面的处理逻辑就不进行叙述了。


    通过以上分析,我们来总结一下Lottie动画库显示动画的整个流程:首先将json文件解析成为LottieComposition对象并将这个对象设置个LottieDrawable,在LottieDrawable对象将将LottieComposion中的图层Layer数据实体变成LayerView对象(这个对象里面处理了每个图层的控制逻辑),然后在LottieDrawable对象中利用属性动画将这个Lottie动画绘制起来,

    将Lottie动画库中的每个图层一层一层的绘制,这个属性动画相当于整个动画的一个引子,将所有的图层联系起来。


    下面我们来比较一下展示动画的两种常用方式:

    (1)android-gif-drawable开源库,利用.gif文件进行动画展示

    (2)Lottie动画库,利用json文件进行动画展示


    我们将从三个方面来进行比较:

    (1)原理方面:

    android-gif-drawable使用c层进行gif图片解析,然后按照关键帧一张一张的显示,所以这个过程中存在gift文件解析、图片解码、图片渲染展示这些过程。

           Lottie则是根据Json文件利用canvas进行绘制,所以它的过程为:解析json文件,canvas绘制动画。


    (2)实现效果方面

    android-gif-drawable由于是使用了图片,所以图片尺寸大小就限定了动画的展示效果,所以他们在不同尺寸的设备上得展现效果存在差异.

    Lottie动画库由于使用json文件,所以不存在这个问题,它在所有设备上得展现效果都一样


    (2)系统资源占用方面

     

    gif方式


        

    Lottie方式


    对于上面的比较,我们发现这两方式各有各的特点,各有各的优势,至于如何选择得看具体的业务场景,Lottie个人觉得适合做宣介、引导等动画,而gif方式则适合做局部复杂UI动画。

    展开全文
  • Android Lottie动画库

    2019-05-31 17:11:44
    简单的使用只需要把动画导出成 的JSON 文件放到assets文件夹下,xml直接使用即可 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com...

    https://www.cnblogs.com/plokmju/p/8036668.html,很详细

    简单的使用只需要把动画导出成 的JSON 文件放到assets文件夹下,xml直接使用即可

     

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white">
    
            <com.airbnb.lottie.LottieAnimationView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                app:lottie_fileName="splash.json"     //动画json文件名
                app:lottie_loop="false"
                app:lottie_autoPlay="true" />
        </FrameLayout>
    </layout>
    

    展开全文
  • 个人博客介绍比较全,也会实时更新:Android自定义加载动画库zLoading 目前拥有的类型: 索引 类名 枚举值(Z_TYPE) 昵称 0 CircleBuilder CIRCLE 圆 1 ClockBuilder CIRCL...

    效果图

    演示效果动画1

    演示效果动画2

    上一个动画链接:Android自定义加载动画-交织

    个人博客介绍比较全,也会实时更新:
    Android自定义加载动画库zLoading

    目前拥有的类型:

    索引 类名 枚举值(Z_TYPE) 昵称
    0 CircleBuilder CIRCLE
    1 ClockBuilder CIRCLE_CLOCK 计时器
    2 StarBuilder STAR_LOADING 跳舞的星星
    3 LeafBuilder LEAF_ROTATE 旋转的叶子
    4 DoubleCircleBuilder DOUBLE_CIRCLE 画两个圈圈
    5 PacManBuilder PAC_MAN PacMan
    6 ElasticBallBuilder ELASTIC_BALL 颤抖吧!球球
    7 InfectionBallBuilder INFECTION_BALL 感染体
    8 IntertwineBuilder INTERTWINE 交织
    9 TextBuilder TEXT 文字
    10 SearchPathBuilder SEARCH_PATH 搜索等待
    11 RotateCircleBuilder ROTATE_CIRCLE 多圆旋转
    12 SingleCircleBuilder SINGLE_CIRCLE 单圆简单动画
    13 SnakeCircleBuilder SNAKE_CIRCLE 引蛇出洞
    14 StairsPathBuilder STAIRS_CIRCLE 舞动阶梯
    15 MusicPathBuilder MUSIC_PATH 跳动音符
    16 StairsRectBuilder STAIRS_RECT 递增方块
    17 ChartRectBuilder CHART_RECT 跳动的柱状图

    链接如下

    第一个,ClockBuilder

    第二个,StarBuilder

    第三个,LeafBuilder

    第四个,DoubleCircleBuilder

    第五个,PacManBuilder

    第六个,ElasticBallBuilder

    第七个,InfectionBallBuilder

    第八个,IntertwineBuilder

    更多请关注 https://www.zyao89.cn/blog

    引入

    1. Gradle方式引用
    compile 'com.zyao89:zloading:1.0.11'
    
    1. GitHub下载工程
      zyao89/ZCustomView(这里应该比较新)

    使用

    1. 可以直接使用等待框模式,如下:
    ZLoadingDialog dialog = new ZLoadingDialog(MainActivity.this);
    dialog.setLoadingBuilder(type)//设置类型
            .setLoadingColor(Color.BLACK)//颜色
            .setHintText("Loading...")
            .show();
    
    1. 也可以直接使用LoadingView动画,如下:
    ZLoadingView zLoadingView_1 = (ZLoadingView) findViewById(R.id.loadingView_1);
    zLoadingView_1.setLoadingBuilder(Z_TYPE.DOUBLE_CIRCLE);
    zLoadingView_1.setColorFilter(Color.BLACK);
    

    也可以如下使用xml配置:

    <com.zyao89.view.zloading.ZLoadingView
            android:id="@+id/loadingView_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:z_type="DoubleCircleBuilder"
            app:z_color="@android:color/holo_green_light"/>
    

    效果实现图可以看前面几篇文章介绍的。



    作者:Zyao89
    链接:https://www.jianshu.com/p/c62332fcf8f4
     

    展开全文
  • Android Lottie动画库 最近工作上面需要所以导入了一个Android动画库Lottie ,这篇博客主要是为了记载一下这个动画库,以及动画库的简单的用法。 简单的来说下这个lottie动画库 Lottie是适用于Android和iOS的移动...
  • 简介官方网站githubRebound是facebook出品的一个弹簧动画库,与之对应的IOS版本有一个pop动画库,也是非常的强大给力。Facebook真是互联网企业中的楷模,开源了很多的实用开源库,大赞一个!!!
  • 上一篇博客,给大家介绍了强大的粒子动画库Leonids,现在我就用Leonids,实现一个超级酷炫的点赞效果, Leonids粒子动画库实战第一篇,话不多说,先上效果图 这个动画分为三个部分,第一个部分四处分散渐变色的...
  • //动画库 compile 'com.daimajia.androidanimations:library:1.1.2@aar' compile 'com.nineoldandroids:library:2.4.0'//使用YoYo.with(Techniques.Bounce) .duration(500).delay(100) ...
  • 废话不多说,直接上官方网址:http://nineoldandroids.com/点击打开链接 具体分析,请看官网
  • 距上次「花了 4 个月整理了 50 篇 Android 干货文章」...Google I/O ‘17 新推出的物理动画库 Android Studio 实用小技巧 那些年Android黑科技①:只要活着,就有希望 那些年Android黑科技②:欺骗的艺术 那些年An
  • [干货]2017已来,最全面试总结——这些Android面试题你一定需要碉堡的LottieAirbnb最近开源了一个名叫Lottie的动画库,它能够同时支持iOS,Android与ReactNative的开发.此消息一出,还在苦于探索自定
  • Android 3D旋转动画库

    2017-09-01 15:29:44
    今天兴趣来潮,撸了一个动画特效,我把他应用在登录的界面,当然也可以用在其他地方,先来预览一下我的特效吧使用方法 1. 在build.gradle里面配置如下 dependencies { compile 'com.jzp:rotate3D:1.0.0' } 2. 生成...
  • android 页面过渡动画兼容
  • Android动画进阶—使用开源动画库nineoldandroids
  • 最近写了一个动画库,叫MTransition,顾名思义,就是过场动画、页面切换动画用的。它可以提高你开发页面切换动画的效率,用一些简单的代码实现非常复杂的动画。跨Activity的动画也适用。 现在代码已经开源,欢迎...
  • android-magic-surface-view 是一个 android 动画特效, 可以实现各种炫酷动画
  • 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/380674751、概述Android提供了几种动画类型:View Animation 、Drawable Animation 、Property Animation 。View Animation相当简单,不过只能...
  • 由于看了IOS上面很多开发者开发的APP的视图界面切换动画体验非常好,这些都是IOS自带的,但是...可以说是目前Android上第一个,也是唯一的一个强大的视图切换动画库引擎! 作者:谭东 QQ:852041173 项目开
  • 21 Android绘图基础CanvasPaint等 22Path类 23绘制游戏动画 3图形特效处理 31 使用Matrix控制变换 32使用drawBitmapMesh扭曲图像 33使用Shader来填充图形 4逐帧动画 41AnimationDrawable 与逐帧动画 5补间动画 51...
  • Android动画库

    2015-02-03 15:33:37
    动画库介绍博客
1 2 3 4 5 ... 20
收藏数 44,432
精华内容 17,772
关键字:

动画库android