zoukankan      html  css  js  c++  java
  • Android自定义控件:动画类---逐帧动画AnimationDrawable

    1:概述

                Android动画包括View Animation(视图动画)Property Animator(属性动画),而View Animation包括Tween Animation(补间动画)和Frame Animation(逐帧动画);补间动画主Animation(ScaleAnimation、 AlphaAnimation、RotateAnimation、TranslateAnimation)为主,而逐帧动画则是以AnimationDrawable为主。

    2:定义逐帧动画

    定义逐帧动画非常简单,只要在<animation-list.../>中使用<item.../>子元素定义动画的全部帧,并指定各帧的持续时间即可
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
    <item
        android:drawable="@drawable/scenery1"
        android:duration="1000"/>
     <item
            android:drawable="@drawable/scenery2"
            android:duration="1000"
            />
        <item
            android:drawable="@drawable/scenery3"
            android:duration="1000"
            />
        <item
            android:drawable="@drawable/scenery4"
            android:duration="1000"
            />
        <item
            android:drawable="@drawable/scenery5"
            android:duration="1000"
            />
    </animation-list>
    上面语法格式中android:onshot控制该动画是否循环播放,如果该参数指定为true,则动画将不会循环播放;否则该动画将会循环播放。每个<item.../>子元素增加一帧。
    接下来就可用ImageView把AnimationDrawable显示出来,习惯上把AnimationDrawable设成ImageView的背景即可。
    需要指出的是:AnimationDrawable代表的动画默认是不播放的,必须在程序中启动动画播放才可以。AnimationDrawable提供如下两个方法开始、停止动画。
     1> start():开始播放动画
     2> stop(): 停止播放动画

    3:添加的帧数过多产生OOM的解决

    <span style="font-size:18px;">private void loadBitmap(){
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPurgeable=true;
            options.inInputShareable=true;
            //设置该属性可获得图片的长宽等信息,但是避免了不必要的提前加载动画
            options.inJustDecodeBounds=false;
            InputStream is=null;
            int[] raw={
                    R.raw.scenery1,R.raw.scenery2,R.raw.scenery3,R.raw.scenery4,R.raw.scenery5
            };
            Bitmap[] mbitMap=new Bitmap[5];
            for(int i=0,j=0;i<5&&j<5;i++,j++){
                is=getResources().openRawResource(raw[i]);
                Bitmap bitmap =BitmapFactory.decodeStream(is, null, options);
                mbitMap[j]=bitmap;
            }
    
            AnimationDrawable clipDrawable= new AnimationDrawable();
            for(int i=0;i<5;i++){
                clipDrawable.addFrame(new BitmapDrawable(mbitMap[i]), 50);
            }
            clipDrawable.setOneShot(false);
            animationDrawable=clipDrawable;
            iv_frame.setBackground(animationDrawable);
        }</span>
    setbackgroundResource()这种方法在设置animationDrawable动画的时候,是会在java层和native层产生两个实例的,而高像素bitmap图是特别占内存的,所以容易产生内存溢出问题,而我找到的最好解决方法是,不适用setBackgroundResource()这个方法而是首先使用decodeStream()这个方法读入bitmap字节码的流,而这个方法与decodeResource等其他方法相比,最好的地方在于它仅仅在native层也就是底层产生一个实例,但不会在java层使用createBitMap()方法产生实例,因此极大地减少了内存的占用,否则当读入20多张大图的时候很容易内存溢出。
  • 相关阅读:
    Vue 使用Scss,深度修改局部样式
    Sublime Text 插件:批量删除空白行
    Sublime Text 3前端开发常用优秀插件介绍
    常用的sublime text 3插件(很爽哦)
    20 个强大的 Sublime Text 插件
    Java多线程之synchronized详解
    进阶Java多线程
    初识Java多线程
    分布式锁实现的正确打开方式
    分布式session实现方式
  • 原文地址:https://www.cnblogs.com/vegetate/p/9997311.html
Copyright © 2011-2022 走看看