一位Android程序员入坑Flutter后整理出一份超详细的学习笔记

通过对三种跨平台引擎的大致了解,我们可以看出来,他们都达到了一定程度的Native体验,然则各自都有一定的性能损耗,比如RN的JS引擎加载JS,以及Bridge通信的损耗,Xamarin Mono虚拟机与Java通信的损耗,以及Flutter Skia渲染与Native Android渲染的差异等。

Flutter笔记


如何启动一个app

Android需要在Manfest里面指定带有MAIN action与LAUNCHER category的Activity声明,而Flutter只需要一行。

void main() => runApp(MyApp());

其中MyApp就是一个普通的Widgets(View).

View vs Widgets

Flutter没有View,与之对应的是Widget,并且分为StatelessWidgets与StatefulWidgets,前者是个静态View,后者是动态通过Data来更新的View。

  • Stateless

Text(

‘I like Flutter!’,

);

  • Stateful

class StatefulText extends StatefulWidget {

@override

State createState() => _TextState();

}

class _TextState extends State {

// Default placeholder text

String textToShow = “I Like Flutter”;

void _updateText() {

setState(() {

// update the text

textToShow = “Flutter is Awesome!”;

});

}

@override

Widget build(BuildContext context) {

…invoke _updateText

}

}

实际上是因为StatefulWidgets通过调用StatesetState方法来触发整个Widgets树的重绘,并且在重绘之前会调用传进去的(){ ... }block。

怎么写Layout, XML到哪里去了

实际上Flutter没有xml了, 并且是通过Widgets的嵌套来实现一个布局的。

如:

  • Center是一个可以把子View放置在中央的容器;

  • Row对应的就是LinearLayout + Horizontal,Column对应的就是LinearLayout + Vertical,他们都具备一个属性叫做crossAxisAlignment,有点类似gravity,来控制子View相对于父View的位置。

  • Expanded支持一个类似weight的属性,叫flex

  • Container是一个具有decoration属性的容器,可以用来控制背景色,border, margin等等。

  • Stack有点像是一个特殊的RelatetiveLayout或者ConstraintLayout,children属性指定了它的子View,第一个是Base View,alignment属性指定了后面的子View相对于BaseView的位置,如alignment: const Alignment(0.6, 0.6)指定了位于BaseView右下角的位置。

  • ListTile是一个特殊的ListItem,有三个属性,分别是左边的Icon (leading),文字 (title),以及右边的Icon (trailing)。

  • 还有诸如ListViewGridViewCard等等比较熟悉的Widgets。

另外有一个类似于我们Activity的Widgets:

  • 叫做MaterialApp, 可以指定themetitle, 以及子View home, 还有更重要的页面跳转routes.

MaterialApp(

title: ‘Welcome to Flutter’,

home: …,

routes: <String, WidgetBuilder> …,

theme: ThemeData(

primaryColor: Colors.white

),

)

还有一个类似于Fragment的:

  • 叫做Scaffold,中文意思是脚手架,它包含一个appBar (ActionBar)与一个body,appBar可以指定title与actions (类似于action button的点击事件)。

Scaffold(

appBar: AppBar(

title: Text(widget.title),

actions: […],

),

body: …,

)

如何从父View中Remove一个元素

答案是没有… 因为在Flutter看来吗,Widgets的树结构是不可以被更改的,但是如果想更改,则是通过StatefulWidgets的方法,通过setState来更改Data,触发Widgets重绘,从而替换掉之前的Widgets。

喜欢画Canvas的同学怎么办?

Flutter同样支持,CustomPaint作为一个 Widgets就支持传入一个实现CustomPainter抽象类的参数,而CustomPainter的抽象方法也类似于Android View的onDraw

void paint(Canvas canvas, Size size)

bool shouldRepaint(CustomPainter oldDelegate)

如何自定义View

不用继承,而使用类似Android ViewGroup的办法,通过组合(composing)与封装的方法来实现,通过小Widgets组合成需要的新Widgets。

页面跳转怎么办,四大组件之一的Intent跑哪里去了

貌似在讲类似于Activity的MaterialApp的时候剧透了…

就是使用NavigatorRoutes来实现界面跳转,实际上是整个Widgets的替换。

routes: <String, WidgetBuilder> {

‘/a’: (BuildContext context) => MyPage(title: ‘page A’),

‘/b’: (BuildContext context) => MyPage(title: ‘page B’),

‘/c’: (BuildContext context) => MyPage(title: ‘page C’),

}

Navigator.of(context).pushNamed(‘/b’);

如何处理外部的Intent

实际上还是需要在Flutter App的Android壳子中注册这个filter,然后在FlutterActivity中拿到存下来。

FlutterView初始化后再通过Bridge,官方叫MethodChannel从Java里获取,进行下一步逻辑。

可以看个简单的例子:

new MethodChannel(getFlutterView(), “app.channel.shared.data”).setMethodCallHandler(

new MethodCallHandler() {

@Override

public void onMethodCall(MethodCall call, MethodChannel.Result result) {

if (call.method.contentEquals(“getSharedText”)) {

result.success(sharedText);

sharedText = null;

}

}

});

getSharedText() async {

var sharedData = await platform.invokeMethod(“getSharedText”);

if (sharedData != null) {

setState(() {

dataShared = sharedData;

});

}

}

常用的startActivityForResult怎么办.

这个Flutter有完全对应的办法,而且用起来很方便,结合之前说的页面跳转。

Map xxx = await Navigator.of(context).pushNamed(‘/xxx’);

Navigator.of(context).pop({xxx});

异步怎么办, runOnUiThread()哪里去了

Flutter有点像JS,是一个单线程模式,所以只是通过模拟来构建简单的异步,关键字就是类似于kotlin coroutines一样,通过await+async来处理。

如:

loadData() async {

response = await http.get(xxx);

setState(() {xxx});

}

但是由于它的单线程,所以无法做很长的阻塞操作,像http请求的延迟正常情况可能都是毫秒级的,但是数据的处理等,可能就得秒级了。

这也是RN在线程方面的做android程序的一个痛点,Flutter采用了比较容易想到的曲线救国的办法,提供了一个叫Isolate的对象,它实际是一个基于socket的数据通道,相当于把数据放在一个独立的进程进行处理,然后再通过socket发送回程序进程,还记得进程间通信办法之一的管道吗…

具体API可以参考文档1…,2….

Flutter 替代OkHttp的网络库

自带了http库,直接http.get(url),在线程部分的代码实例里也有涉及。

通过类似gradle的文件pubspec.yaml引入。

dependencies:

http: ^0.12

^表示不升大版本,并取最新版本,比gradle的+要范围更小。

常见的LCE(Loading Content Error)里面的Loading怎么show

Flutter有一个widget叫做ProgressIndicator,比如我们期望有一个转圈圈的Loading界面在数据加载出来之前。

我们就可以通过StatefulWidgets,根据数据,或者List Widgets的个数 (如果是显示一个List的话)来判断是否显示Loading,使用子类CircularProgressIndicator,来替换页面的Widgets。

当然也是通过setState(() {…})来触发界面刷新的,可以在initState()内触发加载数据的异步操作。

不同分辨率的图片资源怎么放

这个有点像iOS了, 即有1x,2x,3x:

images/my_icon.png // Base: 1.0x image

images/2.0x/my_icon.png // 2.0x image

images/3.0x/my_icon.png // 3.0x image

不一样的一点还需要添加到类似gradle的文件pubspec.yaml里。

assets:

  • images/my_icon.jpeg

字符串怎么存储

Flutter没有像Android的string.xml的东西,目前来说最好的就就是存成静态字符串。

class Strings {

static String welcomeMessage = “Welcome To Flutter”;

}

Text(Strings.welcomeMessage)

Gradle变成什么了

前面说网络库,图片资源的时候提到过,提供了一个叫pubspec.yaml的文件,具体支持的规则可以查看这个文档

Fragment与Activity呢?

之前做过类比,如MaterialApp有点类似于Activity,而Scaffold都点类似Fragment,实际上他们两个都是Flutter的Widgets,也就是说其实只有View的概念了。

还有生命周期吗?

Flutter有一个叫做WidgetsBinding的可以提供类似生命周期的回调。

四种状态inactive (iOS专用),paused(相当于onPause,退后台),resumed(相当于onPostResume,到前台),suspending(android专用,相当于onStop)。

一般在StatefulWidgets的State中注册与反注册。

@override

void initState() {

super.initState();

WidgetsBinding.instance.addObserver(this);

}

@override

void dispose() {

WidgetsBinding.instance.removeObserver(this);

super.dispose();

}

ScrollView vs ListView

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
己不成体系的自学效果低效漫长且无助**。

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-yMeck5Rg-1715806558321)]

[外链图片转存中…(img-TfFsIDnU-1715806558324)]

[外链图片转存中…(img-ywyKLJjI-1715806558325)]

[外链图片转存中…(img-CfaawTGP-1715806558326)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值