- Flutter是一个由Google开发的开源移动应用软件开发工具包,用于为Android、iOS、 Windows、Mac、Linux、Google Fuchsia跨平台开发应用。作为一个UI框架,可以快速的基于上述操作系统构建高质量的原生用户界面。
- Flutter的主要组成部分包括:
- Dart平台
- Flutter引擎
- 基础库
- 定制化设计风格的组件
- Flutter相比其他跨平台技术的优点:
- 自绘UI + 原生渲染,调用系统API渲染,UI运行体验与原生应用相差无几,性能好且开发效率高
- Google提供了符合各个操作系统UI风格的控件,且可以自由组合构建自己想要的界面
- 多平台移植成本很低,无需为某个特定的操作系统添加额外的适配代码
- 开发生态日趋完善,可以在pub.dev找到近乎所有的类原生开发包
- Flutter 1.0版本于北京时间2018年12月5日发布以来,对于国内的很多开发者,直接阅读Google官方英文文档相对来说比较困难,而等待国内公开出版的Flutter相关书籍又显得太慢
- 官网上的示例代码稍显零碎,不太直观
- 想要运行起来零距离"触摸"下各种widget,体验下各种属性,往往得几经折腾
- 对于追一门偏向于实践且比较新的技术,往往抄起键盘来一边写一边看是相对比较快速的上手方法
- 基于上述现状,本项目旨在提供一个App形式的demo,将各路常用的控件"揣"在一起供大家把玩,部分场景甚至可以直接移植使用
- 相应的关键部位,在代码当中有相应的注释
- 力图一个App搞定所有Flutter常见控件的使用
- 不定期更新控件使用方式和pub依赖版本
- 路由界面
- 状态传递
- 基础控件
- 随机字符串(package:english_words/english_words.dart)
- 文本控件,字体样式(Text/TextStyle/Text.rich/TextSpan)
- 按钮系列(RaisedButton/FlatButton/OutlineButton/IconButton/FlatButton.icon/shape)
- 图片系列(ImageProvider/Image/Image.asset/Image.network)
- 单选开关和复选框Switch/Checkbox
- 输入框和表单(TextField/Form/TextFormField/FormState)
- 登录表单(TextField/Form/TextFormField/FormState)
- 各种样式的进度条(LinearProgressIndicator/CircularProgressIndicator)
- 布局控件
- 容器控件
- 填充(Padding/EdgeInsets)
- 尺寸限制(ConstrainedBox/BoxConstraints/SizedBox/UnconstrainedBox)
- 装饰(DecoratedBox)
- 变换(Transform/Matrix4(作用于绘制阶段)/RotatedBox(作用于布局阶段))
- 容器(Container(多种装饰和填充等组件的组合)/Padding/Margin)
- 裁减(Clip/CustomClipper(裁减动作的作用时期与Transform相同,都作用于绘制阶段))
- 通用类导航主界面(Scaffold/AppBar/TabBar/TabBarView/Drawer/FloatingActionButton)
- 列表控件
- 单child滚动控件(SingleChildScrollView/Scrollbar)
- 有限列表项情况下使用ListView(ListView)
- 众多列表项情况下使用ListView(ListView.builder)
- 带分割线的列表项情况下使用ListView(ListView.separated)
- 下拉刷新 和 上拉加载更多(初始化加载数据、结束时的标记、根据index判断底部是绘制结束的Widget还是正在加载时的Widget、Widget的正常显示)
- 有限GridView(GridView + SliverGridDelegateWithFixedCrossAxisCount)
- 有限GridView.count(效果完全等价于GridView + SliverGridDelegateWithFixedCrossAxisCount)
- 有限GridView(GridView + SliverGridDelegateWithMaxCrossAxisExtent)
- 有限GridView.extent(效果完全等价于GridView + SliverGridDelegateWithMaxCrossAxisExtent)
- 无限GridView加载(GridView.builder)
- 滚动监听(ScrollController/ScrollPosition)
- 触摸反馈
- 事件总线
- 通知
- 存储路径访问和文件操作
- 网络编程
- 功能控件及数据状态管理(InheritedWidget)
- Dialog
- AlertDialog
- SimpleDialog
- ListDialog
- 对话框状态管理(StatefulBuilder实现)
- 对话框状态管理(markNeedsBuild实现)
- 底部sheet(showModalBottomSheet)
- 对话框之LoadingDialog
- 对话框之DatePicker
- 对话框之IOS风格DatePicker
- 应用主题切换(Theme/ThemeData(内部通过InheritedWidget实现))
- 与原生互调和相互集成(MethodChannel.invokeMethod)
- WebView Flutter(webview_flutter)
- 开发者通用设置(MaterialApp)
- 是否显示界面布局网格(debugShowMaterialGrid)
- 是否打开性能监控,覆盖在屏幕最上面(showPerformanceOverlay)
- 是否打开栅格缓存图像的检查板(checkerboardRasterCacheImages)
- 是否打开显示到屏幕外位图的图层的检查面板(checkerboardOffscreenLayers)
- 是否打开覆盖图,显示框架报告的可访问性信息,显示边框(showSemanticsDebugger)
- 是否显示右上角的Debug标签(debugShowCheckedModeBanner)
- 切换操作系统平台(Android/iOS)
- 切换为Android应用: debugDefaultTargetPlatformOverride = TargetPlatform.android
- 切换为iOS应用: debugDefaultTargetPlatformOverride = TargetPlatform.iOS
- 动画
- 自定义控件
- 国际化
- 内含大量gif图,loading可能会比较耗时,依自身网速而定
OS平台应用包 | QRCode |
---|---|
Android APK包下载(内测密码:123456) |
OS平台应用包 | QRCode |
---|---|
iOS 包下载( 虚位以待 ) |
- web地址: 虚位以待
- Waiting for another flutter command to release the startup lock...
- 因为已经有一个Flutter命令正在运行,删除SDK中的flutter/bin/cache/lockfile文件重新运行即可
- 因为GFW的封锁,强烈建议使用国内高校镜像网站: 清华大学开源软件镜像站
- XXX called with a context that does not contain a Scaffold...
- 注意要在State中的body节点对应new一个Builder,且通过命名参数显式的传递一个上下文参数,否则就会报如上错误
- 具体写法可参照代码: https://stackoverflow.com/questions/51304568/scaffold-of-called-with-a-context-that-does-not-contain-a-scaffold
- Failed assertion: line 25 pos 15: 'child != null': is not true...
- 某个控件树下没有对应的设置child节点
- 修改应用名称和应用logo无效...
- 只修改main.dart文件中MaterialApp节点下的title是不行的,title不全等价于App在手机上的应用名。对应的还需要修改相应平台的名称: Android/iOS。
- 原生平台的应用名称修改分别在android/app/src/main/AndroidManifest.xml和ios/Runner/Info.plist下
- 同理,修改应用logo也遵循此原则
- The method 'showSnackBar' was called on null...
- 调用showSnackBar方法显示SnackBar时,往往是在与一个StatefulWidget对应的State类中调用
- 在State对应的子类的body节点中,需要new一个Builder并传递一个上下文,通过上下文find到父类中对应的ScaffoldState对象,进而调用showSnackBar显示SnackBar
- 否则,会出现没有对应的上下文对象所导致的NPL
- Positioned宽度width和高度height的计算...
- width的计算会基于left和right进行, 当指定left和width后,right会自动算出(left+width),如果同时指定width/left/right属性则会报错
- height的计算会基于top和bottom进行,当指定top和height后,bottom会自动算出(top+height),如果同时指定height/top/bottom属性则会报错
- 在事件冒泡过程中
- 深坑: 当给底部Container控件设置color后,任何behavior(opaque/translucent/deferToChild)将会失效
- Flutter如何更改App包名?
1.) src/profile/AndroidManifest.xml
2.) src/debug/AndroidManifest.xml
3.) src/main/AdroidManifest.xml
4.) build.gradle .
defaultConfig {
applicationId
5.) MainActivity.java on "package"
- Flutter更改versionCode及versionName
- pubspec.yaml文件中默认有version: 1.0.0+1,其中+之前的"1.0.0"对应versionName,+后边的"1"对应versionCode.
- 打release包
- Flutter command not found
- 打开终端
- open .bash_profile
- export PATH=/Users/yangyi/developer/flutter/bin:$PATH
- 上述PATH后的部分为你的Flutter SDK路径
- 保存
- 设置当前操作系统平台
- AppBar设置actions节点后,debugDefaultTargetPlatformOverride = TargetPlatform.iOS切换iOS效果不起作用
- 迁移FlutterActivity以兼容WebView和MethodChannel
- io.flutter.app.FlutterActivity类已过时,官方推荐需要迁移到io.flutter.embedding.android.FlutterActivity
- 但是迁移至io.flutter.embedding.android.FlutterActivity后会找不到FlutterView,需要用flutterEngine.getDartExecutor()代替
- flutterEngine在configureFlutterEngine回调中可以拿到,通过flutterEngine.getDartExecutor()获取最终传入MethodChannel的值
- 本人学(cai)习(keng)中的一些小体会(主观居多︿( ̄︶ ̄)︿)
- 先说Dart
- Dart语言是基于Java、JavaScript的部分语法,还糅合了Kotlin的部分语法糖的一门语言,本身是融合的产物,估计Google的初衷是想"博采众长"
- Dart语言本身比Java更加简练,也加入了一些Java中没有的语法糖。比如async和await,本质其实还是个Future
- 对于已经习惯了Rx系列链式编程的人来说,Dart天然自带。如果觉得链式书写的"链"太长"影响市容"的话,还可以采用类似Kotlin中协程的写法非常舒服的书写异步任务,基本上在Dart语言中不会出现callback hell
- 对于掌握上述任何一种语言的人来说,近乎可以以极小成本上手Dart
- 再说Flutter
- Flutter本质上其实算一个UI框架,一套代码到处跑。UI框架+原生引擎渲染
- 一套优秀的Flutter代码,理论上可以在Android/iOS/Web/Fuchsia各种环境和操作系统上运行,并且保证UI界面的高度一致性
- Flutter的数据结构体系,本质上与其他技术栈对于UI层控件的处理类似,都是一颗多叉树,创建并渲染UI的过程本质上就是建树和走树的过程
- 在写Flutter的过程中,有时候甚至觉得自己不是在"写代码",更像是在一棵"树"上画画
- 对于有任何一端移动开发经验尤其是Android开发经验的同学来说,Flutter的上手门槛是0
- 先说Dart