Flutter(一)之Flutter开发初体验(上)

简介: Flutter开发初体验

一. 创建Flutter项目


创建Flutter项目有两种方式:通过命令行创建通过开发工具创建


1.1. 通过命令行创建


通过命令行创建非常简单,在终端输入以下命令即可:

  • **注意:**Flutter的名称不要包含特殊的字符,另外不可以使用驼峰标识
  • 创建完之后使用自己喜欢的开发工具打开即可

flutter create learn_flutter

image.png


1.2. 通过开发工具创建


我这里也可以直接通过Android Studio来进行创建:

  • 选择Start a new Flutter project,之后填写相关的信息即可,这里不再赘述

image.png


1.3. 默认程序分析


我们讲创建的应用起来跑在模拟器上(我这里选择iPhone模拟器,Android也可以),会看到如下效果:

image.png

默认项目分析:

  • 我们之前已经分析过目录结构了,在目录下有一个lib文件夹,里面会存放我们编写的Flutter代码;
  • 打开发现里面有一个main.dart,它是我们Flutter启动的入口文件,里面有main函数

默认代码分析:

  • 这是一个计数器的案例程序,点击右下角的 + 符号,上面显示的数字会递增;
  • 但是我们第一次接触main.dart中的代码,可能会发现很多不认识的代码,不知道这个内容是如何编写出来的;

作为初学者,我的建议是将其中所有的代码全部删除掉,从零去创建里面的代码,这样我们才能对Flutter应用程序的结构非常清晰;


二. 开始Flutter代码


2.1. Hello World


2.1.1. Hello World的需求


做任何的开发,我们都是从祖传的Hello World开始,那么现在我们的需求来了:

  • 在界面中心位置,显示一个Hello World;


2.1.2. Hello World的实现


下面,我们就动手开始编写Hello World:

import 'package:flutter/material.dart';
main(List<String> args) {
  runApp(Text("Hello World", textDirection: TextDirection.ltr));
}

image.png

当然,上面的代码我们已经实现了在界面上显示Hello World:

  • 但是没有居中字体也有点小
  • 这些问题,我们放到后面再来解决,先搞懂目前的几行代码;

上面的代码我们有一些比较熟悉,有一些并不清楚是什么:

  • 比如我们知道Dart程序的入口都是main函数,而Flutter是Dart编写的,所以入口也是main函数;
  • 但是我们导入的Material是什么呢
  • 另外,我们在main函数中调用了一个runApp()函数又是什么呢?

下面,我们对不认识的代码进行一些分析。


2.2. 代码分析


2.2.1. runApp和Widget


runApp是Flutter内部提供的一个函数,当我们启动一个Flutter应用程序时就是从调用这个函数开始的

  • 我们可以点到runApp的源码,查看到该函数
  • 我们暂时不分析具体的源码(因为我发现过多的理论,对于初学者来说并不友好)
void runApp(Widget app) {
  ...省略代码
}

该函数让我们传入一个东西:Widget

我们先说Widget的翻译

  • Widget在国内有很多的翻译;
  • 做过Android、iOS等开发的人群,喜欢将它翻译成控件
  • 做过Vue、React等开发的人群,喜欢将它翻译成组件
  • 如果我们使用Google,Widget翻译过来应该是小部件
  • 没有说哪种翻译一定是对的,或者一定是错的,但是我个人更倾向于小部件或者组件

Widget到底什么东西呢?

  • 我们学习Flutter,从一开始就可以有一个基本的认识:Flutter中万物皆Widget(万物皆可盘)
  • 在我们iOS或者Android开发中,我们的界面有很多种类的划分:应用(Application)、视图控制器(View Controller)、活动(Activity)、View(视图)、Button(按钮)等等;
  • 但是在Flutter中,这些东西都是不同的Widget而已
  • 也就是我们整个应用程序中所看到的内容几乎都是Widget,甚至是内边距的设置,我们也需要使用一个叫Padding的Widget来做;

runApp函数让我们传入的就是一个Widget:

  • 但是我们现在没有Widget,怎么办呢?
  • 我们可以导入Flutter默认已经给我们提供的Material库,来使用其中的很多内置Widget;


2.2.2. Material设计风格


material是什么呢?

  • material是Google公司推行的一套设计风格,或者叫设计语言设计规范等;
  • 里面有非常多的设计规范,比如颜色文字的排版响应动画与过度填充等等;
  • 在Flutter中高度集成了Material风格的Widget
  • 在我们的应用中,我们可以直接使用这些Widget来创建我们的应用(后面会用到很多);

Text小部件分析

  • 我们可以使用Text小部件来完成文字的显示;
  • 我们发现Text小部件继承自StatelessWidget,StatelessWidget继承自Widget;
  • 所以我们可以将Text小部件传入到runApp函数中
  • 属性非常多,但是我们已经学习了Dart语法,所以你会发现只有this.data属性是必须传入的。
class Text extends StatelessWidget {
  const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
  });
}

StatelessWidget简单介绍:

  • StatelessWidget继承自Widget;
  • 后面我会更加详细的介绍它的用法;
abstract class StatelessWidget extends Widget {
  // ...省略代码
}


2.3. 代码改进


2.3.1. 改进界面样式


我们发现现在的代码并不是我们想要的最终结果:

  • 我们可能希望文字居中显示,并且可以大一些;
  • 居中显示: 需要使用另外一个Widget,Center
  • 文字大一些: 需要给Text文本设置一些样式;

我们修改代码如下:

  • 我们在Text小部件外层包装了一个Center部件,让Text作为其child;
  • 并且,我们给Text组件设置了一个属性:style,对应的值是TextStyle类型;
import 'package:flutter/material.dart';
main(List<String> args) {
  runApp(
    Center(
      child: Text(
        "Hello World",
        textDirection: TextDirection.ltr,
        style: TextStyle(fontSize: 36),
      ),
    )
  );
}

image.png


2.3.2. 改进界面结构


目前我们虽然可以显示HelloWorld,但是我们发现最底部的背景是黑色,并且我们的页面并不够结构化。

  • 正常的App页面应该有一定的结构,比如通常都会有导航栏,会有一些背景颜色

在开发当中,我们并不需要从零去搭建这种结构化的界面,我们可以使用Material库,直接使用其中的一些封装好的组件来完成一些结构的搭建。

我们通过下面的代码来实现:

import 'package:flutter/material.dart';
main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: Center(
          child: Text(
            "Hello World",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 36),
          ),
        ),
      ),
    )
  );
}

image.png

在最外层包裹一个MaterialApp

  • 这意味着整个应用我们都会采用MaterialApp风格的一些东西,方便我们对应用的设计,并且目前我们使用了其中两个属性;
  • title:这个是定义在Android系统中打开多任务切换窗口时显示的标题;(暂时可以不写)
  • home:是该应用启动时显示的页面,我们传入了一个Scaffold;

Scaffold是什么呢?

  • 翻译过来是脚手架,脚手架的作用就是搭建页面的基本结构;
  • 所以我们给MaterialApp的home属性传入了一个Scaffold对象,作为启动显示的Widget;
  • Scaffold也有一些属性,比如appBarbody
  • appBar是用于设计导航栏的,我们传入了一个title属性
  • body是页面的内容部分,我们传入了之前已经创建好的Center中包裹的一个Text的Widget;


2.3.3. 进阶案例实现


我们可以让界面中存在更多的元素:

  • 写到这里的时候,你可能已经发现嵌套太多了,不要着急,我们后面会对代码重构的
import 'package:flutter/material.dart';
main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Checkbox(
                value: true,
                onChanged: (value) => print("Hello World")),
              Text(
                "同意协议",
                textDirection: TextDirection.ltr,
                style: TextStyle(fontSize: 20),
              )
            ],
          ),
        ),
      ),
    )
  );
}

image.png


2.4. 代码重构


2.4.1. 创建自己的Widget


很多学习Flutter的人,都会被Flutter的嵌套劝退,当代码嵌套过多时,结构很容易看不清晰。

这里有两点我先说明一下:

  • 1、Flutter整个开发过程中就是形成一个Widget树,所以形成嵌套是很正常的。
  • 2、关于Flutter的代码缩进,更多开发中我们使用的是2个空格(前端开发2个空格居多,你喜欢4个也没问题)

但是,我们开发一个这么简单的程序就出现如此多的嵌套,如果应用程序更复杂呢?

  • 我们可以对我们的代码进行封装,将它们封装到自己的Widget中,创建自己的Widget;

如何创建自己的Widget呢?

  • 在Flutter开发中,我们可以继承自StatelessWidget或者StatefulWidget来创建自己的Widget类;
  • StatelessWidget: 没有状态改变的Widget,通常这种Widget仅仅是做一些展示工作而已;
  • StatefulWidget: 需要保存状态,并且可能出现状态改变的Widget;

在上面的案例中对代码的重构,我们使用StatelessWidget即可,所以我们接下来学习一下如果利用StatelessWidget来对我们的代码进行重构;

StatefulWidget我们放到后面的一个案例中来学习;


2.4.2. StatelessWidget


StatelessWidget通常是一些没有状态(State,也可以理解成data)需要维护的Widget:

  • 它们的数据通常是直接写死(放在Widget中的数据,必须被定义为final,为什么呢?我在下一个章节讲解StatefulWidget会讲到);
  • 从parent widget中传入的而且一旦传入就不可以修改;
  • 从InheritedWidget获取来使用的数据(这个放到后面会讲解);

我们来看一下创建一个StatelessWidget的格式:

  • 1、让自己创建的Widget继承自StatelessWidget;
  • 2、StatelessWidget包含一个必须重写的方法:build方法;
class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return <返回我们的Widget要渲染的Widget,比如一个Text Widget>;
  }
}


build方法的解析:

  • Flutter在拿到我们自己创建的StatelessWidget时,就会执行它的build方法;
  • 我们需要在build方法中告诉Flutter,我们的Widget希望渲染什么元素,比如一个Text Widget;
  • StatelessWidget没办法主动去执行build方法,当我们使用的数据发生改变时,build方法会被重新执行;

build方法什么情况下被执行呢?:

  • 1、当我们的StatelessWidget第一次被插入到Widget树中时(也就是第一次被创建时);
  • 2、当我们的父Widget(parent widget)发生改变时,子Widget会被重新构建;
  • 3、如果我们的Widget依赖InheritedWidget的一些数据,InheritedWidget数据发生改变时;


2.4.3. 重构案例代码


现在我们就可以通过StatelessWidget来对我们的代码进行重构了

  • 因为我们的整个代码都是一些数据展示,没有数据的改变,使用StatelessWidget即可;
  • 另外,为了体现更好的封装性,我对代码进行了两层的拆分,让代码结构看起来更加清晰;(具体的拆分方式,我会在后面的案例中不断的体现出来,目前我们先拆分两层)

重构后的代码如下:

import 'package:flutter/material.dart';
main(List<String> args) {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: HomeContent(),
      ),
    )
  }
}
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Checkbox(
              value: true,
              onChanged: (value) => print("Hello World")),
          Text(
            "同意协议",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 20),
          )
        ],
      ),
    );
  }
}

image.png

相关文章
|
1月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
|
4天前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
17 2
|
1月前
|
开发者
鸿蒙Flutter实战:07-混合开发
鸿蒙Flutter混合开发支持两种模式:1) 基于har包,便于主项目开发者无需关心Flutter细节,但不支持热重载;2) 基于源码依赖,利于代码维护与热重载,需配置Flutter环境。项目结构包括AppScope、flutter_module等目录,适用于不同开发需求。
79 3
|
22天前
|
传感器 开发框架 物联网
鸿蒙next选择 Flutter 开发跨平台应用的原因
鸿蒙(HarmonyOS)是华为推出的一款旨在实现多设备无缝连接的操作系统。为了实现这一目标,鸿蒙选择了 Flutter 作为主要的跨平台应用开发框架。Flutter 的跨平台能力、高性能、丰富的生态支持和与鸿蒙系统的良好兼容性,使其成为理想的选择。通过 Flutter,开发者可以高效地构建和部署多平台应用,推动鸿蒙生态的快速发展。
150 0
|
24天前
|
Dart 安全 UED
Flutter&鸿蒙next中的表单封装:提升开发效率与用户体验
在移动应用开发中,表单是用户与应用交互的重要界面。本文介绍了如何在Flutter中封装表单,以提升开发效率和用户体验。通过代码复用、集中管理和一致性的优势,封装表单组件可以简化开发流程。文章详细讲解了Flutter表单的基础、封装方法和表单验证技巧,帮助开发者构建健壮且用户友好的应用。
62 0
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
82 7
|
1月前
|
编解码 Dart API
鸿蒙Flutter实战:06-使用ArkTs开发Flutter鸿蒙插件
本文介绍了如何开发一个 Flutter 鸿蒙插件,实现 Flutter 与鸿蒙的混合开发及双端消息通信。通过定义 `MethodChannel` 实现 Flutter 侧的 token 存取方法,并在鸿蒙侧编写 `EntryAbility` 和 `ForestPlugin`,使用鸿蒙的首选项 API 完成数据的读写操作。文章还提供了注意事项和参考资料,帮助开发者更好地理解和实现这一过程。
70 0
|
1月前
|
Dart Android开发
鸿蒙Flutter实战:03-鸿蒙Flutter开发中集成Webview
本文介绍了在OpenHarmony平台上集成WebView的两种方法:一是使用第三方库`flutter_inappwebview`,通过配置pubspec.lock文件实现;二是编写原生ArkTS代码,自定义PlatformView,涉及创建入口能力、注册视图工厂、处理方法调用及页面构建等步骤。
60 0
|
2月前
|
JSON Dart Java
flutter开发多端平台应用的探索
flutter开发多端平台应用的探索
52 6
|
2月前
|
JSON Dart Java
flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
下一篇
无影云桌面