Flutter重拾(一)之Flutter開發(fā)初體驗

前言:距離上次寫Flutter已經(jīng)2個月過去了,這兩天打開Flutter項目一看,既有些熟悉又有些陌生。由于目前的項目是用Swift寫的,項目有點小忙。忙只是接口,保持持續(xù)的輸入輸出才是重中之重。要是丟了Flutter這塊的知識儲備,覺得實在是太可惜,于是決定重新開啟啟程之路。早上提前到辦公室學(xué)習(xí)半小時,中午再利用中午空擋時間學(xué)習(xí)半小時。 這樣光工作的閑魚時間一個月算下來110個小時。。
Let's learn together!

一、創(chuàng)建工程
二、開始Flutter代碼
2.1 Hello World的實現(xiàn)
2.2 代碼分析
2.2.1 runApp和Widget
2.2.2. Material設(shè)計風(fēng)格
2.3 代碼優(yōu)化
2.3.1 改進(jìn)界面樣式及結(jié)構(gòu)
2.4 代碼重構(gòu)
2.4.1. 創(chuàng)建自己的Widget
2.4.2. StatelessWidget
2.4.3. 重構(gòu)案例代碼

一、創(chuàng)建工程

創(chuàng)建功能之后會有一些默認(rèn)的代碼,直接運行,我們會發(fā)現(xiàn)這是一個計數(shù)器的案例程序,點擊右下角的 + 符號,上面顯示的數(shù)字會遞增;

默認(rèn)項目分析:
在目錄下有一個lib文件夾,里面會存放我們編寫的Flutter代碼;
打開發(fā)現(xiàn)里面有一個main.dart,它是我們Flutter啟動的入口文件,里面有main函數(shù);
我們第一次接觸main.dart中的代碼,可能會發(fā)現(xiàn)很多不認(rèn)識的代碼,不知道這個內(nèi)容是如何編寫出來的;
作為初學(xué)者,我的建議是將其中所有的代碼全部刪除掉,從零去創(chuàng)建里面的代碼,這樣我們才能對Flutter應(yīng)用程序的結(jié)構(gòu)非常清晰;

二、開始Flutter代碼

2.1 Hello World的需求實現(xiàn)(簡單粗暴型實現(xiàn)方式)

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

圖片.png

疑惑

  • 導(dǎo)入的Material是什么呢?
  • 我們在main函數(shù)中調(diào)用了一個runApp()函數(shù)又是什么呢?

2.2 代碼分析

2.2.1 runApp和Widget

runApp是Flutter內(nèi)部提供的一個函數(shù),當(dāng)我們啟動一個Flutter應(yīng)用程序時就是從調(diào)用這個函數(shù)開始的
我們可以點到runApp的源碼,查看到該函數(shù)

void runApp(Widget app) {
  ...省略代碼
}

該函數(shù)讓我們傳入一個東西:Widget?

對Widget的理解:

  • 做過Android、iOS等開發(fā)的人群,喜歡將它翻譯成控件;
  • 做過Vue、React等開發(fā)的人群,喜歡將它翻譯成組件;
  • 如果我們使用Google,Widget翻譯過來應(yīng)該是小部件;

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

runApp函數(shù)讓我們傳入的就是一個Widget:
但是我們現(xiàn)在沒有Widget,怎么辦呢?
我們可以導(dǎo)入Flutter默認(rèn)已經(jīng)給我們提供的Material庫,來使用其中的很多內(nèi)置Widget;

2.2.2. Material設(shè)計風(fēng)格

material是什么呢?
material是Google公司推行的一套設(shè)計風(fēng)格,或者叫設(shè)計語言、設(shè)計規(guī)范等;
里面有非常多的設(shè)計規(guī)范,比如顏色、文字的排版、響應(yīng)動畫與過度、填充等等;
在Flutter中高度集成了Material風(fēng)格的Widget;
在我們的應(yīng)用中,我們可以直接使用這些Widget來創(chuàng)建我們的應(yīng)用(后面會用到很多);

Text小部件分析:
我們可以使用Text小部件來完成文字的顯示;
我們發(fā)現(xiàn)Text小部件繼承自StatelessWidget,StatelessWidget繼承自Widget;
所以我們可以將Text小部件傳入到runApp函數(shù)中
屬性非常多,但是我們已經(jīng)學(xué)習(xí)了Dart語法,所以你會發(fā)現(xiàn)只有this.data屬性是必須傳入的。

2.3 代碼優(yōu)化

需求改進(jìn):

  • 我們可能希望文字居中顯示,并且可以大一些;
  • 居中顯示: 需要使用另外一個Widget,Center;
  • 文字大一些: 需要給Text文本設(shè)置一些樣式;
2.3.1 改進(jìn)界面樣式及結(jié)構(gòu)

正常的App頁面應(yīng)該有一定的結(jié)構(gòu),比如通常都會有導(dǎo)航欄,會有一些背景顏色等
在開發(fā)當(dāng)中,我們并不需要從零去搭建這種結(jié)構(gòu)化的界面,我們可以使用Material庫,直接使用其中的一些封裝好的組件來完成一些結(jié)構(gòu)的搭建

import 'package:flutter/material.dart';

main(){

  runApp(
    MaterialApp(
      debugShowCheckedModeBanner:false ,
      home: Scaffold(
        appBar: AppBar(

          title: Text("Flutter"),
        ),
        body: Center(
          child:  Text(
            "Hello World",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 20),
          ),
        ),
      ),
    ),
  );

}
圖片.png

代碼解讀
在最外層包裹一個MaterialApp
這意味著整個應(yīng)用我們都會采用MaterialApp風(fēng)格的一些東西,方便我們對應(yīng)用的設(shè)計,并且目前我們使用了其中兩個屬性;
title:這個是定義在Android系統(tǒng)中打開多任務(wù)切換窗口時顯示的標(biāo)題;(暫時可以不寫)
home:是該應(yīng)用啟動時顯示的頁面,我們傳入了一個Scaffold;

Scaffold是什么呢?
翻譯過來是腳手架,腳手架的作用就是搭建頁面的基本結(jié)構(gòu);
所以我們給MaterialApp的home屬性傳入了一個Scaffold對象,作為啟動顯示的Widget;
Scaffold也有一些屬性,比如appBar和body;
appBar是用于設(shè)計導(dǎo)航欄的,我們傳入了一個title屬性;
body是頁面的內(nèi)容部分,我們傳入了之前已經(jīng)創(chuàng)建好的Center中包裹的一個Text的Widget;

2.4 代碼重構(gòu)

2.4.1 創(chuàng)建自己的Widget

當(dāng)代碼嵌套過多時,結(jié)構(gòu)很容易看不清晰。學(xué)會拆分以及抽取使其代碼可讀性更高,乃是重中之重?。?!

2.4.2 StatelessWidget

StatelessWidget通常是一些沒有狀態(tài)(State,也可以理解成data)需要維護(hù)的Widget:
它們的數(shù)據(jù)通常是直接寫死;
從parent widget中傳入的而且一旦傳入就不可以修改;

我們來看一下創(chuàng)建一個StatelessWidget的格式:
1、讓自己創(chuàng)建的Widget繼承自StatelessWidget;
2、StatelessWidget包含一個必須重寫的方法:build方法;

class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return <返回我們的Widget要渲染的Widget,比如一個Text Widget>;
  }
}

build方法的解析:
Flutter在拿到我們自己創(chuàng)建的StatelessWidget時,就會執(zhí)行它的build方法;
我們需要在build方法中告訴Flutter,我們的Widget希望渲染什么元素,比如一個Text Widget;
StatelessWidget沒辦法主動去執(zhí)行build方法,當(dāng)我們使用的數(shù)據(jù)發(fā)生改變時,build方法會被重新執(zhí)行;

build方法什么情況下被執(zhí)行呢?:
1、當(dāng)我們的StatelessWidget第一次被插入到Widget樹中時(也就是第一次被創(chuàng)建時);
2、當(dāng)我們的父Widget(parent widget)發(fā)生改變時,子Widget會被重新構(gòu)建;
3、如果我們的Widget依賴InheritedWidget的一些數(shù)據(jù),InheritedWidget數(shù)據(jù)發(fā)生改變時;

2.4.3 重構(gòu)案例代碼
  • 整個代碼都是一些數(shù)據(jù)展示,沒有數(shù)據(jù)的改變,使用StatelessWidget即可
  • 為了體現(xiàn)更好的封裝性,對代碼進(jìn)行了兩層的拆分,讓代碼結(jié)構(gòu)看起來更加清晰

重構(gòu)后的代碼如下:


import 'package:flutter/material.dart';

//只有一行代碼 可用箭頭函數(shù)
main() =>(  runApp(MyApp()));

/*
* Widget:
* 有狀態(tài)的Widget:StatefulWidget 在運行過程中有些狀態(tài)(data)需要改變
* 無狀態(tài)的Widget:StatelessWidget 內(nèi)容是確定滅有狀態(tài)(data)的改變
* */

//寫死的東西則選用StatelessWidget繼承
class MyApp extends StatelessWidget{

//StatelessWidget中的 有個抽象方法 build 必須要實現(xiàn)
  @override
  Widget build(BuildContext context) {

    return  MaterialApp(
      debugShowCheckedModeBanner:false ,
      home: Scaffold(
        appBar: AppBar(
          title:Text("Flutter"),
        ),
        body: HomeBody(),
      ),
    );
  }
}
class HomeBody extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return  Center(
      child: Text("Hello World",
          style: TextStyle(
            color: Colors.red,
            fontSize:32.0,
          )
      ),
    );
  }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容