Flutter :几个常用的知识点

简介: 本文介绍几个在 Flutter 中常用的知识点。

1. BoxFit 各个值得含义

在使用 Image Widget 展示一张图片时,我们通过 fit 参数给它设置图片的拉伸规则,例如:

Image.asset('assets/top.jpeg',fit: BoxFit.cover),

BixFit 本身是一个枚举:

它是表示将一个 box 内置到另一个 box 中时,如何利用外层 box 的剩余空间。

enum BoxFit {
   
   
  fill,

  contain,

  cover,

  fitWidth,

  fitHeight,

  none,

  scaleDown,
}

1.1 BoxFit.fill

充满父容器。为了适应父容器,宽和高有可能被拉伸或者压缩而导致变形。

1.2 BoxFit.contain

尽可能大,但同时保证不超过父容器的边界。如果子元素的宽和高不能与父容器的宽高匹配,那么子元素的左右两侧或者上下有可能留有空白区域。

1.3 BoxFit.cover

充满容器,可能会被截断。

1.4 BoxFit.fitWidth

图片填满宽度,高度可能会被截断。

1.5 BoxFit.fitHeight

图片填满高度,宽度可能会被截断

1.6 BoxFit.none

默认居中展示在容器的中间,如果超出父容器的宽高,那么超出的部分会被截断;如果没有超出父容器的宽高,直接居中展示。

1.7 BoxFit.scaleDown

默认居中展示在容器的中间,如果超出父容器的宽高,将其进行缩小,以保证全部展示,这点和 BoxFit.contain 一样;如果没有超出父容器的宽高,直接居中展示,这点和 BoxFit.none 一样。

2. Stateful and stateless widgets

有状态的 Widget 和无状态的 Widget 唯一的区别就是看它与用户交互以后,Widget 是否会发生变化。

比如用户可以进行勾选的 Checkbox

一个 widget 的状态保存在一个 State 对象中,它和 widget 的显示分离。 Widget 的状态是一些可以更改的值,如一个复选框是否被选中。当 widget 状态改变时,State 对象调用 setState(),告诉框架去重绘 widget。

如何创建一个 StatefulWidget

需要创建两个类:一个 StatefulWidget 的子类和一个 State 的子类。

例子:点击收藏按钮,更新收藏数量

///创建 StatefulWidget 的子类
///
///FavoriteWidget 类管理自己的状态,因此它通过重写 createState() 来创建状态对象。框架会在构建 widget 时调用 createState()。
///在这个例子中,createState() 创建 _FavoriteWidgetState 的实例,将在下一步中实现该实例。
class FavoriteWidget extends StatefulWidget {
   
   
  
  _FavoriteWidgetState createState() => _FavoriteWidgetState();
}
class _FavoriteWidgetState extends State<FavoriteWidget> {
   
   
  //状态对象存储的信息在 _isFavorited 和 _favoriteCount 变量中。
  bool _isFavorited = true;//是否收藏
  int _favoriteCount = 41;//收藏数量

  
  Widget build(BuildContext context) {
   
   
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          padding: EdgeInsets.all(0),
          child: IconButton(
            padding: EdgeInsets.all(0),
            alignment: Alignment.centerRight,
            icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)),
            color: Colors.red[500],
            onPressed: _toggleFavorite,
          ),
        ),
        SizedBox(
          width: 18,
          child: Container(
            child: Text('$_favoriteCount'),
          ),
        ),
      ],
    );
  }

  void _toggleFavorite() {
   
   
  setState(() {
   
   
    if (_isFavorited) {
   
   
      _favoriteCount -= 1;
      _isFavorited = false;
    } else {
   
   
      _favoriteCount += 1;
      _isFavorited = true;
    }
  });
}
}

运行效果

3. Flutter 中的页面指的是什么?

在 Flutter 中我们使用 screen 表示一个页面,它的本质就是一个 Widget

那什么是路由呢?

在 Android 开发中,Activity 相当于“路由”,在 iOS 开发中,ViewController 相当于“路由”。在 Flutter 中,“路由”也是一个 widget。

4. Flutter 页面之间如何传值?

在 Flutter 中从一个页面导航到另一个页面主要有两种方式:

  1. Navigator.push()
onPressed: () {
   
   
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),
  );
}
  1. 命名路由 Navigator.pushNamed()
onPressed: () {
   
   
  Navigator.pushNamed(context, '/second');
}

使用不同的导航方式,传值的方式也不同,下面分别来说一下:

4.1 使用 Navigator.push() 传值的方式有两种

第一种:通过构造函数传值

先在目标页面定义好构造函数

class SecondScreen extends StatelessWidget {
   
   
  //SecondScreen 页面需要一个 title 参数
  SecondScreen({
   
   Key key,  this.title}) : super(key: key);

...
}

传值:

onPressed: () {
   
   
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => SecondScreen(title: '参数',)
    )
  )
}

第二种:使用 RouteSettings 传递参数

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => RouteManager(),
    settings: RouteSettings(arguments: '参数')
  )
)

接收参数:ModalRoute.of(context).settings.arguments

class SecondScreen extends StatelessWidget {
   
   
  
  Widget build(BuildContext context) {
   
   
    //接收参数
    final String title = ModalRoute.of(context).settings.arguments;

    // Use the title to create the UI.
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text(title),
      ),
    );
  }
}

4.2 使用 Navigator.pushNamed() 时的传值方式

Navigator.pushNamed(
  context,
  '路由名称',
  arguments:'参数'
)

接收参数同样可以用:ModalRoute.of(context).settings.arguments

4.3 适配

那么这里有一个问题,假如一个页面,它的构造函数必须接收一个参数,同时呢,我也想用命令路由的方式跳转到该页面,应该怎么做呢?

假设这个页面是:

class SecondScreen extends StatelessWidget {
   
   
  //SecondScreen 页面需要一个 title 参数
  SecondScreen({
   
   Key key,  this.title}) : super(key: key);

  final String title;

...
}

路由注册方式:

class MyApp extends StatelessWidget {
   
   
  
  Widget build(BuildContext context) {
   
   
    return MaterialApp(

      //省略无语代码
      ...

      //注册路由表
      routes: {
   
   
        'second': (context) => SecondScreen(
              title: ModalRoute.of(context).settings.arguments,
            ),
      },
    );
  }
}

4.4 从一个页面回传数据

上面介绍了跳转一个新路由时如何传值,那么如果我返回上一个页面的话,如果回传数据呢?

Navigator.pop(context, '回传的值');

接收上个页面返回的值,并通过一个 SnackBar 来显示:

void _navigateAndDisplay(BuildContext context) async {
   
   
  //导航并接收结果
  final result =
      await Navigator.pushNamed(context, 'second', arguments: '参数');

  Scaffold.of(context)
    ..removeCurrentSnackBar()
    ..showSnackBar(SnackBar(content: Text("$result")));
}

5. 跨页面切换的动效 Widget (Hero animations)

如何在页面切换时为某个组件加上转场动画,从而在两个页面间建立视觉上的锚定关联。如下如所示:

Flutter 为我们提供了 Hero animations 来实现:

代码示例:

///第一个页面
class HeroDemoScreen extends StatelessWidget {
   
   
  static const routeName = '/HeroDemoScreen';

  
  Widget build(BuildContext context) {
   
   
    return Scaffold(
      appBar: AppBar(
        title: Text('Hero animations'),
      ),
      body: GestureDetector(
        child: Hero(
            tag: 'imageHero',
            child: Image.network('https://picsum.photos/250?image=9')),
        onTap: () => {
   
   Navigator.pushNamed(context, ImageScanScreen.routeName)},
      ),
    );
  }
}
///第二个页面
class ImageScanScreen extends StatelessWidget {
   
   
  static const routeName = '/ImageScanScreen';

  
  Widget build(BuildContext context) {
   
   
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('查看图片'),
      ),
      body: GestureDetector(
        child: Center(
          child: Hero(
              tag: 'imageHero',
              child: Image.network('https://picsum.photos/250?image=9')),
        ),
        onTap: ()=>{
   
   
          Navigator.pop(context)
        },
      ),
    );
  }
}

为了通过动画在两个页面间建立联系,需要把每个页面的 Image 组件都包裹进 Hero 组件里面。 Hero 组件有两个参数:

  1. tag
    作为 Hero 组件的标识,在这两个页面中必须相同。

  2. child
    在两个屏幕直接跨越的那个 widget,在本例中就是 Image。

Hero(
  tag: 'imageHero',
  child: Image.network(
    'https://picsum.photos/250?image=9',
  ),
);
相关文章
|
Dart Java
flutter开发之必须掌握的dart知识点:list,set,map
要说,List在我的开发使用中,确实是最为频繁的了,那么如何使用list,也就成了一个问题,list提供的方法又有哪些 这些都是需要掌握理解的。 首先第一个, 对于固定长度的list,如何删除添加元素呢
615 0
|
27天前
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
18 1
|
12天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
144 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
28天前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
116 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
17天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
124 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
25天前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
75 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
15天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
38 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
89 18
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
30天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
80 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
1月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
36 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 4
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 6
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
  • 7
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 9
    【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 10
    flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    28
  • 2
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
    59
  • 3
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
    42
  • 4
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    144
  • 5
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    38
  • 6
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    73
  • 7
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    124
  • 8
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    75
  • 9
    flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
    18
  • 10
    【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    29