Flutter新手入坑指南

写在前面


    在做Flutter项目,我之前从事的是iOS开发,以object-C为主,Swift为辅。对Flutter也是从小白开始,因此这个过程中我踩过的坑,对于即将入坑的开发者来说还是具有普遍的先行者意义。希望各位读者,可以从中受到启发,从而绕过某些坑,在Flutter的开发之路上走得更快更稳健,那么也是我这篇文章最大的作用了。

价值论与方法论


    相信大家都清楚,无论是object-C还是Swift,都是一种命令式编程。因此在我前几年的开发过程中,会被该语言特性潜移默化的塑造,脑子里的思维模型完全是被驯化成面向过程的。即:面对一个功能点,我马上想到的是我要得到这个结果,那么编译器你应该按照1、2、3点一步一步来做,先做什么,再做什么,最后做什么。

    但是Flutter完全不同,它是一种声明式编程。它要得到某个结果,只需要告诉编译器应该做什么,但是不指定具体要怎么做。

    正是由于这种思维定势的转换,是我首先需要克服的最大障碍。就像一个对孩子事事操心了18年的老父亲,突然在孩子成年后,不能再给出具体方法论,而是只能指出价值论的转变。期间的不适应是必须的,但是需要适应,需要适应这种不适应。

    如果这种思维转换过来了,那么接下来就是单独面对这门语言的问题了。

工欲善其事必先利其器


    开发工具:Vscode,Android Studio

    利用Android Studio开发工具,预先设置快捷指令,可以让我们后期的开发过程事半功倍。下面我给出自己使用比较频繁的供大家参考。P.S.如果快捷指令有出入,各读者可以在自己的Android Studio上打开Preferences自行设置。

代码行复制:cmd+ a

查找文件:cmd +shift+ o/a

动态模式:cmd + j

代码上下移动:alt +shift+ up/down

代码展示/折叠:cmd + +/-

代码对齐:ctrl + alt  + l

代码包裹:option(alt) + enter

statelessWidget转statefulWidget:option(alt) + enter

将build出来的Widget抽取到单独的widget中:option(alt) + enter + w

抽象类的实现类,方法的具体实现:command+ alt + B

格式化:command+ option(alt) + l

快速生成getter,setter,toString,constructor:command+ n

Dart先行


    Dart是一种开源的通用编程语言。它最初由Google开发,后来被ECMA批准为标准。Dart是一种新的编程语言,适用于服务器和浏览器,现也被谷歌应用在Flutter中。

1.在线执行脚本:

可以使用https://dartpad.dartlang.org/上的在线编辑器在线运行测试脚本。

2.Dart标识符:

标识符是程序中元素的名称,如变量,函数等。标识符的规则是 -

标识符可以包括字符和数字。但是,标识符不能以数字开头。

除下划线(_)或美元符号($)外,标识符不能包含特殊符号。

标识符不能是关键字。

它们必须是唯一的。

标识符区分大小写。

标识符不能包含空格。

3.Dart数字方法:

abs:返回数字的绝对值

ceil:返回不小于该数字的最小整数

compareTo:将此与其他数字进行比较

floor:返回不大于当前数字的最大整数

remainder:除以两个数后,返回截断的余数

round:返回最接近当前数字的整数

toDouble:返回数字的double等效值

toInt:返回数字的int等效值

toString:返回数字的字符串等效表示形式

4.Dart函数定义:

function_name() {

    statements     

}

或者

void function_name() {

    statements

}

void关键字表示该函数不向调用者返回任何值。

5.级联运算符(..)

class Student {

    void test_method() {

        print("This is a  test method"); 

    }

    voidtest_method1() {

        print("This is a  test method1"); 

    }

}

void main() {

    new Student() 

    ..test_method()   

    ..test_method1();

}

级联(..)运算符可用于通过对象发出一系列调用。

更多的Dart语法学习,推荐直通车:

https://www.yiibai.com/dart

Flutter随后


    中心思想:万物皆Widget

    在学习过程中,我做了Flutter跟OC的等价:

MaterialApp ~ rootViewController

Scaffold ~ UIViewController

Widget ~ UIView

ListView ~ UITableView

GridView ~ UICollectionView

1.生命周期

先学习statefulWidget生命周期的意义:初始化数据,状态;网络请求;事件监听;内存管理等;

widget的constructor(init)方法:

构造函数widget的createState()方法

state的constructor()构造方法

state的initState()方法,必须调用 super.initState()

state的didChangeDependencies()方法

state的build()方法

state的dispose()销毁方法

注:

didUpdateWidget方法:当父类的结构发生改变时,则该方法会调用。

生命周期复杂版:state中的属性:dirty==true会调用build;mounted,是state内部属性;

clean表示当前build出来的widget,下次重绘时不需要重build;

创建

State 初始化时会依次执行 :构造方法 -> initState -> didChangeDependencies -> build,随后完成页面渲染。

更新

Widget 的状态更新,主要由 3 个方法触发:setState、didChangeDependencies 与 didUpdateWidget。

销毁

组件销毁相对比较简单。比如组件被移除,或是页面销毁的时候,系统会调用 deactivate 和 dispose 这两个方法,来移除或销毁组件。

获取屏幕尺寸的方法:

MediaQuery.of(context).size

MediaQuery.of(context).size=window.physicalSize/window.devicePixelRatio

2.Flutter与Native通信

Flutter定义了三种不同类型的Channel:

BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息。

MethodChannel:用于传递方法调用,一次性通信。比如拍照。

EventChannel:用于数据流通信,持续通信,收到消息后无法回复此次消息,通常用于Native向Dart的通信。比如:手机电量变化,陀螺仪,传感器,网络变化等。

注:

在Flutter中,Native向Dart传递消息可以通过BasicMessageChannel或者EventChannel都可以实现。

在Flutter中,Dart向Native传递消息可以通过BasicMessageChannel或者MethodChannel都可以实现。

3.Widget的显示与隐藏

AnimatedOpacity(opacity: 1);

Offstage(offstage: ture);

Size为0的占位container

4.去掉水波纹或者高亮效果

theme:ThemeData(highlightColor:Colors.transparent,)

5.Flutter动画

Animation抽象类,监听动画值的改变,监听状态改变,value,status

AnimationController继承自Animation,vsycn:同步信号(this -> with SingleTickerProviderStateMixin)  forward()向前执行动画  reverse()反转执行动画

CurvedAnimation:设置动画执行的速率(速度曲线)

Tween:设置动画执行的value范围。begin开始值  end结束值 

1.创建AnimationController_controller = AnimationController(  vsync: this,  duration: Duration(seconds: 2))

2.设置Curve的值 _animation = CurvedAnimation(parent: _controller, curve: Curves.linear);

3.Tween _sizeAnim = Tween(begin: 50.0, end: 150.0).animate(_animation);

4.监听值的状态改变_controller.addStatusListener((status) {  if (status == AnimationStatus.completed) { _controller.reverse() }})

6.路由

    路由的概念由来已久,包括网络路由,后端路由,到现在流行的前端路由。

    无论路由的概念如何应用,它的核心是一个:路由映射表。比如,名字detail映射到DetailPage页面等。

    在Flutter中,路由管理主要有两个类:Route, Navigator

Route:这是一个应用程序抽象的屏幕或者页面。一个页面要想被路由统一管理,必须包装到路由管理。

MaterialPageRoute在不同平台有不同的表现。当然,iOS平台我们也可以使用CupertinoPageRoute.

Navigator:这是一个管理路由的widget。管理所有的Route的Widget,通过一个栈来进行管理的。开发中不需要手动创建一个Navigator,开发中使用的MaterialApp,CupertinoApp,WidgetsApp默认是有插入Navigator的。

以上两种widget对应Flutter中实现页面导航的有两种选择:

—具体指定一个由路由名构成的Map。(MaterialApp)

—直接跳转到一个路由。(WidgetApp)

例如:

MaterialApp(routes:{‘/a’:(BuildContext ctx) =>MyPage(title:’page A’)})通过把路由的名字push给一个Navigator来跳转:Navigator.of(context).pushNamed(‘/a’);还可以使用Navigator的push方法。以下示例中,MaterailPageRoute widget是一种模板路由,它根据平台自适应替换整个页面。Navigator.push(context, MaterialPageRoute(builder:(BuilderContext context) =>UsualNavscreen()));

Future result = Navigator.of(context).push(MaterialPageRoute( builder(ctx) {returnHYFindPage() } )); result.then((res) { })//用于接收下级页面传回来的值 下一个页面取出数据finaldata= ModalRoute.of(context).settings.argumentsasHYModel;

onGenerateRoute:(setting) {if(setting.name == @“one”) { }}

onUnknownRoute:(settings) { 跳转到未知页面 }willPopScope(onWillPop: () {returnFuture.value(ture)}  child: Scaffold())

如何获取路由跳转返回的结果?

Mapresult =awaitNavigator.of(context).pushNamed(‘/a’);Navigator.of(context).pop({“lat”:123, “lon”:234});

Flutter第三方插件


轮播插件:Flutter-swiper

屏幕适配插件:flutter_screenUtil

网络请求库:flutter_dio

打电话,发邮件插件 :url_launcher

上拉加载下拉刷新库:flutter_easyrefresh

位置信息GPS插件:geolocator

相册与相机插件:image_picker

本地存储插件:SharedPreferences Plugin

访问数据库的插件:SQFlite

唤起第三方登录的插件:flutter_facebook_login

推送通知的插件:firebase_messaging

使用Firebase的插件:firebase plugin

关于Flutter直通车


变更记录:https://github.com/flutter/flutter/wiki/Changelog

公告:https://groups.google.com/g/flutter-announce?pli=1

博客:http://www.devio.org/tags/#Flutter  http://www.imooc.com/t/4951150#article

第三方库查找:https://pub.dartlang.org/Flutter

官方仓库:https://github.com/flutterFlutter

官方文档:https://flutter.dev/Flutter

官方讨论邮件:https://groups.google.com/forum/#!forum/flutter-devFlutter

问题&方案:

Google:https://www.google.com

stackoverflow:https://stackoverflow.com

官库-issue:https://github.com/flutter/flutter/issues

Flutter第三方库:https://dart.dev/

网络请求测试:https://httpbin.org/

Flutter中文网:https://flutterchina.club/cookbook/

Flutter SDK:https://api.flutter.dev/

数据转换模型:https://app.quicktype.io/

写在最后


    由于我也是刚入坑不久,难免挂一漏万,期间如果有错误,希望各位读者雅正。先在此谢过!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容