从0到1使用Flutter重构识兔(1)

383 阅读4分钟

前言

之前用react-native写过一版识兔,当初写识兔的时候就想过出视频来说一下该怎么架构RN项目,录过几集视频,但最终还是因为各种原因放弃了。 后期也会以文章的形式,把开发RN过程中的一些小技巧写出来。

在本系列文章中,会努力为读者梳理怎么架构Flutter项目,尽可能多的涉及flutter中的知识点与可能遇到的问题。

flutter版识兔也已经开源,放在了github上,点击跳转。 react-native版识兔地址,点击跳转

如果在开发中遇到什么问题,欢迎加入 flutter兴趣交流群 QQ群:541020533

目录

该标题下,会将本文中涉及到的知识点做梳理

  1. 搭建识兔首页
  2. 实现背景图片模糊
  3. 实现圆角按钮
  4. 实现圆角按钮进场效果

UI效果

真实效果会比gif好一些,gif压缩了画质

效果图

搭建识兔首页

在效果图中,首页分为两部分,顶部导航栏,中间内容。

1. 顶部导航栏

这里直接使用flutter自带的AppBar创建导航栏。

AppBar是属于Scaffold的一个属性方法,一般在开发flutter中都会把Scaffold放在最外层,用其提供的方便属性搭建页面框架。

AppBar中提供了很多属性/方法,这里不做详细讲解,本系列文章中,只会讲用到的方法,不会特别细致的讲组件提供的其他方法。

Scaffold(
    appBar: AppBar(
      title: Text('识兔'),
    ),
),

2. 中间内容

效果图中,中间内容包含了模糊背景图片和带有动画的按钮。 本文中,会实现背景图片 + 模糊效果 + 中间按钮。

背景图片(Image)

效果图中,首先实现的应该是背景图,在flutter中使用Image.network就可以加载网络图片了,所以我们的第一版代码应该是这样。

@override
Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('识兔'),
        ),
        body: Image.network(
            'http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg'),
      ),
   );
}

效果图

图片和导航栏出来了,但并不是图片不是全屏的效果。这里就要获取屏幕的高度了。

flutter中获取屏幕高度的方法有好几种,这里列出两种。

  • widgets.dart自带的MediaQuery,使用如下。
Size size = MediaQuery.of(context).size
final width = size.width;
final height = size.height;
  • 使用import 'dart:ui'提供的window.physicalSize,返回值同上。
Size physicalSize = ui.window.physicalSize;

只拿到屏幕宽度就够了吗?并不是,还需要给Image设置fit属性,这里直接给最终代码,对于fit的其他效果,可以自行测试。

body: Image.network(
    'http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg',
    fit: BoxFit.fitHeight,
    height: size.height,
)

效果图

组件层叠(Stack)

在实现模糊之前,需要先调整下层级关系。 为什么要这样呢? 因为接下来的模糊效果其实是覆盖在背景图上面的。

Stack允许子组件堆叠,我们将最外层改为Stack。代码如下

body: Stack(
    alignment: Alignment.centerLeft,
    children: <Widget>[
    Image.network(
        "http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg",
        fit: BoxFit.fitHeight,
        height: size.height,
        ),
    ],
),

可以看到Stack中拥有的children返回的是一个数组,这样我们可以接下来的步骤了。

高斯模糊(BackdropFilter)

BackdropFilterflutter中用来实现高斯模糊效果,在BackdropFilter源码中,会发现其必须要传filter,在源码中还推荐使用ImageFilter.blur来实现高斯模糊。 这里直接使用ImageFilter.blur来实现想要的效果。

body: Stack(
    alignment: Alignment.centerLeft,
    children: <Widget>[
        Image.network(
            "http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg",
            fit: BoxFit.fitHeight,
            height: size.height,
        ),
        BackdropFilter(
            filter: ImageFilter.blur(
                sigmaX: 5,  // x轴的模糊程度
                sigmaY: 5,  // y轴的模糊程度
            ),
            child: Container(
                color: Colors.white.withOpacity(0.1),
            ),
        ),
    ],
),

效果图

中间按钮(RaisedButton、FlatButton、OutlineButton,IconButton)

flutter中按钮提供了好几种,前三个都是集成自MaterialButton,但使用方式大同小异,只不过属性有点差别,本文用的是RaisedButton,因为其简单粗暴,但其他几个按钮,除了IconButton外,属性都大同小异,可以自行测试。 但这些都是flutter提供的Button,如果我们想要某个Widget加点击事件该怎么弄呢? 稍后的文章中会有讲解。

OutlineButton(
    child: Text(
        '点我搜索',
        style: TextStyle(color: Colors.white),
    ),
    onPressed: () {},               // 点击事件, 必填项
    color: Colors.lightBlue,        // 按钮颜色
    shape: shape: StadiumBorder(),  // 圆角
),

最终效果图

总结

本文中,只写出了首页搭建,下一篇文章会讲目录结构和按钮的动画效果。欢迎关注。

如果在开发中遇到什么问题,欢迎加入 flutter兴趣交流群 QQ群:541020533