Android列表动图展示的实现策略

所属分类: 软件编程 / Android 阅读数: 38
收藏 0 赞 0 分享

前言

在最近的时间里,短视频流行了起来,随着这股潮流,一种动图封面的设计也被很多短视频app采用:

某音

而在app中,动图的展示是比较消耗性能的操作,对于这种一页非常多的动图在展示时需要做对应的处理,今天我结合自己在项目中处理的经验分享一下多动图的处理策略。

图片加载框架选择

对于动图的加载,尤其是webp格式的动图,Fresco真是不二的选择,而且fresco本身对内存的处理也很棒,本文是基于Fresco 1.0.10版本,如果使用低版本Fresco出现无解的问题时,不妨可以试着升级Fresco版本。

图片展示的策略

只在当前页展示

我们知道,动图是由一帧一帧的静图组成的,通常来说我们需要这个动图一直播放,也就是说动图从加载完成之后会不停的渲染每一帧,拿某音举例:

首页

假设下面的“首页”“、”关注”、“消息”、“我”4个tab都有动图,当我们点击其他页面时,当前页被隐藏,而根据Fresco的官方文档Fresco中文官方文档通常只有当SimpleDrawView被移出屏幕才会停止播放动画(我在测试中发现通常Activity生命周期级别的也会触发),所以当tab页隐藏时动图依旧在被渲染,所以我们需要控制动图的停止和播放,只有当前页展示时,才播放动图:

    Animatable animatable = mSimpleDraweeView.getController().getAnimatable();
    if (animatable != null) {
      animatable.start();
       // later
      animatable.stop();
     }

只在可见区域展示

当我们做列表动图的时候,无论控件是listview还是recyclerview,数据和item的绑定都会在屏幕外绑定,而此时站在性能优化的角度上,是不需要渲染动图的;当动图滑动在列表边界的时候,是不是说明用户的焦点已经不在这张图上了,所以此时可以提前在动图滑出屏幕外之前停止动图播放(在项目中我与产品商定动图播放和停止的边界值定为图片的1/2,也就是说图片滑入屏幕自身长度1/2的时候播放动图,滑出屏幕自身长度1/2的时候停止播放);当快速滑动的时候也应当停止动图渲染(平时加载静图可能不需要在意,但是在android老手机上加载很多动图会使得cpu和内存大幅度浮动)。

也就是说当列表在做数据绑定的时候我们应当先去加载图片但并不渲染动图,动图播放和停止唯一的判断标准是滑入滑出屏幕的长度,如果是快速滑动则无视第二个规则直接停止所有的动图。

上面的第二、第三个处理会有些许的代码量,而且重点是时机的判断不是动图的处理,这里着重讲策略,代码就略过了。对于第一个处理,Fresco本身是支持的:

    DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
     .setAutoPlayAnimations(false)
      . // 其他设置(如果有的话)
      .build();

setAutoPlayAnimations即表示是否在加载完成之后立即播放动图,这里设置为false即可,滑入播放调用上一张图的方法就行了。可是还有一种情况,动图在我们滑入的时候还没有加载完成,那么我们就可以设置一个标示来表示是否播放,因为SimpleDrwaView是可以拿到动图加载的回调的:

 ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
 @Override
 public void onFinalImageSet(
  String id,
  @Nullable ImageInfo imageInfo,
  @Nullable Animatable anim) {
  if (anim != null && tag == BEGAIN) {
   // 其他控制逻辑
   anim.start();
  }
 }
};

滑入屏幕时,就把tag 置为BEGAIN,滑出再置空就行了,并且这里我们不用担心重复播放和停止的问题,这里的anim对象其实是AnimatedDrawble2对象,而该对象在start和stop的时候都对状态进行了判断。

图片的规格尺寸

规格

相较于传统的gif,同质量的webp体积更小,更能节省存储空间,但是在解码上webp更为耗时,所以能用webp尽量用webp,实在还是卡再考虑用gif。

帧率

目前调研发现的动图帧率一般是10帧或者20帧,帧率不要太高了,不然会加大cpu的占用率,其实如果Fresco的使用方式没出问题,内存的问题Fresco已经帮你搞定了,其他的优化主要是针对cpu占用率优化的。在项目中我们加载的动图最后采用的是20帧(模仿腾讯谋产品的策略,最好控制在10帧其实,这款腾讯的产品在一页上展示的动图明显比其他同类型产品展示的数量少)。

大小

动图的大小也会影响解码耗时,在手机端可以使用小图,在项目中,我们手机端的动图最多在200kb左右。

在实际的开发中,可能因为业务的关系,上述的策略不能保证全部都做到,这里时候就得根据业务形态做对应的取舍,这里可能是一个长久优化的过程,毕竟这种新的动图封面设计以前都没有遇到过。

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

使用ViewPager实现android软件使用向导功能实现步骤

现在的大部分android软件,都是使用说明,就是第一次使用该软件时,会出现向导,可以左右滑动,然后就进入应用的主界面了,下面我们就实现这个功能
收藏 0 赞 0 分享

android在异步任务中关闭Cursor的代码方法

android在异步任务中如何关闭Cursor?在我们开发应用的时候,很多时候会遇到这种问题,下面我们就看看代码如何实现
收藏 0 赞 0 分享

Android自定义桌面功能代码实现

android自定义桌面其实很简单,看一个例子就明白了
收藏 0 赞 0 分享

android将图片转换存到数据库再从数据库读取转换成图片实现代码

有时候我们想把图片存入到数据库中,尽管这不是一种明智的选择,但有时候还是不得以会用到,下面说说将图片转换成byte[]数组存入到数据库中去,并从数据库中取出来转换成图像显示出来
收藏 0 赞 0 分享

TextView显示系统时间(时钟功能带秒针变化

用System.currentTimeMillis()可以获取系统当前的时间,我们可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间,可以做一个时钟的功能
收藏 0 赞 0 分享

Android用ListView显示SDCard文件列表的小例子

本文简单实现了用ListView显示SDCard文件列表,目录的回退等功能暂不讨论,获取文件列表,files即为所选择目录下的所有文件列表
收藏 0 赞 0 分享

Android拦截外拨电话程序示例

这篇文章主要介绍了Android拦截外拨电话的示例,大家参考使用吧
收藏 0 赞 0 分享

通过Html网页调用本地安卓(android)app程序代码

如何使用html网页和本地app进行传递数据呢?经过研究,发现还是有方法的,总结了一下,大致有一下几种方式
收藏 0 赞 0 分享

android Textview文字监控(Textview使用方法)

以手机号充值为例,当用户输入最后一位数时候,进行汇率的变换,本文就实现类似这样的功能
收藏 0 赞 0 分享

Android ListView长按弹出菜单二种实现方式示例

这篇文章主要介绍了Android ListView长按弹出菜单的方法,大家参考实现
收藏 0 赞 0 分享
查看更多