Flutter學習筆記4--Flutter初識

本文主要介紹Flutter項目的簡單界面構(gòu)建,以及布局

一.創(chuàng)建新的Flutter工程

  1. 使用終端進行創(chuàng)建
    flutter create 項目名
    
    不支持大寫字母,可以加下劃線
    創(chuàng)建成功后,可以使用VSCode或者Android studio打開
  2. 工程內(nèi)容
    lib文件夾:存放編寫的代碼,main.dart即為啟動入口
  3. 項目啟動
    打開iOS或者安卓模擬器, 在工具欄找到啟動調(diào)試,點擊進行啟動

二、flutter項目編寫

  1. flutter項目的幾個特性
    熱重載 hot reload 、 熱重啟 hot restart
    運行一個flutter項目有三種方式: 冷啟動:(從0啟動)、 熱重載 (最主要是執(zhí)行build方法,其他方法不受影響)、 熱重啟(重新運行整個項目)
    使用熱重載可以快速預(yù)覽布局變化,但是只有build方法會重置
  2. 簡單編寫啟動內(nèi)容
    導入頭文件(package:flutter/material.dart), 然后調(diào)用runApp函數(shù)
    import 'package:flutter/material.dart';
    
    main(List<String> args) {
      runApp(Text("Hello world", textDirection: TextDirection.ltr));
    }
    
  3. 具體內(nèi)容設(shè)置
    textDirection 傳入文字方向
    style 設(shè)置樣式,字體顏色等
    Center 也是一個Widget,實現(xiàn)居中操作
    runApp(Center(
      child: Text("Hello world",
          textDirection: TextDirection.ltr,
          style: TextStyle(fontSize: 30, color: Colors.red))));
    

三、Material設(shè)計風格

  1. Widget 即組件
    萬物皆是Widget, 通過嵌套Widget來實現(xiàn)布局功能
    • 有狀態(tài)的Widget:
      StatefulWedget 在運行過程中有一些狀態(tài)(data數(shù)據(jù))需要改變
    • 無狀態(tài)的Widget:
      StatelessWidget 內(nèi)容是確定的,沒有狀態(tài)(data數(shù)據(jù))的改變
  2. 幾種Widget
  • MaterialApp 會自動添加某些默認配置,不需要手動進行設(shè)置,比如文字方向等
     runApp(MaterialApp(
      home: Center(
          child: Text("Hello World",
              style: TextStyle(fontSize: 30, color: Colors.orange)))));
    
  • Scaffold 腳手架 用于快速搭建頁面 創(chuàng)建導航欄、Tabbar等
    主要參數(shù)有 appBar(導航欄或者Tabbar),body(界面內(nèi)容)
    runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(
              title: Text(
            "第一個項目",
            style: TextStyle(fontSize: 20, color: Colors.white),
          )),
          body: Center(
              child: Text("Hello world",
                  textDirection: TextDirection.ltr,
                  style: TextStyle(fontSize: 30, color: Colors.red))))));
    
    debugShowCheckedModeBanner 控制右上角debug標簽的顯示
  1. 自定義Widget子類
    class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          // TODO: implement build
          return Text("hello World");
        }
      }
    

build方法: 在創(chuàng)建自定義Widget子類時,會執(zhí)行它的build方法,返回一個希望渲染的Widget元素,例如上例所示的Text Widget

StatelessWidget沒辦法去主動執(zhí)行build方法,當我們的數(shù)據(jù)發(fā)生改變的時候,build方法會被重新執(zhí)行

  • build方法在什么情況下會執(zhí)行?
    1)當對應(yīng)的StatelessWidget第一次被插入到Widget樹中時,即第一次創(chuàng)建時
    2) 當對應(yīng)的父Widget發(fā)生改變時,子Widget會被重新構(gòu)建
    3) 如果對應(yīng)的Widget依賴inheritedWidget的一些數(shù)據(jù),inheritedWidget數(shù)據(jù)發(fā)生改變時

將需要構(gòu)造的Widget放到build方法中返回,然后直接調(diào)用編寫的Widget子類,即可得到想要的界面```

main(List<String> args) {
        runApp(MyApp());
      }

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            appBar: AppBar(
                title: Text(
              "第一個項目",
              style: TextStyle(fontSize: 20, color: Colors.white),
            )),
            body: Center(
                child: Text("Hello world",
                    textDirection: TextDirection.ltr,
                    style: TextStyle(fontSize: 30, color: Colors.red)))));
  }
}
  1. 代碼拆分抽取
    將各個Widget包裝成一個個自定義Widget子類,再進行組合,完成代碼的拆分重組
main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(debugShowCheckedModeBanner: false, home: HomePageView());
  }
}

class HomePageView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text(
          "第一個項目",
          style: TextStyle(fontSize: 20, color: Colors.white),
        )),
        body: ContentBody());
  }
}

class ContentBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text("Hello world",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 30, color: Colors.orange)));
  }
}
  1. 一行寫入多個控件
    橫向?qū)懭攵鄠€控件 Row
    豎向?qū)懭攵鄠€控件 Column
class ContentBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
      Text("111"),
      Text("Hello world",
          textDirection: TextDirection.ltr,
          style: TextStyle(fontSize: 30, color: Colors.orange))
    ]));
  }
}

默認從每行的最左端開始布局,使用mainAxisAlignment參數(shù)可以改變行內(nèi)的布局位置

  1. @immutable
  • 使用@immutable 注解標明的類及其子類均為不可變類,其中的屬性均不可變,使用final修飾,不可定義狀態(tài)
    Widget類使用@immutable標記,所有的Widget都不可以直接定義狀態(tài)
  • StatelessWidget即是不可更改的類,不可定義狀態(tài)
  • StatefulWidget內(nèi)部有一個抽象方法createState,此方法返回一個State類
  • 在自定義的State子類中通過重寫build方法實現(xiàn)控件
  • StatefulWidget內(nèi)部不可直接定義狀態(tài),但是可以在自定義的State子類中可以定義狀態(tài)
class ContentBody extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ContentBodyState();
  }
}

class _ContentBodyState extends State<ContentBody> {
  var flag = true;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
        child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
      Checkbox(
          value: flag,
          onChanged: (value) {
            setState(() {
              flag = value ?? false;
            });
          }),
      Text("Hello world",
          textDirection: TextDirection.ltr,
          style: TextStyle(fontSize: 30, color: Colors.orange))
    ]));
  }
}

總結(jié):
繼承自StatefulWidget的類負責實現(xiàn)createState方法,返回一個State類
State類負責實現(xiàn)Build方法,以及狀態(tài)的創(chuàng)建,來實現(xiàn)功能

另外需要注意的幾點:

  • 狀態(tài)的改變需要在setState回調(diào)中進行,否則不生效
  • State類一般使用下劃線_開頭,如_ContentBodyState,下劃線開頭的類在別的文件無法訪問,保證安全,而繼承自StatefulWidget的類不加下劃線

問題1:上述示例中,ContentBody返回的State類一定要定義為ContentBody泛型嗎?可以改成別的StatefulWidget類嗎?

可以,但沒必要。
語法上無問題,但是,定義成此泛型,才可以使用系統(tǒng)提供的一個widget屬性來構(gòu)建出橋梁,連通對應(yīng)的StatefulWidget子類,所以一般會這么寫

問題2:繼承自StatefulWidget的類,具體的作用?

1). 生成返回State類
2). 可以接收父Widget傳過來的數(shù)據(jù)
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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