Flutter基礎(四)開發Flutter應用前須要掌握的Basic Widget

本文首發於公衆號「劉望舒」html

關聯繫列
ReactNative入門系列
React Native組件
Flutter基礎系列前端

前言

學完了Dart語言,接下來就能夠學習Widget了,Flutter的UI界面就是由Widget組成的,Widget的數量繁多,所以我會用幾篇文章來專門介紹它,本篇就來介紹Basics Widget。java

1.什麼是Widget

Flutter的Widget的設計靈感來自於React,主要目的就是使用Widget構建UI。Widget根據其當前配置和狀態來描述視圖,當Widget的狀態發生更改時,Widget會重建其描述。framework將根據前面的描述進行對比,以肯定底層渲染樹從一個狀態轉換到下一個狀態所需的最小更改。 在Flutter中,除了Basics 的文本、圖片、卡片、輸入框這些基礎控件,佈局方式和動畫等也都是由Widget組成的。經過使用不一樣類型的Widget,就能夠實現複雜的界面。 Widget能夠翻譯爲部件,粗略的至關於Android中的View。Widget和View不一樣的是:Widget具備不一樣的生命週期:它是不可變的,每當Widget或者其狀態發生變化時,Flutter的框架都會建立一個新的Widget實例樹。相比之下,Android中的View會被繪製一次,而且在invalidate調用以前不會重繪。程序員

2.Widget的分類

Widget的分類有不少類別,每一個類別下面又包含不少Widget,主要包括如下幾種類別:數組

  • Basics:在構建第一個Flutter應用程序以前,須要知道的Basics Widget。
  • Material Components:Material Design風格的Widget。
  • Cupertino:iOS風格的Widget。
  • Accessibility:輔助功能Widget。
  • Animation and Motion:動畫和動做Widget。
  • Async:Flutter應用程序的異步Widget。
  • Input:除了在Material Components和Cupertino中的輸入Widget外,還能夠接受用戶輸入的Widget。
  • Interaction Models:響應觸摸事件並將用戶路由到不一樣的視圖中。
  • Layout:用於佈局的Widget。
  • Painting and effects:不改變佈局、大小、位置的狀況下爲子Widget應用視覺效果。
  • Scrolling:滾動相關的Widget。
  • Styling:主題、填充相關Widget。
  • Text:顯示文本和文本樣式。

Basics有些特殊,它是由Flutter官方從其餘的Widget分類中選取的一些Widget組成的,這些Widget是官方建議開發者構建第一個Flutter應用程序以前,須要知道的,目的是讓開發者更快的入門。好比Row屬於Layout分類,它就被選進了Basics中。本文遵循了Flutter官方的意圖,首先介紹Basics(Basics Widget)。bash

Widget更多的是以組合的形式存在,好比Container是屬於Layout中的一個Widget,而Container又由LimitedBox、 ConstrainedBox、Align、 Padding、 DecoratedBox、Transform部件組成。 若是要實現Container的自定義效果,能夠組合上面這些Widget以及其餘簡單的Widget,而不是將Container進行子類化實現。網絡

3.Widget的狀態分類

在Android中,咱們能夠經過直接更改View來更新視圖。可是在Flutter中,Widget是不可變的而且不會直接更新,而是必須使用Widget的狀態。 Widget有兩種狀態分類分別是無狀態的StatelessWidget和有狀態的StatefulWidget,StatelessWidget是不可變的,設置之後就不可再變化,全部的值都是最終的設置。StatefulWidget能夠保存本身的狀態,可是Widget是不可變的,所以須要配合State來保存狀態。 State擁有本身的聲明週期,以下所示:app

名稱 狀態
initState create以後被insert到渲染樹時調用的,只會調用一次
didChangeDependencies state依賴的對象發生變化時調用
didUpdateWidget Widget狀態改變時候調用,可能會調用屢次
build 構建Widget時調用
deactivate 當移除渲染樹的時調用
dispose Widget即將銷燬時調用

4.根Widget的種類

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
     ...
        ),
      ),
    );
  }
}
複製代碼

上面的MaterialApp就是一個根Widget,也就是Flutter應用程序的第一個Widget,根Widget有如下幾種:框架

  • WidgetsApp: 若是須要自定義風格,可使用WidgetsApp。
  • MaterialApp:Material Design風格的Widget。
  • CupertinoApp iOS風格的根Widget。

若是公司沒有特殊要求,這裏建議使用MaterialApp作爲根Widget就能夠了。less

5.Basics Widget

Basics Widget也就是Basics,主要有如下幾種:

  • Container:一個便利的容器Widget,能夠設置Widget的背景、尺寸、定位。
  • Row:在水平方向上佈置子窗口Widget列表。
  • Column:在垂直方向上佈置子窗口Widge列表。
  • Image:顯示圖像的Widget
  • Text:單同樣式的文本。
  • Icon:符合Material Design設計規範的圖標
  • RaisedButton:符合Material Design設計規範的凸起按鈕。
  • Scaffold:實現Basics 的Material Design佈局結構。
  • Appbar:Material Design的應用欄。
  • FlutterLogo:以Widget形式來展現一個Flutter圖標,能夠調整樣式。
  • Placeholder:繪製一個框,爲未來添加的Widget的佔位。

這裏選擇一些咱們必需要掌握的Basics Widget來進行講解。

5.1 代碼模板和主題

爲了更好的理解這些Basics Widget,咱們須要寫一些例子,這些例子須要一個代碼模板,方便測試和學習。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(//1
      title: 'Welcome to Flutter',
      home: Scaffold(//2
        appBar: AppBar(//3
          title: Text('Basics Widget'),
        ),
        body:
          Padding(
            padding: EdgeInsets.all(40.0),
            child:  Text('在這裏編寫和測試其餘Basics Widget'),
          ),
      ),
    );
  }
}
複製代碼

上面的代碼是稍微改動了官方的Hello World代碼,便於測試,具體的代碼含義已經在Flutter基礎(二)Flutter開發環境搭建和Hello World中講過了,這裏結合本文要講的內容再說點細節。註釋1處的MaterialApp屬於Material Components類別中的Widget,MaterialApp中包含了實現Material Design的應用程序所須要的Widget。 註釋2和3處的Scaffold和AppBar一樣也是Material Components類別中的Widget,Scaffold實現了Material Design佈局結構,AppBar是Material Design的應用欄,它們會在下一篇文章介紹Material Components時進行講解。效果以下圖所示:

5.2 文本

在4.1小節中已經用了Text,還能夠定義樣式:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Basics Widget'),
        ),
        body: Padding(
          padding: EdgeInsets.all(60.0),
          child: Text(
            '文本樣式',
            style: TextStyle(
              fontSize: 16.0, 
              color: Colors.indigo,
              fontStyle: FontStyle.normal,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}
複製代碼

此次爲了便於理解列出了所有的代碼,此後的舉例只列出改變的部分。 經過TextStyle來定義文本的樣式,效果以下:

VZrQ3V.png

5.3 圖片

Image的構造函數有多種:

  • new Image:從ImageProvider獲取圖片
  • new Image.asset:使用key從AssetBundle獲取圖片
  • new Image.network:加載網絡圖片
  • new Image.file:從文件中獲取圖片
  • new Image.memory:用於從Uint8List獲取圖片

Image的屬性有不少種,主要的屬性爲fit,用於表示圖片的填充模式,參數類型爲BoxFit,BoxFit的取值主要有如下幾種,示例圖片來自flutter官方。

contain 全圖顯示,保持原比例。

cover 全圖充滿,可能拉伸也可能被裁剪
fill 全圖顯示,經過拉伸來充滿目標框
fitHeight 圖片高度充滿目標框,可能拉伸也可能被裁剪
fitWidth 圖片寬度充滿目標框,可能拉伸也可能被裁剪
none 保持圖片的原始大小,剪裁掉位於目標框外的圖片部分
scaleDown 與contain縮小圖像的方式相同,只不過會在必要時縮小以確保圖片徹底在目標框內,若是不縮小等同於none。

child: Image.network(
            "https://upload-images.jianshu.io/upload_images/1417629-53f7d0902457cbe6.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
            width: 260,
            height: 100,
            fit: BoxFit.fill,
          ),
複製代碼

效果以下圖所示:

VZr8uF.png

5.4 凸起按鈕

凸起按鈕RaisedButton是符合Material Design設計規範的按鈕,能夠經過onPressed來回調按鈕的點擊。

RaisedButton(
            onPressed: () => print("onPressed"),
            color: Colors.lightBlueAccent,
            child: Text('RaisedButton', style: TextStyle(fontSize: 10)),
          ),
複製代碼

除了使用RaisedButton,flutter還提供了其餘的按鈕,好比FlatButton、IconButton、FloatingActionButton等等,它們的使用方法和RaisedButton大同小異,這裏就再也不贅述。

5.5 其餘Widget

Basics Widget中的還有Row、Column、Container等Widget,這裏簡單介紹下。

Row Row用於在水平方向顯示數組中的子元素Widget。

child: Row(
            children: <Widget>[
              Icon(Icons.access_alarm),
              Icon(Icons.add_a_photo),
              Icon(Icons.add_call),
            ],
          ),
複製代碼

垂直方向顯示數組中的子元素Widget用Column,使用方法和Row同樣。這裏須要提到的是Expanded,能夠用Expanded來配合Row和Column使用,用來填充剩餘的空間。

Row(
            children: <Widget>[
              Icon(Icons.access_alarm),
              Icon(Icons.add_a_photo),
              Icon(Icons.add_call),
              Expanded(
                child: FittedBox(
                  fit: BoxFit.contain,
                  child: const FlutterLogo(), ), flex: 2, ), Expanded( child: Text( "佔剩餘部分的三分之一", ), flex: 1, ), ], ), 複製代碼

其中的Expanded的做用是在本身的尺寸範圍內縮放而且調整child位置,使得child適合其尺寸。FlutterLogo是Basics Widget中的一種,用於展現Flutter圖標。使用flex能夠調整兩個Expanded的佔比。

Container 一個便利的容器Widget,能夠設置Widget的背景、尺寸、定位。描述起來有些抽象,能夠理解它和Android中的ViewGroup差很少。

Container(
              decoration:BoxDecoration(
                color: Colors.lightGreen
              ),
            child: Text('Container'),
            padding: EdgeInsets.all(36.0),
            margin: EdgeInsets.all(10.0),
          ),
複製代碼

Container的padding和margin屬性和Android中的做用是相似的:

總結

本文主要介紹了什麼是Widget、Widget的分類、Basics Widget。由於Widget的數量繁多,官方將Widget進行了分類,並將須要先了解的Widget納入到了Basics Widget中,後續文章會介紹其餘的Widge分類。


分享大前端、Android、Java等技術,助力5萬程序員成長進階。

相關文章
相關標籤/搜索