文档章节

YY项目之帧动画(二)

dj_归去来兮
 dj_归去来兮
发布于 2016/04/05 16:12
字数 783
阅读 72
收藏 0

YY项目之帧动画(一)中我们介绍了帧动画的基本使用。

但是如果美工给我们的图片都是几百 * 几百的,加载进不同的分辨率的手机中,占用的内存是显而易见的。

而且,在我的项目中,会经常出现OOM,所以下面就来解决由帧动画引起的OOM问题。

由前面的文章可以知道,这个需求主要实现framelayout的上面一层来实现动画,底下的层用来实现需要展示的视图。

所以,底下的视图层照常编辑即可。

如果需要解决帧动画加载内存占用的问题,就不能加载编辑好的drawable文件夹中的xml文件了,需要手动编辑java代码,在java代码层面处理生成AnimationDrawable(这里是关键的思想)。

使用java代码创建AnimationDrawable的好处是:动态的按需处理加载进内存的图片的像素,从而优化了内存占用过多(甚至发生OOM)的问题。

那么,接下来,就看看代码是如何实现的吧,只列举其中的一个AnimationDrawable动画。

  • 手动创建AnimationDrawable,并设置到指定的View上

/**
 * 初始化 点击的动画
 */
clickDrawable = new AnimationDrawable();
clickDrawable.setOneShot(true);
for (int i = 0 ;i < 9 ;i++) {
    if (i == 0 || i == 8) {
        // 添加透明的帧
        clickDrawable.addFrame(getResources().getDrawable(R.drawable.transpanrent), 50);
    } else {
        int resId = getResources().getIdentifier("click_" + (i - 1), "mipmap", getPackageName());
        clickDrawable.addFrame(new BitmapDrawable(getResources(), ImageLoaderUtils.decodeSampledBitmapFromResource(getResources(), resId, 100, 100)), 50);
    }
}
iv_anim.setImageDrawable(clickDrawable);

    里面需要用到的透明的效果的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@android:color/transparent"/>
    <stroke android:color="@android:color/transparent"/>
</shape>
  •  设置点击事件,执行动画:

iv_click.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        if (right) {
            if (!isLongClick) {
                restartAnimation(clickDrawable);
            }
        } else {
            // 显示红色背景
            showWrong();
        }
    }
});

    关键代码片段:

/**
 * 重新启动动画
 * 首先得停止帧动画,然后才能重新执行帧动画,否则没有效果
 *
 * @param drawable
 */
private void restartAnimation(AnimationDrawable drawable) {
    if (drawable.isRunning() && drawable != null) {
        drawable.stop();
    }
    drawable.start();
}

    ImageLoaderUtils 解决该问题的关键方法源码:

/**
 * 计算图片的缩放比例 <br/>
 * 作者 :dengjie zhang <br/>
 * created at 2016/3/16 9:25
 */
public static int calculateInSampleSize(BitmapFactory.Options options,
                                        int reqWidth, int reqHeight) {
    // 源图片的高度和宽度
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
        // 计算出实际宽高和目标宽高的比率
        final int heightRatio = Math.round((float)height / (float)reqHeight);
        final int widthRatio = Math.round((float)width / (float)reqWidth);
        // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
        // 一定都会大于等于目标的宽和高。
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
}

/**
 * 获取合适的大小的图片的bitmap的形式 <br/>
 * 作者 :dengjie zhang <br/>
 * created at 2016/3/16 9:27
 */
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                     int reqWidth, int reqHeight) {
    // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    // 调用上面定义的方法计算inSampleSize值
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}


© 著作权归作者所有

dj_归去来兮
粉丝 15
博文 113
码字总数 31739
作品 0
合肥
Android工程师
私信 提问
YY项目之帧动画(一)

由于项目中需要实现一个小游戏,根据音乐节奏打击节奏点,打击时需要有一个效果动画。 实现:利用framelayout的浮动特性,使用2层relativelayout,第一层视图层,第二层,动画层 <FrameLayo...

奔跑的野马
2016/03/14
50
0
直播App中Android酷炫礼物动画实现方案(下篇):SVGA由来与Lottie的对比

在一个月黑风高的夜里,一位开发Da Lao在朋友圈吐槽『你们UED设计的动画,太炫了!我们实现不了……!』,接着小B(UED掌门人)与这位Da Lao谈了一整晚的人生。 第二天,小B把Pony捉到了会议...

urdfmqcul2
2017/10/30
0
0
Android实用视图动画及工具系列之二:Toast对话框和加载载入对话框

实现效果 功能说明 类似Toast底色的弹出对话框和加载对话框,主要实现弹出和提示消息的功能,对话框可以实现不被取消,主要功能原理利用了安卓逐帧动画和继承对话框接口来实现,适用于新手及...

jaikydota163
2016/08/02
0
0
Android实用视图动画及工具系列之一:简单的载入视图和载入动画

实现效果 功能说明 简单的载入视图和载入动画,相信大家一听名字就知道是些什么功能了,本Demo主要实现了安卓逐帧动画的开始播放,暂停和停止功能,适用于新手及新学习Android的码友们,老玩...

jaikydota163
2016/08/02
0
0
Windows 8应用实例解析 - WinRT下创建GIF动画(Flipflop)

在Windows Store中下载了一个有意思的应用,叫做Flipflop(http://apps.microsoft.com/windows/app/flipflop/99c01512-fe4f-4d1a-872e-eb9fd6638ff4),该应用允许用户创建翻页式动画效果(Flip...

冷秋寒
2018/06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

微服务之架构技术选型与设计

本文主要介绍了架构技术选型与设计-微服务选型,Spring cloud 实现采用的技术,希望对您的学习有所帮助。 架构技术选型与设计-DUBBODubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿...

别打我会飞
33分钟前
3
0
在Windows中运行Linux bash命令的几种方法

如果你正在课程中正在学习 shell 脚本,那么需要使用 Linux 命令来练习命令和脚本。 你的学校实验室可能安装了 Linux,但是你自己没有安装了 Linux 的笔记本电脑,而是像其他人一样的 Window...

老孟的Linux私房菜
36分钟前
1
0
深入理解计算机系统(1.1)------Hello World 是如何运行的

上一篇序章我谈了谈 程序员为啥要懂底层计算机结构 ,有人赞同也有人反对,但是这并不影响 LZ 对深入理解计算机系统研究的热情。这篇博客以案例驱动的模式,通过跟踪一个简单 Hello World 程...

vinci321
41分钟前
2
0
Linux操作系统之Shell程序设计

Linux操作系统之Shell程序设计 Shell是种命令解释程序,也可以看作是一种命令语言的解释器。 用户在与Shell交互时所输入的命令行必须符合Shell命令的语法和语义规范,才能够被Shell理解并执行...

linuxCool
49分钟前
5
0
Java Foreach拉姆达表达式

以下案例分析了foreach循环和Java8 拉姆达表达式的区别 public static void main(String[] args) {/* * foreach 和 list */List<String> arrs = new ArrayList<>();...

cuishy
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部