目录
5.在Android中,可以通过View.animate()对视图进行动画处理,那在Flutter中怎样才能对Widget进行处理
2.如何在Flutter中处理来自外部应用程序传入的Intents
3.startActivityForResult 在Flutter中等价于什么
1.runOnUiThread 在Flutter中等价于什么
2.AsyncTask和IntentService在Flutter中等价于什么
1.在哪里存储分辨率相关的图片文件? HDPI/XXHDPI
3.Android Gradle vs Flutter pubspec.yaml
1.Activity和Fragment 在Flutter中等价于什么
2.RelativeLayout在Flutter中等价于什么
1.如何将一个onClick监听器添加到Flutter中的widget
Views
1.widget与view
与View相比,Widget有一些不同之处。 首先,Widget仅支持一帧,并且在每一帧上,Flutter的框架都会创建一个Widget实例树(译者语:相当于一次性绘制整个界面)。 相比之下,在Android上View绘制结束后,就不会重绘,直到调用invalidate时才会重绘。
与Android的视图层次系统不同(在framework改变视图),而在Flutter中的widget是不可变的,这允许widget变得超级轻量。
2.如何更新widget
在Android中,您可以通过直接对view进行改变来更新视图。然而,在Flutter中Widget是不可变的,不会直接更新,而必须使用Widget的状态。
StatefulWidget与Stateless Widget:每一帧它们都会重新构建,不同之处在于StatefulWidget有一个State对象,它可以跨帧存储状态数据并恢复它
那么要记住这个规则:如果一个widget发生了变化(例如用户与它交互),它就是有状态的。但是,如果一个子widget对变化做出反应,而其父widget对变化没有反应,那么包含的父widget仍然可以是无状态的widget。
3.如何布局? XML layout 文件跑哪去了?
在Android中,您通过XML编写布局,但在Flutter中,您可以使用widget树来编写布局。
4.如何在布局中添加或删除组件
在Android中,您可以从父级控件调用addChild或removeChild以动态添加或删除View。 在Flutter中,因为widget是不可变的,所以没有addChild。相反,您可以传入一个函数,该函数返回一个widget给父项,并通过布尔值控制该widget的创建。
5.在Android中,可以通过View.animate()对视图进行动画处理,那在Flutter中怎样才能对Widget进行处理
在Flutter中,可以通过动画库给widget添加动画。
在Android中,您可以通过XML创建动画或在视图上调用.animate()。
6.如何使用Canvas draw/paint
在Android中,您可以使用Canvas在屏幕上绘制自定义形状。
Flutter有两个类可以帮助您绘制画布,CustomPaint和CustomPainter,它们实现您的算法以绘制到画布。
7.如何构建自定义 Widgets
在Android中,您通常会继承View或已经存在的某个控件,然后覆盖其绘制方法来实现自定义View。
在Flutter中,一个自定义widget通常是通过组合其它widget来实现的,而不是继承。
Intents
1.Intent在Flutter中等价于什么?
在Android中,Intents主要有两种使用场景:在Activity之间切换,以及调用外部组件。 Flutter不具有Intents的概念,但如果需要的话,Flutter可以通过Native整合来触发Intents(调用外部组件)。
要在Flutter中切换屏幕,您可以访问路由以绘制新的Widget。 管理多个屏幕有两个核心概念和类:Route 和 Navigator。Route是应用程序的“屏幕”或“页面”的抽象(可以认为是Activity), Navigator是管理Route的Widget。Navigator可以通过push和pop route以实现页面切换。
和Android相似,您可以在AndroidManifest.xml中声明您的Activities,在Flutter中,您可以将具有指定Route的Map传递到顶层MaterialApp实例
2.如何在Flutter中处理来自外部应用程序传入的Intents
Flutter可以通过直接与Android层通信并请求共享的数据来处理来自Android的Intents
在这个例子中,我们注册文本共享intent,所以其他应用程序可以共享文本到我们的Flutter应用程序
这个应用程序的基本流程是我们首先处理Android端的共享文本数据,然后等待Flutter请求数据,然后通过MethodChannel发送。
3.startActivityForResult 在Flutter中等价于什么
处理Flutter中所有路由的Navigator类可用于从已经push到栈的路由中获取结果。 这可以通过等待push返回的Future来完成。
异步UI
1.runOnUiThread 在Flutter中等价于什么
Dart是单线程执行模型,支持Isolates(在另一个线程上运行Dart代码的方式)、事件循环和异步编程。 除非您启动一个Isolate,否则您的Dart代码将在主UI线程中运行,并由事件循环驱动(译者语:和JavaScript一样)。
例如,您可以在UI线程上运行网络请求代码而不会导致UI挂起(译者语:因为网络请求是异步的)
要更新UI,您可以调用setState,这会触发build方法再次运行并更新数据。
2.AsyncTask和IntentService在Flutter中等价于什么
在Android中,当你想访问一个网络资源时,你通常会创建一个AsyncTask,它将在UI线程之外运行代码来防止你的UI被阻塞。 AsyncTask有一个线程池,可以为你管理线程。
由于Flutter是单线程的,运行一个事件循环(如Node.js),所以您不必担心线程管理或者使用AsyncTasks、IntentServices。
要异步运行代码,可以将函数声明为异步函数,并在该函数中等待这个耗时任务
在Android上,当您继承AsyncTask时,通常会覆盖3个方法,OnPreExecute、doInBackground和onPostExecute。 在Flutter中没有这种模式的等价物,因为您只需等待一个长时间运行的函数,而Dart的事件循环将负责其余的事情。
但是,有时您可能需要处理大量数据,导致UI可能会挂起。
在这种情况下,与AsyncTask一样,在Flutter中,可以利用多个CPU内核来执行耗时或计算密集型任务。这是通过使用Isolates来完成的。
是一个独立的执行线程,它运行时不会与主线程共享任何内存。这意味着你不能从该线程访问变量或通过调用setState来更新你的UI。
3.OkHttp在Flutter中等价于什么
当使用受欢迎的“http”package时,Flutter进行网络信非常简单。
虽然“http” package 没有实现OkHttp的所有功能,但“http” package 抽象出了许多常用的API,可以简单有效的发起网络请求。
https://pub.dartlang.org/packages/http
您可以通过在pubspec.yaml中添加依赖项来使用它
4.如何在Flutter中显示进度指示器
在Android中,当您执行耗时任务时,通常会显示进度指示器。
在Flutter中,这可以通过渲染Progress Indicator widget来实现。您可以通过编程方式显示Progress Indicator , 通过布尔值通知Flutter在耗时任务发起之前更新其状态。
项目结构和资源
1.在哪里存储分辨率相关的图片文件? HDPI/XXHDPI
Flutter遵循像iOS这样简单的3种分辨率格式: 1x, 2x, and 3x.
创建一个名为images的文件夹,并为每个图像文件生成一个@2x和@3x文件,并将它们放置在如下这样的文件夹中
-
…/my_icon.png
- …/2.0x/my_icon.png
- …/3.0x/my_icon.png
然后,您需要在pubspec.yaml文件中声明这些图片
然后您可以使用AssetImage访问您的图像
2.在哪里存储字符串? 如何存储不同的语言
目前,最好的做法是创建一个名为Strings的类
class Strings{
static String welcomeMessage = "Welcome To Flutter";
}
3.Android Gradle vs Flutter pubspec.yaml
在Android中,您可以在Gradle文件来添加依赖项。
在Flutter中,虽然在Flutter项目中的Android文件夹下有Gradle文件,但只有在添加平台相关所需的依赖关系时才使用这些文件。 否则,应该使用pubspec.yaml声明用于Flutter的外部依赖项。
发现好的flutter packages的一个好地方 Pub
Activities 和 Fragments
1.Activity和Fragment 在Flutter中等价于什么
在Android中,Activity代表用户可以完成的一项重点工作。Fragment代表了一种模块化代码的方式,可以为大屏幕设备构建更复杂的用户界面,可以在小屏幕和大屏幕之间自动调整UI。 在Flutter中,这两个概念都等同于Widget。
2.如何监听Android Activity生命周期事件
在Android中,您可以覆盖Activity的方法来捕获Activity的生命周期回调。
在Flutter中您可以通过挂接到WidgetsBinding观察并监听didChangeAppLifecycleState更改事件来监听生命周期事件
您可以监听到的生命周期事件是
- resumed - 应用程序可见并响应用户输入。这是来自Android的onResume
- inactive - 应用程序处于非活动状态,并且未接收用户输入。此事件在Android上未使用,仅适用于iOS
- paused - 应用程序当前对用户不可见,不响应用户输入,并在后台运行。这是来自Android的暂停
- suspending - 该应用程序将暂时中止。这在iOS上未使用
Layouts
1.LinearLayout在Flutter中相当于什么
在Android中,使用LinearLayout来使您的控件呈水平或垂直排列。在Flutter中,您可以使用Row或Column来实现相同的结果。
2.RelativeLayout在Flutter中等价于什么
RelativeLayout用于使widget相对于彼此位置排列。在Flutter中,有几种方法可以实现相同的结果
您可以通过使用Column、Row和Stack的组合来实现RelativeLayout的效果。您可以为widget构造函数指定相对于父组件的布局规则。
3.ScrollView在Flutter中等价于什么
在Android中,ScrollView允许您包含一个子控件,以便在用户设备的屏幕比控件内容小的情况下,使它们可以滚动。
在Flutter中,最简单的方法是使用ListView。但在Flutter中,一个ListView既是一个ScrollView,也是一个Android ListView。
手势检测和触摸事件处理
1.如何将一个onClick监听器添加到Flutter中的widget
在Flutter中,添加触摸监听器有两种方法:
-
如果Widget支持事件监听,则可以将一个函数传递给它并进行处理。例如,RaisedButton有一个onPressed参数
-
如果Widget不支持事件监听,则可以将该Widget包装到GestureDetector中,并将处理函数传递给onTap参数
class SampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new GestureDetector(
child: new FlutterLogo(
size: 200.0,
),
onTap: () {
print("tap");
},
),
));
}
}
2.如何处理widget上的其他手势
使用GestureDetector,可以监听多种手势,例如
-
Tap
onTapDown
onTapUp
onTap
onTapCancel
-
Double tap
onDoubleTap
用户快速连续两次在同一位置轻敲屏幕.
-
长按
onLongPress
-
垂直拖动
onVerticalDragStart
onVerticalDragUpdate
onVerticalDragEnd
-
水平拖拽
onHorizontalDragStart
onHorizontalDragUpdate
onHorizontalDragEnd
Listview & Adapter
1.ListView在Flutter中相当于什么
在Flutter中,ListView就是一个ListView!
在Android ListView中,您可以创建一个适配器,然后您可以将它传递给ListView,该适配器将使用适配器返回的内容来展示每一行。 然而,你必须确保在合适的时机回收行,否则,你会得到各种疯狂的视觉和内存问题。
在Flutter中,由于Flutter的不可变的widget模型,将一个Widgets列表传递给的ListView,而Flutter将负责确保它们快速平滑地滚动。
2.怎么知道哪个列表项被点击
在Android中,ListView有一个方法’onItemClickListener’来确定哪个列表项被点击。 Flutter中可以更轻松地通过您传入的处理回调来进行操作。
3.如何动态更新ListView
需要更新适配器并调用notifyDataSetChanged。在Flutter中,如果setState()中更新widget列表,您会发现没有变化, 这是因为当setState被调用时,Flutter渲染引擎会遍历所有的widget以查看它们是否已经改变。 当遍历到你的ListView时,它会做一个==
运算,以查看两个ListView是否相同,因为没有任何改变,因此没有更新数据。
要更新您的ListView,然后在setState中创建一个新的List()并将所有旧数据复制到新列表中。这是实现更新的简单方法(译者语:此时状态改变,ListView被重新构建)
然而,推荐的方法是使用ListView.Builder。当您拥有动态列表或包含大量数据的列表时,此方法非常有用。 这实际上相当于在Android上使用RecyclerView,它会自动为您回收列表元素
我们不是创建一个“新的ListView”,而是创建一个新的ListView.builder,它接受两个参数,即列表的初始长度和一个ItemBuilder函数。
ItemBuilder函数非常类似于Android适配器中的getView函数,它需要一个位置并返回要为该位置渲染的行。
最后,但最重要的是,如果您注意到onTap函数,在里面,我们不会再重新创建列表,而只是添加新元素到列表。
使用 Text
1.如何在 Text widget上设置自定义字体
在Android SDK(从Android O开始)中,创建一个Font资源文件并将其传递到TextView的FontFamily参数中。
在Flutter中,首先你需要把你的字体文件放在项目文件夹中(最好的做法是创建一个名为assets的文件夹)
接下来在pubspec.yaml文件中,声明字体
最后,将字体应用到Text widget
'''
——from pubspec.yaml
fonts:
- family: MyCustomFont
fonts:
- asset: fonts/MyCustomFont.ttf
- style: italic
'''
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sample App"),
),
body: new Center(
child: new Text(
'This is a custom font text',
style: new TextStyle(fontFamily: 'MyCustomFont'),
),
),
);
}
2.如何在Text上定义样式
除了自定义字体,您还可在Text上自定义很多不同的样式
Text的样式参数需要一个TextStyle对象,您可以在其中自定义许多参数,如
- color
- decoration
- decorationColor
- decorationStyle
- fontFamily
- fontSize
- fontStyle
- fontWeight
- hashCode
- height
- inherit
- letterSpacing
- textBaseline
- wordSpacing
表单输入
1.Input的”hint”在flutter中相当于什么
在Flutter中,您可以通过向Text Widget的装饰构造函数参数添加InputDecoration对象,轻松地为输入框显示占位符文本
2.如何显示验证错误
就像您如何使用“hint”一样,您可以将InputDecoration对象传递给Text的装饰构造函数。
但是,您不希望首先显示错误,并且通常会在用户输入一些无效数据时显示该错误。这可以通过更新状态并传递一个新的InputDecoration对象来完成
Flutter 插件
1.如何使用 GPS sensor
要访问GPS传感器,您可以使用社区插件 https://pub.dartlang.org/packages/location
2.如何访问相机
访问相机的流行社区插件是 https://pub.dartlang.org/packages/image_picker
3.如何使用Facebook登陆
要访问Facebook Connect功能,您可以使用 https://pub.dartlang.org/packages/flutter_facebook_connect .
4.如何构建自定义集成Native功能
如果有Flutter或其社区插件缺失的平台特定功能,那么您可以自己按照以下教程构建 开发packages .
简而言之,Flutter的插件架构就像在Android中使用Event bus一样:您可以发出消息并让接收者进行处理并将结果返回给您,在这种情况下,接收者将是iOS或Android。
5.如何在我的Flutter应用程序中使用NDK
自定义插件首先会与Android应用程序通信,您可以在其中调用native标记的函数。一旦Native完成了相应操作,就可以将响应消息发回给Flutter并呈现结果。
主题
1.如何构建Material主题风格的app
Flutter很好的实现了一个美丽的Material Design,它会满足很多样式和主题的需求。 与Android中使用XML声明主题不同,在Flutter中,您可以通过顶层widget声明主题。
MaterialApp是一个方便的widget,它包装了许多Material Design应用通常需要的widget,它通过添加Material特定功能构建在WidgetsApp上。
如果你不想使用Material Components,那么你可以声明一个顶级widget-WidgetsApp,它是一个便利的类,它包装了许多应用程序通常需要的widget
要自定义Material Components的颜色和样式,您可以将ThemeData对象传递到MaterialApp widget中,例如在下面的代码中,您可以看到主色板设置为蓝色,并且所有选择区域的文本颜色都应为红色。
数据库和本地存储
1.如何在Flutter中访问Shared Preferences ?
在Android中,您可以使用SharedPreferences API存储一些键值对
在Flutter中,您可以通过使用插件Shared_Preferences来访问此功能
这个插件包装了Shared Preferences和NSUserDefaults(与iOS相同)的功能
2.如何在Flutter中访问SQLite
在Android中,您可以使用SQLite存储,通过SQL查询的结构化数据。
在Flutter中,您可以使用SQFlite插件来访问SQFlite此功能
通知
如何设置推送通知
在Android中,您可以使用Firebase云消息传递为您的应用设置推送通知。
在Flutter中,您可以使用Firebase_Messaging插件访问此功能
注意:在中国无法使用Firebase服务。