Flutter 28: 易忽略的【小而巧】的技术点汇总 (五)

      小菜继续整理 Flutter 中日常用到的小知识点。

1. WillPopScope 返回导航

      小菜在做 Android 时经常会双击快速点击返回键弹出退出对话框,之后在进行操作,而 Flutter 也提供了监听返回导航的 WillPopScope,其中的回调方法返回一个 boolean 类型,true 时退出页面,false 时不退出,小菜设置在 1500ms 之内连续点击两次弹出提示框。在对时间进行监听时,小菜用到 Duration 可以设置时分秒毫秒微秒等,方便快捷。

class _MyHomePageState extends State<MyHomePage> {
  DateTime _lastPressedAt;

  @override
  Widget build(BuildContext context) {
   
    return WillPopScope(
        child: Scaffold(
            body: new SafeArea(
              top: true,
              child: new Center(child: childHomeWidget(context)),
            ),
        onWillPop: () async {
          if (_lastPressedAt == null ||
              DateTime.now().difference(_lastPressedAt) >
                  Duration(milliseconds: 1500)) {
            _lastPressedAt = DateTime.now();
            return false;
          } else {
            return showDialog(
                context: context,
                barrierDismissible: false,
                builder: (BuildContext context) {
                  return ExitDialog(
                      context: '您确定要退出吗?',
                      onCancelEvent: () {
                        Navigator.pop(context, false);
                      },
                      onSureEvent: () {
                        Navigator.pop(context, true);
                      });
                });
          }
        });
  }
}

2. onScaleUpdate 缩放监听

      小菜在处理图片时可能需要用到图片缩放方面的监听事件,查阅资料发现基本的 GestureDetector 便有监听方法 onScaleUpdate,这是一个回调方法,监听缩放时的比例和角度 ScaleUpdateDetails,其中 scalerotation 均不可为空。

class _GesturePageState extends State<GesturePage> {
  var _width = 300.0;
  var _height;

  @override
  Widget build(BuildContext context) {
    return new SafeArea(
        top: false,
        child: Scaffold(
            appBar: new AppBar(
              title: Text('图片缩放'),
            ),
            body: Center(
                child: GestureDetector(
                    child: Image.asset('images/icon_hzw02.jpg', width: _width),
                    onScaleUpdate: (ScaleUpdateDetails details) {
                      setState(() {
                        var num = details.scale.clamp(0.5, 2.0);
                        _width = 200 * num;
//                        _width = 400;
                      });
                    }))));
  }
}

3. FadeInImage 淡入图片

      小菜在上一篇博客中尝试了一下 CachedNetworkImage 缓存图片,这次发现了另一种 FadeInImage 淡入式图片,在图片的加载过程中有一个简单的动画效果,用户体验更好。FadeInImage 可加载本地图片/网络图片/内存图片,使用方式很简单。除了基本的图片大小/状态等,placeholderimage 两个参数必须存在,否则报异常。

FadeInImage(
  placeholder: AssetImage('images/icon_copylink.png'),
  image: AssetImage('images/icon_hzw01.jpg')
//  image: NetworkImage("https://flutter.io/images/catalog-widget-placeholder.png"
  )

      对于加载网络图片,FadeInImage 还提供了两种更便利的加载方式:

FadeInImage.assetNetwork
FadeInImage.assetNetwork(
    placeholder: 'images/icon_copylink.png',
    placeholderScale: 2.0,
    image: 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=703702342,1604162245&fm=26&gp=0.jpg')),
FadeInImage.memoryNetwork
FadeInImage.memoryNetwork(
    placeholder: kTransparentImage,
    image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1544938569112&di=feeab11968f3870520482630563c4f54&imgtype=0&src=http%3A%2F%2Fi1.hdslb.com%2Fbfs%2Farchive%2Fac5c906111130579c6909aae47f6656e20d0906b.jpg')),

Tips:

  1. 上述两种方式一般只用来加载网络图;
  2. FadeInImage.memoryNetwork 方式展位图用Uint8List资源(byte数组)加载,通常使用 transparent_image 透明来处理;
  3. FadeInImage.assetNetwork 占位图默认不是居中,位置需要自己调整。

4. ToolTip 提示框

      小菜在使用 FloatingActionButton 时,长按按钮会出现一个简短的提示信息,很方便,故特意学习一下 ToolTip,以后方便使用。

      ToolTip 默认是在点击范围底部展示,当底部范围不够时在顶部展示,也可以通过 preferBelow 进行设置,true 为底部,false 为顶部;而 ToolTip 展示的位置及大小可以通过 verticalOffsetheight 等属性共同配置。

Widget toolTipItemWid(var str, var color) {
  return Tooltip(
      message: str,
      child: Container(
          width: 150.0,
          height: 60.0,
          color: color,
          child: Center(
              child: Text(str,
                  style: TextStyle(color: Colors.white, fontSize: 16.0)))));
}

5. AspectRatio 比例布局

      小菜在学习大神博客时,发现 AspectRatio 可以设置布局的比例。设置父布局的宽或高可以根据 aspectRatio 展示子布局大小,比例 aspectRatio=width/high,注意 aspectRatio 必须存在且大于 0

Widget aspectRatioWid() {
    return Container(
        height: 200.0,
        child: new AspectRatio(
            aspectRatio: 0.5,
            child: new Container(color: Colors.lightBlueAccent)));
  }

      如上即会生成一个宽为 400 高为 200 的矩形,但实际情况还有很多,小菜逐一尝试,widthheight 均为根据比例计算之后的子布局大小,ScreenWidthScreenHeight 分别为屏幕宽高:

5.1 父布局宽固定 && width <= ScreenWidth && height <= ScreenHeight
return Container(
    width: 200.0,
    child: new AspectRatio(
        aspectRatio: 0.5,
        child: new Container(color: Colors.lightBlueAccent)));

      此时在屏幕上正常显示比例样式,如图:


5.2 父布局宽或高固定 && width <= ScreenWidth && height > ScreenHeight
return Container(
    width: 300.0,
    child: new AspectRatio(
        aspectRatio: 0.5,
        child: new Container(color: Colors.lightBlueAccent)));

      若按比例计算,width=300.0 & height=600.0,但 height 超过屏幕高度,所以全部占满,如图:

5.3 父布局宽固定 && width > ScreenWidth && height <= ScreenHeight
return Container(
    width: 600.0,
    child: new AspectRatio(
        aspectRatio: 2,
        child: new Container(color: Colors.lightBlueAccent)));

      若按比例计算,width=600.0 & height=300.0,但 width 超过屏幕高度,所以全部占满,如图:

5.4 父布局宽固定 && width > ScreenWidth && height > ScreenHeight
return Container(
    width: 600.0,
    child: new AspectRatio(
        aspectRatio: 0.5,
        child: new Container(color: Colors.lightBlueAccent)));

      若按比例计算,width=600.0 & height=1200.0,但 widthheight 均超过屏幕高度,所以全部占满,如图:

5.5 父布局高固定 && width <= ScreenWidth && height > ScreenHeight
return Container(
    height: 600.0,
    child: new AspectRatio(
        aspectRatio: 2,
        child: new Container(color: Colors.lightBlueAccent)));

      效果如 5.2

5.6 父布局高固定 && width > ScreenWidth && height <= ScreenHeight
return Container(
    height: 300.0,
    child: new AspectRatio(
        aspectRatio: 2,
        child: new Container(color: Colors.lightBlueAccent)));

      效果如 5.3

5.7 父布局高固定 && width > ScreenWidth && height > ScreenHeight
return Container(
    height: 600.0,
    child: new AspectRatio(
        aspectRatio: 2,
        child: new Container(color: Colors.lightBlueAccent)));

      效果如 5.4


      如果有不对的地方还希望多多指出。

来源:阿策小和尚

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

推荐阅读更多精彩内容