Google Flutter From Scratch:使用小部件构建应用程序

Flutter正迅速成为开发跨平台移动应用程序的最流行框架之一。今天,大多数Android和iOS开发人员开始认为,它是一种比其他跨平台框架(如React Native和NativeScript)更快,更具面向未来的替代方案。

谷歌本身不遗余力地吸引更多开发者加入。例如,Google I / O今年有几个深入的会议,专注于使用它开发符合Material Design标准的应用程序。在其中一次会议中,Google还宣布Flutter将成为Material Design的一流平台。

在本系列教程中,我将帮助您掌握使用Flutter开发Android应用程序的基础知识。在本系列开始的教程中,我将重点关注Flutter小部件,这是所有Flutter应用程序的构建块。

先决条件

要充分利用这个系列,您需要:

  • 最新版本的Android Studio
  • 运行Android API等级21或更高版本的设备或模拟器

1.配置Android Studio

安装了一些轻量级插件后,您可以使用Android本地Android应用程序开发人员最熟悉的Android Studio来开发Flutter应用程序。

首先启动Android Studio,然后 在欢迎屏幕中选择配置>插件选项。

在弹出的对话框中,按“ 浏览存储库” 按钮并搜索Flutter插件。

浏览存储库对话框

找到插件后,按“ 安装” 按钮。此时,系统会询问您是否还要安装Dart插件。按 继续。

插件依赖项对话框

安装 完两个插件后,按“ 重启Android Studio”按钮完成配置。

2.创建一个新项目

重启后,您将能够 在Android Studio欢迎屏幕上看到“ 启动新的Flutter项目”按钮。按此按钮开始创建您的第一个Flutter项目。

在下一个屏幕上,选择Flutter Application 选项,然后按Next

创建Flutter项目对话框

您现在将看到一个表单,询问有关Flutter应用程序的各种详细信息,例如其名称和位置。确保在所有字段中键入有效值。

Flutter项目配置对话框

Flutter插件不与Flutter SDK捆绑在一起。因此,您必须单独安装SDK。您现在可以通过按“ 安装SDK” 按钮来执行此操作。

根据Internet连接的速度,安装可能需要相当长的时间才能完成。成功后,您将能够按“ 下一步” 按钮完成项目设置。

3.添加入口点

在本教程中,您将在lib / main.dart 文件中编写代码。默认情况下,它将包含一些您不需要的示例代码。所以在继续之前删除所有内容。

Flutter框架使用Dart编程语言,这是一种易于学习的语言,其语法与Java和C的语法非常相似。因此,像大多数独立的Java和C程序一样,Flutter应用程序也需要一个main() 函数,一个特殊的函数,作为应用程序的入口点。

因此,将以下代码添加到main.dart 文件中:

void main() {
    // TO DO
}

此时,您可以按 Shift-F10 来构建和运行应用程序。如果您在前面的步骤中没有遇到任何错误,您应该会看到该应用在您的设备上显示空白的白色画布。

4.使用无状态小部件

所有Flutter应用程序都由一个或多个小部件组成,类的实例允许您在屏幕上绘制文本和图像。通常,您不必从头开始编写任何低级小部件,因为该框架附带了各种预制的,漂亮的小部件,这些小部件遵循Android和iOS平台的设计语言。

为了能够在您的应用程序中使用基本小部件,请widgets 通过在main.dart 文件的开头添加以下代码来导入库:

import 'package:flutter/widgets.dart';

您可以创建的最简单的小部件是无状态小部件。正如您可能已经猜到的那样,它们没有与之相关的状态,因此是静态的。它们非常适合显示标签,标题和其他UI元素,其内容在应用程序运行时不太可能发生变化。要创建无状态窗口小部件,必须扩展StatelessWidget 该类并覆盖其build() 方法。以下示例代码显示了如何:

class MyFirstWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // More code here
  }
}

正如您在上面的代码中看到的,该build() 方法必须返回一个Widget 对象。您可以自由选择并返回Flutter提供的数十种预制小部件中的任何一种。例如,如果要显示一行文本,可以创建并返回一个Text 小部件,如下所示:

return Text("This is nice!",
        textDirection: TextDirection.ltr);

请注意,您必须始终记住在使用Text 窗口小部件时指定文本的方向 。

但是,如果您立即运行该应用程序,您将无法看到该文本。那是因为你还没有实例化你的无状态小部件。所以转到main() 方法,在其中实例化小部件,并将其传递给runApp() 方法。这是如何做:

runApp(new MyFirstWidget());

在您添加上述代码并保存项目的那一刻,Android Studio应该会自动在您的设备上热重新加载应用,以便您查看文本。

应用程序显示文本

如果要显示图像而不是文本,可以Text 使用Image 类的build() 方法中的窗口小部件替换窗口小部件。以下代码显示如何创建Image 下载并显示远程图像的窗口小部件:

`return` `Image.network(`

`"[https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg](https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg)"``);`

再次保存项目时,您应该在设备上看到类似的内容:

应用程序显示图像

欢迎加入Android技术开发交流2群:935654177。大家相互交流学习

5.创建小部件树

所有Flutter应用程序都可以被视为小部件树。您在上一步中创建的应用程序是一个只包含一个小部件的小部件树。但是,使用TextImage 窗口小部件作为窗口小部件树的顶部元素并不是一个好主意,因为您将无法向它们添加任何子窗口小部件。

Flutter提供了几个可以作为其他小部件容器的小部件。最常用的是RowColumn 小部件。正如他们的名字所暗示的那样, Row 小部件允许您将多个小部件放在一起,并且Column 小部件可以帮助您将小部件放在 另一个之下。在创建更深层的窗口小部件树时,它们是必不可少的。

以下代码显示如何使用Column 窗口小部件创建具有两个子窗口的窗口小部件树:Text 窗口小部件和Image 窗口小部件。

`Text myText = Text(``"This is a nice photo!"``,`

`textDirection: TextDirection.ltr);`

`Image myImage = Image.network(`

`"[https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg](https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg)"``);`

`return` `Column(`

`children: <Widget>[myText, myImage]`

`);`

该应用程序现在应该如下所示:

应用程序显示两个小部件

此外,还有一些小部件可以帮助您更好地定位单个小部件。例如,Center 窗口小部件可帮助您集中窗口小部件。同样,Container 窗口小部件允许您向窗口小部件添加填充和边距。

以下代码向您展示如何Column通过将您刚创建的窗口小部件嵌入窗口小部件来居中它Center

return Center(child: Column(
    children: <Widget>[myText, myImage],
    mainAxisSize: MainAxisSize.min
  )
);

在上面的代码中,请注意Column 窗口小部件使用一个名为的附加属性 mainAxisSize,其值设置为min。这是必要的,因为在对列居中之前,必须使其高度等于其所有子节点的高度之和。如果没有该属性,Column 窗口小部件将与设备的屏幕一样大,并且Center 窗口小部件将不会对其产生任何影响。

6.使用Material Design Widgets
在此期间,您一直在使用作为widgets 库的一部分的基本小部件。Flutter有一个名为的替代库material,它提供了Material Design小部件。要在您的应用程序中使用它,请使用以下内容替换导入widgets 库的语句:

import 'package:flutter/material.dart';

接下来,要将Material Design样式应用于窗口小部件,您必须MaterialApp 在窗口小部件树的顶部放置一个 窗口小部件。您还必须将先前创建的所有小部件嵌入到窗口小Scaffold 部件中,该窗口小部件可用作窗口小部件的主屏幕 MaterialApp 。

此外,由于大多数Material Design应用程序都有应用栏,因此您可以选择将Scaffold 小部件appBar 属性设置为新AppBar 小部件。

以下代码向您展示如何简洁地完成所有操作:

return MaterialApp(
    home: Scaffold(
        appBar: AppBar(title: Text("My App")),
        body: Center(
          child: Column(
            children: <Widget>[myText, myImage],
            mainAxisSize: MainAxisSize.min
          ),
        )
    )
);

该应用程序现在应该看起来好多了。

应用程序显示Material Design小部件

7.使用有状态小部件

无状态小部件是不可变的。使用您在前面的步骤中编写的代码,没有简单的方法来修改Text 窗口小部件或Image 窗口小部件的内容。为什么?因为Flutter框架更喜欢反应式编程而不是命令式编程。因此,它的大多数小部件都没有可以在运行时更新其内容的setter方法。例如,Text 窗口小部件没有setText() 允许您更改其显示文本的方法。

另一方面,有状态小部件是可变的,尽管不是直接的。他们依靠 State 对象来决定在任何给定实例中应该显示什么。因此,只要State 对象发生更改,框架就会自动更新连接到它的任何有状态窗口小部件的内容。

要创建有状态窗口小部件,必须扩展StatefulWidget 该类并覆盖其 createState() 方法。

class MySecondWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TO DO
  }
}

接下来,您必须创建一个新的自定义State 类,其中包含构成有状态窗口小部件状态的变量。此外,在类中,您必须重写 build() 方法以返回窗口小部件树。

以下代码显示如何创建State 包含名为的单个变量的类url:

`class` `MyState` `extends` `State<MySecondWidget> {`

`String url =` `"[https://source.unsplash.com/random/800x600](https://source.unsplash.com/random/800x600)"``;`

`// A random image from Unsplash`

`@override`

`Widget build(BuildContext context) {`

`// More code here`

`}`

`}`

为了一个具体的例子,我们现在创建一个Material Design窗口小部件树Image ,其中包含一个显示随机图像的RaisedButton 窗口小部件和一个窗口小部件,用户可以按这个窗口小部件来加载新的随机图像。以下代码显示了如何:

return MaterialApp(
  home: Scaffold(
    body: Center(
      child:Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          RaisedButton(
            child: Text("Press Me"),
            onPressed: changeURL,
          ),
          Image.network(url)
        ]
      )
    )
  )
);

请注意,Image 窗口小部件的构造函数现在将url 变量作为其输入,而不是字符串文字。这允许框架在Image 绘制窗口小部件时使用变量的最新值。

另请注意,RaisedButton 窗口小部件具有onPressed 指向名为的事件侦听器的属性changeURL()。该方法尚不存在,因此请创建它。

void changeURL() {
    // More code here
}

当然,在方法中,您必须更改url 变量的值。但是,您不应该直接更改它。如果这样做,Flutter框架将不会收到有关更改的通知。要正确更新有状态窗口小部件的状态,必须始终在setState() 方法内进行所有更改。

目前,为了显示随机图像,我建议您使用Unsplash Source 服务。从中下载随机图像所需要做的就是向其URL发出HTTP请求并向其传递唯一的查询字符串。

以下代码显示如何使用时间戳构造唯一查询字符串:

`setState(() {`

`url =` `"[https://source.unsplash.com/random/800x600/?](https://source.unsplash.com/random/800x600/?)"` `+`

`"q=${new DateTime.now().millisecondsSinceEpoch}"``;`

`});`

此时,您的自定义State 类已准备就绪。接下来需要做的就是实例化它并从createState() 有状态小部件的方法返回它。

runApp(new MyFirstWidget());

如果您将有状态窗口小部件的实例传递给runApp()方法,重新加载应用程序,并按几次按钮,您应该会看到它每次都显示一张新照片。

应用程序显示随机照片

结论

您现在知道如何在Flutter应用程序中使用无状态和有状态的小部件。您还学习了如何将Material Design主题应用于它们,动态更改其内容并使它们具有交互性。

值得注意的是,Flutter不使用任何移动平台的本机小部件。它使用名为Skia的高性能2D图形引擎自行绘制所有小部件,该引擎广泛使用GPU。因此,Flutter应用程序通常以接近60 fps的速度运行,并且感觉非常流畅和响应。


Flutter.png

想学习更多Android知识,或者获取相关资料请加入Android技术开发交流2群:935654177。本群可免费获取Gradle,RxJava,小程序,Hybrid,移动架构,NDK,React Native,性能优化等技术教程!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容