通过对三种跨平台引擎的大致了解,我们可以看出来,他们都达到了一定程度的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通过调用State
的setState
方法来触发整个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)。 -
还有诸如
ListView
,GridView
,Card
等等比较熟悉的Widgets。
另外有一个类似于我们Activity的Widgets:
- 叫做
MaterialApp
, 可以指定theme
,title
, 以及子Viewhome
, 还有更重要的页面跳转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
的时候剧透了…
就是使用Navigator
与Routes
来实现界面跳转,实际上是整个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发送回程序进程,还记得进程间通信办法之一的管道
吗…
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开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!