Flutter 与 Android 差异

本文详细比较了Flutter和Android开发的区别,包括Widgets、Intent处理、异步UI、项目结构与资源、手势处理、数据库访问等多个方面。Flutter的Widget是不可变的,更新采用StatefulWidget和State对象;Intent在Flutter中需要通过Native整合;动画处理使用动画库;自定义组件通过组合其他Widget实现。此外,还介绍了如何在Flutter中实现Android类似的功能,如ListView、网络请求、字体样式等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Views

1.widget与view

2.如何更新widget

3.如何布局? XML layout 文件跑哪去了?

4.如何在布局中添加或删除组件

5.在Android中,可以通过View.animate()对视图进行动画处理,那在Flutter中怎样才能对Widget进行处理

6.如何使用Canvas draw/paint

7.如何构建自定义 Widgets

Intents

1.Intent在Flutter中等价于什么?

2.如何在Flutter中处理来自外部应用程序传入的Intents

3.startActivityForResult 在Flutter中等价于什么

异步UI

1.runOnUiThread 在Flutter中等价于什么

2.AsyncTask和IntentService在Flutter中等价于什么

3.OkHttp在Flutter中等价于什么

4.如何在Flutter中显示进度指示器

项目结构和资源

1.在哪里存储分辨率相关的图片文件? HDPI/XXHDPI

2.在哪里存储字符串? 如何存储不同的语言

3.Android Gradle vs Flutter pubspec.yaml

Activities 和 Fragments

1.Activity和Fragment 在Flutter中等价于什么

2.如何监听Android Activity生命周期事件

Layouts

1.LinearLayout在Flutter中相当于什么

2.RelativeLayout在Flutter中等价于什么

3.ScrollView在Flutter中等价于什么

手势检测和触摸事件处理

1.如何将一个onClick监听器添加到Flutter中的widget

2.如何处理widget上的其他手势

Listview & Adapter

1.ListView在Flutter中相当于什么

2.怎么知道哪个列表项被点击

3.如何动态更新ListView

使用 Text

1.如何在 Text widget上设置自定义字体

2.如何在Text上定义样式

表单输入

1.Input的”hint”在flutter中相当于什么

2.如何显示验证错误

Flutter 插件

1.如何使用 GPS sensor

2.如何访问相机

3.如何使用Facebook登陆

4.如何构建自定义集成Native功能

5.如何在我的Flutter应用程序中使用NDK

主题

1.如何构建Material主题风格的app

数据库和本地存储

1.如何在Flutter中访问Shared Preferences ?

2.如何在Flutter中访问SQLite

通知

如何设置推送通知


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或Co​​lumn来实现相同的结果。

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中,添加触摸监听器有两种方法:

  1. 如果Widget支持事件监听,则可以将一个函数传递给它并进行处理。例如,RaisedButton有一个onPressed参数

  2. 如果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服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值