Flutter 初學Flutter頁面開發 一. 創建Flutter項目 二. 目錄結構 三. hot reload & hot restart 四. flutter

一. 創建Flutter項目

1.1. 創建

命令行方式

flutter create learn_flutter

注意:

  • Flutter的名稱不要包含特殊的字符,另外 <font color=red>不可以使用駝峯,不支持大寫,儘量不要使用一些符號</font> 標識
  • 創建完之後使用自己喜歡的開發工具打開即可
  • xxx_xxx 下劃線格式較多一些

工具創建

如:android studio - Start a new Flutter project

1.2. 運行

運行

  • 命令行方式,進入flutter項目目錄:flutter run即可

  • android studio 打開項目,可以使用ide提供的快捷工具直接運行,as也是可以運行ios模擬器的

  • 也可以通過as或xcode分別打開flutter項目中的android或ios代碼,直接運行即可。

  • as也可以直接打開整個flutter項目代碼

斷點

vscode dart代碼支持斷點調試的,也是代碼面板左邊點擊某行代碼打上斷點,然後run - start debugging

二. 目錄結構

文件或目錄 說明
.dart_tool 記錄了一些dart工具庫所在的位置和信息
.idea android studio 是基於idea開發的,.idea 記錄了項目的一些文件的變更記錄
android Android項目文件夾
ios iOS項目文件夾
lib lib文件夾內存放我們的dart語音代碼
test 用於存放我們的測試代碼
.gitignore git忽略配置文件
.metadata IDE 用來記錄某個 Flutter 項目屬性的的隱藏文件
.packages pub 工具需要使用的,包含 package 依賴的 yaml 格式的文件
flutter_app.iml 工程文件的本地路徑配置
pubspec.lock 當前項目依賴所生成的文件
pubspec.yaml 當前項目的一些配置文件,包括依賴的第三方庫、圖片資源文件等
README.md READEME文件

重要的文件就以下幾個:

  • lib

我們日常開發的dart語言代碼都放在這裏,可以說是我們的“核心工作文件夾”

  • iOS

這裏麪包含了iOS項目相關的配置和文件,當我們的項目需要打包上線的時候,需要打開該文件內的Runner.xcworkspace文件進行編譯和打包工作。

  • android

與ios文件夾一樣,在android項目需要打包上架的時候,也需要使用此文件夾裏面的文件。同樣的如果我們需要原生代碼的支持,原生代碼也是放在這裏。

  • test

這裏存放了我們在項目開發過程中的測試代碼,良好的測試習慣是保證代碼質量的必要手段,希望大家在test文件裏寫更多的代碼!

  • pubspec.yaml

就好比開發原生,你總要知道工程如何配置,依賴三方,資源文件等

2.1. main.dart

flutter 默認入口文件,內部main函數是flutter解析的入口

關於默認的main.dart文件:

1、程序默認入口文件,這個是可配置的,如as開發環境:可以通過Edti Configuratios來修改入口文件。。。也可以通過命令行:flutter run -t lib/entry.dart

2、雖然入口文件能修改,但是一般不用,並且注意,入口文件內必須有main函數主入口的,這個跟android,ios之類的一樣

三. hot reload & hot restart

冷啓動

從零編譯運行,耗時

hot reload

主要執行build:

@override
  Widget build(BuildContext context) {

意思就是如果修改的是build方法體內的內容,只需要hot reload即可

hot restart

重新運行整個app,如果修改的是非build內容,則需要hot restart

四. flutter

4.1. 基本頁面

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('title'),
        ),
        body: Center(
            child: Text(
              'hello world',
              style: TextStyle(
                  color: Colors.amber,
                  fontSize: 50
              ),
              strutStyle: StrutStyle(
                fontSize: 10,
                fontStyle: FontStyle.italic,
              ),
              textDirection: TextDirection.ltr,
              // textScaleFactor: 2,
            )
        ),
        bottomNavigationBar: BottomAppBar(
          color: Colors.red,
          child: Text(
            'bottom'
          ),
        ),
      )
    )
  );
}

4.2. 代碼分析

runApp

runApp是Flutter內部提供的一個函數,當我們啓動一個Flutter應用程序時就是從調用這個函數開始的

  • 我們可以點到runApp的源碼,查看到該函數

該函數讓我們傳入一個東西:Widget?

widget

  • 我們學習Flutter,從一開始就可以有一個基本的認識:Flutter中萬物皆Widget(萬物皆可盤);
  • 在我們iOS或者Android開發中,我們的界面有很多種類的劃分:應用(Application)、視圖控制器(View Controller)、活動(Activity)、View(視圖)、Button(按鈕)等等;
  • 但是在Flutter中,這些東西都是不同的Widget而已;
  • 也就是我們整個應用程序中所看到的內容幾乎都是Widget,甚至是內邊距的設置,我們也需要使用一個叫Padding的Widget來做;

material

  • material是Google公司推行的一套設計風格,或者叫設計語言、設計規範等;
  • 裏面有非常多的設計規範,比如顏色、文字的排版、響應動畫與過度、填充等等;
  • 在Flutter中高度集成了Material風格的Widget;
  • 在我們的應用中,我們可以直接使用這些Widget來創建我們的應用(後面會用到很多);

cupertino.dart 風格

前端開發,ui是主要部分,上面的Material提供了豐富的ui組件,cupertino風格是蘋果風格的,但不是很豐富,可以嘗試用

Scaffold 腳手架

  • 翻譯過來是腳手架,腳手架的作用就是搭建頁面的基本結構;
  • 所以我們給MaterialApp的home屬性傳入了一個Scaffold對象,作爲- 啓動顯示的Widget;
  • Scaffold也有一些屬性,比如appBar和body;
  • appBar是用於設計導航欄的,我們傳入了一個title屬性;
  • body是頁面的內容部分,我們傳入了之前已經創建好的Center中包裹的一個Text的Widget;

4.3. 代碼重構

一個簡單的頁面,嵌套寫了那麼多層的代碼,很不友好,所以,正常的代碼怎麼做的?

flutter中萬物皆widget,也即分析頁面後,可以將頁面元素拆分,比如:導航條,body體,底部視圖等。然後各個部分抽離出來封裝爲新的組件

4.3.1. 封裝widget

首先,新入門語言,都會覺得有些不是因,要做的是需要熟悉寫法,學會該語言的代碼結構,然後熟練就好了。

關於flutter的widget,先說明一下:

  • Flutter整個開發過程中就是形成一個Widget樹,所以形成嵌套是很正常的。
  • 封裝widget有兩種類型,可以繼承自StatelessWidget或者StatefulWidget

這裏先不深入如何完全自定義widget,先學會小視圖組合方式的封裝,把代碼重構清晰

4.3.1.1. StatelessWidget

StatelessWidget是沒有狀態改變的Widget,通常這種Widget僅僅是做一些展示工作而已;

  • 它們的數據通常是直接寫死(放在Widget中的數據,必須被定義爲final)
    • StatelessWidget所繼承的Widget被@immutable標記,表示不可變,不可變是指該widget內所有的變量是不可變的,所以,你的widget內聲明狀態是不合理的。所以印證了上面的話:StatelessWidget類型的widget只做一些純展示
  • 很重要的一點是:自定義widget內沒有setState方法,所以,沒法進行widget狀態管理,觸發重新渲染更新
  • 從parent widget中傳入的而且一旦傳入就不可以修改;
  • 從InheritedWidget獲取來使用的數據;
//1、繼承自StatelessWidget
//2、重寫的方法: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數據發生改變時;

重構結果

篇幅原因,部分代碼就不展示了

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: MyHomePage()
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title'),
      ),
      body: HomeBody(),
      bottomNavigationBar: HomeBottomBar(),
    );
  }
}

class HomeBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
          'hello world',
          ...
        )
    );
  }
}

class HomeBottomBar extends StatelessWidget {...}

4.3.1.2. StatefulWidget

StatefulWidget是需要保存狀態,並且可能出現狀態改變的Widget;前面說了,StatelessWidget是純展示的一個widget,也即其是沒辦法做狀態管理的,所以,其上內容是沒法更新的。就做一些靜態展示。。與其相對的額StatefulWidget就包含了狀態管理,做數據展示和數據操作

StatefulWidget學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章