Flutter : 图片, 动画, 异步, 手势检测, 主题及文字的处理

Image Widget

    1. Image Widget简介
    • 屏幕快照 2019-06-13 下午2.52.33.png
    1. 支持的图片格式
    • 屏幕快照 2019-06-13 下午2.53.15.png
    1. 如何加载网络图片
    • 屏幕快照 2019-06-13 下午2.54.36.png
    1. 如何加载静态图片, 以及处理不同分辨率的图片
    • 声明图片路径
    • 使用AssetImage / Image.asset访问图图片
    1. 如何加载本地图片
    • 加载完整路径的本地图片
    • 加载相对路径的本地图片
    1. 如何设置placeholder

    为了设置Placeholder我们需要借助FadeInImage, 它能够从内存, 本地资源中加载placeholder

    • 从内存中加载placeholder
    • 从本地资源中加载placeholder
    1. 如何配置图片缓存
    • 屏幕快照 2019-06-13 下午3.25.32.png
    1. 如何加载Icon
    • Icon的使用
    • 具体代码
    • 自定义的Icon

Flutter : 动画

    1. 在Flutter中有哪些动画?
    • 屏幕快照 2019-06-19 上午10.11.07.png
    1. 如何使用动画库中的基础类给widget添加动画?
    • 屏幕快照 2019-06-19 上午10.12.16.png
    • Animation
    • CurvedAnimation
    • AnimationController
    • AnimationController注意事项
    • Tween
    • Tween.animate
    1. 为widget添加动画
    • 代码示例
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    
    class AnimateDemoPage extends StatefulWidget {
      AnimateDemoPage({Key key}) : super(key: key);
    
      _AnimateDemoPageState createState() => _AnimateDemoPageState();
    }
    
    class _AnimateDemoPageState extends State<AnimateDemoPage>
        with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
      AnimationStatus animationState;
      double animationValue;
      @override
      void initState() {
        super.initState();
        controller =
            AnimationController(duration: const Duration(seconds: 2), vsync: this);
        animation = Tween<double>(begin: 0, end: 300).animate(controller)
          ..addListener(() {
            setState(() {
              animationValue = animation.value;
            });
          })
          ..addStatusListener((AnimationStatus status) {
            setState(() {
              animationState = status;
            });
          });
      }
      
      @override
      void dispose() {
        // TODO: implement dispose
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: EdgeInsets.only(top: 100),
          child: Column(
            children: <Widget>[
              GestureDetector(
                onTap: (){
                  controller.reset();
                  controller.forward();
                },
                child: Text('Start', textDirection: TextDirection.ltr,),
              ),
              Text('State: ' + animationState.toString(), textDirection: TextDirection.ltr,),
              Text('Value: ' + animationValue.toString(), textDirection: TextDirection.ltr,),
              Container(
                height: animation.value,
                width: animation.value,
                color: Colors.red,
                child: Icon(Icons.fullscreen, color: Colors.blue,),
              )
            ],
          ),
        );
      }
    }
    
    1. 如何为动画提供监听器
    • 屏幕快照 2019-06-19 上午10.31.14.png
    1. 用AnimatedWidget与AnimatedBuilder简化和重构我们对动画的使用
    • 什么是AnimatedWidget?
    • 代码示例
    class AnimatedLogo extends AnimatedWidget  {
      const AnimatedLogo({Key key, Animation<double> animation}) : super(key: key, listenable: animation);
    
      @override
      Widget build(BuildContext context) {
        final Animation<double> animation = listenable;
        return Center(
          child: Container(
            margin: new EdgeInsets.symmetric(vertical: 10.0),
            height: animation.value,
            width: animation.value,
            child:  new Text('测试'),
          ),
        );
      }
    }
    
    class LogoApp extends StatefulWidget  {
      LogoApp({Key key}) : super(key: key);
    
      _LogoAppState createState() => _LogoAppState();
    }
    
    class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
    
      AnimationStatus animationState;
      double animationValue;
      @override
      void initState() {
        super.initState();
        controller =
            new AnimationController(duration: const Duration(seconds: 2), vsync: this);
        animation = Tween<double>(begin: 0, end: 300).animate(controller)
          controller.forward();
      }
      
      @override
      void dispose() {
        // TODO: implement dispose
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedLogo(animation: animation,);
      }
    }
    
    1. AnimatedBuilder
    • AnimatedBuilder概述
    • AnimatedBuilder树状图
    • 代码示例
    class LogoApp extends StatefulWidget  {
      LogoApp({Key key}) : super(key: key);
    
      _LogoAppState createState() => _LogoAppState();
    }
    
    class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
    
      AnimationStatus animationState;
      double animationValue;
      @override
      void initState() {
        super.initState();
        controller =
            new AnimationController(duration: const Duration(seconds: 2), vsync: this);
        animation = Tween<double>(begin: 0, end: 300).animate(controller);
        controller.forward();
      }
      
      @override
      void dispose() {
        // TODO: implement dispose
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return 
        GrowTransition(
          childWidget: LogoWidget(),
          animation: animation,
        );
        // return AnimatedLogo(animation: animation,);
      }
    }
    
    class LogoWidget extends StatelessWidget {
      const LogoWidget({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: EdgeInsets.symmetric(vertical: 10),
          child: Text('LogoWidget'),
        );
      }
    }
    
    
    class GrowTransition extends StatelessWidget {
      const GrowTransition({this.animation, this.childWidget});
    
      final Widget childWidget;
      final Animation<double> animation;
      @override
      Widget build(BuildContext context) {
        return Center(
          child: AnimatedBuilder(
            animation: animation,
            builder: (context, child) => Container(
              height: animation.value,
              width: animation.value,
              child: child,
            ),
            child: childWidget,
          ),
        );
      }
    }
    
    1. Hero动画
    • Hero动画概述
    • 代码示例
    import 'package:flutter/material.dart';
    
    class HeroAnimation extends StatelessWidget {
      const HeroAnimation({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        double timeDilation = 10.0;
        return Scaffold(
          appBar: AppBar(
            title: Text('Basic Hero Animation'),
          ),
          body: Center(
            child: PhotoHero(
              photo: '',
              width: 300,
              ontap: () {
                Navigator.of(context)
                    .push(MaterialPageRoute<void>(builder: (BuildContext context) {
                  return Scaffold(
                    appBar: AppBar(
                      title: Text('Flippers Page'),
                    ),
                    body: Container(
                      color: Colors.lightBlueAccent,
                      padding: EdgeInsets.all(15.0),
                      alignment: Alignment.topLeft,
                      child: PhotoHero(
                          photo: '',
                          width: 300,
                          ontap: () {
                            Navigator.of(context).pop();
                          }),
                    ),
                  );
                }));
              },
            ),
          ),
        );
      }
    }
    
    class PhotoHero extends StatelessWidget {
      final VoidCallback ontap;
      final double width;
      final String photo;
      const PhotoHero({Key key, this.photo, this.width, this.ontap})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: width,
          child: Hero(
            tag: photo, // 关联两个动画的标识
            child: Material(
              color: Colors.transparent,
              child: InkWell(
                onTap: ontap,
                child: Image.network(photo, fit: BoxFit.contain),
              ),
            ),
          ),
        );
      }
    }
    
    

Flutter的异步代码

    1. 如何编写异步的代码?
    • async/await & Isolate
    • async/await的使用
    1. 如何把工作放到后台线程执行?
    • async/await关键字
    • Isolate的使用方法
    • Isolate代码示例
    • Isolate代码示例
    1. 如何进行网络请求
    • http网络请求使用
    1. 如何为长时间运行的任务添加一个进度指示器?
    • ProgressIndicator的使用
    • 代码示例 - 1
    • 代码示例 - 2

手势检测 / 触摸事件处理

    1. 如何给Flutter的widget添加一个点击事件的监听?
    • 第一种方法
    • 第二种方法
    1. 如何处理widget上的其他手势?
    • 屏幕快照 2019-06-25 上午10.50.36.png

主题和文字处理

    1. 如何在Text widget上设置自定义字体?
    • 添加字体
    • 使用字体
    1. 如何在Text上定义样式?
    • Text的属性
    1. 如何给App设置主题?
    • 主题概述
    • 代码示例

Flutter调试技巧

    1. 调试技巧概述:
    • Flutter调试技巧
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容