亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Flutter 119: 圖解簡易 ACEFrameAnimated 幀動畫

標簽:
Android

    小菜在做 Android 开发时,常常需要 帧动画 来作为作为 loading 动画;而 Flutter 没有直接提供类似于 帧动画 的组件,小菜简单尝试一个简单的 ACEFrameAnimated 帧动画小组件;

    小菜理解的 帧动画 其实一系列图片在一段时间内的叠加展示,以达到连贯的动画效果;

ACEFrameAnimated

    小菜认为,帧动画最重要的两个元素,分别是图片资源和间隔时间;之后便可对图片根据间隔时间来循环展示;为了适配网络图片和本地图片,小菜设置了一个 ACEFramePicType 资源类型;

enum ACEFramePicType { asset, network }

final List<Map<ACEFramePicType, String>> picList;
final Duration duration;

ACEFrameAnimated(this.picList, this.duration);

    小菜计划返回一个基本的 Widget,并通过 Future 延迟加载图片资源,其中需要注意的是循环加载,注意当前数组下标;其中在 initState() 中更新图片 _framePicList() 时,需要在 Future.delayed 之前先加载第一张图片,否则会出现短暂空白的情况;

class _ACEFrameAnimatedState extends State<ACEFrameAnimated> {
  List<Map<ACEFramePicType, String>> _picList;
  Duration _duration;
  int _index = 0;
  Widget _buildWid = Container();

  _ACEFrameAnimatedState(this._picList, this._duration);

  @override
  void initState() {
    super.initState();
    _framePicList();
  }

  @override
  Widget build(BuildContext context) => _buildWid;

  _framePicList() async {
    setState(() {
      _index = _index % _picList.length;
      _buildWid = Container(
          child: _picList[_index].keys.toList()[0] == ACEFramePicType.asset
              ? Image.asset(_picList[_index].values.toList()[0])
              : Image.network(_picList[_index].values.toList()[0]));
      _index++;
    });
    await Future.delayed(_duration, () => _framePicList());
  }
}

Tips

    小菜在退出页面时出现内存溢出,导致原因有两个,第一个是未清除 Widget 中的资源列表;第二个是 Future.delayed 发送消息后,await 导致消息未返回;

E/flutter (13298): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter (13298): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (13298): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (13298): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1112:9)
E/flutter (13298): #1      State.setState (package:flutter/src/widgets/framework.dart:1147:6)
E/flutter (13298): #2      _ACEFrameAnimatedState._framePicList (package:flutter_app/widget/ace_frame_animated.dart:32:5)
E/flutter (13298): #3      _ACEFrameAnimatedState._framePicList.<anonymous closure> (package:flutter_app/widget/ace_frame_animated.dart:40:43)
E/flutter (13298): #4      new Future.delayed.<anonymous closure> (dart:async/future.dart:316:39)
E/flutter (13298): #5      _rootRun (dart:async/zone.dart:1122:38)
E/flutter (13298): #6      _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (13298): #7      _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter (13298): #8      _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
E/flutter (13298): #9      _rootRun (dart:async/zone.dart:1126:13)
E/flutter (13298): #10     _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (13298): #11     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:949:23)
E/flutter (13298): #12     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:23:15)
E/flutter (13298): #13     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:384:19)
E/flutter (13298): #14     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:418:5)
E/flutter (13298): #15     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)

    小菜根据提示在使用 setState 时先判断当前 State 是否已绑定在 View 中;同时在 dispose 中清空资源;

@override
void dispose() {
  super.dispose();
  if (_picList != null) {
    _picList.clear();
  }
  if (widget != null && widget.picList != null) {
    widget.picList.clear();
  }
}

    [ACEFrameAnimated 案例源码] github.com/ACE-YANGCE/FlutterApp/blob/master/lib/page/ace_frame_animated_page.dart


    小菜仅实现了最基本的帧动画效果,对于效果的优化还未涉及;如有错误请多多指导!

来源: 阿策小和尚

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
移動開發工程師
手記
粉絲
168
獲贊與收藏
165

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消