欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-10-30 17:14:40
前言 在最近的时间里,短视频流行了起来,随着这股潮流,一种动图封面的设计也被很多短视频app采用: 某音 而在app中,动图的展示是比较消耗性能的操作,对于这...

前言

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

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

某音

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

图片加载框架选择

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

图片展示的策略

只在当前页展示

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

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

首页

假设下面的“首页”“、”关注”、“消息”、“我”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左右。

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

总结:

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