Flutter 即學即用系列博客——06 超實用 Widget 集錦

本篇文章咱們來說講一些比較經常使用的 Widget。數組

你們驗證的時候使用下面的代碼替換 main.dart 代碼,而後在 //TODO 語句返回下面經常使用 Widget 示例的代碼。網絡

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: _buildWidget(),
        ),
      ),
    );
  }

  Widget _buildWidget() {
    //TODO
  }

}

目錄

1. Text

1)基本使用less

return Text('Show Regular Text');

2)設置字體樣式ide

屬性:style佈局

設置粗體:學習

return Text(
      'Show Bold Text',
      style: TextStyle(fontWeight: FontWeight.bold),
    );

設置顏色:測試

return Text(
      'Show Bold Red Text',
      style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
    );

其餘樣式相信你們學習過以前的文章,知道如何查看一個 Widget 源碼以及如何使用了。字體

3)設置最大行數及省略號ui

屬性:maxLinesoverflowthis

return Container(
      width: 100,
      child: Text(
        '設置文本超過 100,這樣可以看到效果,這裏設置最多顯示一行',
        maxLines: 1,                      //設置最大行數
        overflow: TextOverflow.ellipsis,  //設置超過顯示省略號
      ),
    );

大概效果以下:

2. Image

1)本地加載圖片

第一步:建立放置圖片的文件夾,這裏假設咱們在 my_flutter 下面建立 assets/images/2.0xassets/images/3.0x 文件夾用於存放本地圖片。

第二步:拷貝圖片 wechat.png 到上述文件夾,通常若是切圖是用 sketch,則直接選擇對應的 2 倍圖和 3 倍圖。

第三步:在 pubspec.yaml 文件肯定要使用的圖片資源位置。這裏能夠定義以下:

assets:
    - assets/images/wechat.png

第四步:使用以下。

return Image.asset('assets/images/wechat.png')

可能有小夥伴會以爲,若是我有不少圖片須要使用,是否是每次執行第三步和第四步的時候都要寫那麼長的路徑。

先說下第四步,若是你都是同個目錄,只是最後圖片名稱不同。那麼你能夠自定義一個包裝類作一層包裝。

接着咱們來講下第三步的狀況。

假設你有不少圖片在同一個文件夾下面,那麼你是能夠在 pubspec.yaml 裏面使用目錄定義的。可是,注意官方文檔的一句話:

Note that only files located directly in the directory will be included; to add files located in subdirectories, create an entry per directory.

簡單的說就是你使用的目錄要到最底層,也就是這個目錄下面就是圖片而不是目錄了。

舉咱們這個例子就是若是你要用目錄定義及使用,上面第三步替換爲

assets:
    - assets/images/2.0x/

第四步替換爲

return Image.asset('assets/images/2.0x/wechat.png');

能夠看到這樣咱們若是一張圖片要適配不一樣尺寸估計就不是很合適了。

所以對於有適配場景的,其實推薦第一種直接配置指定圖片的方式。

舒適提示:

修改 pubspec.yaml 文件以後建議運行以前增長清理工做。

好比以前是執行 flutter run

修改以後建議執行 flutter packages get;flutter clean;flutter run

上面定義的位置能夠直接在 pubspec.yaml 文件搜索 assets,有註釋講解的位置就是你要添加的位置了。

官網:
https://flutter.dev/docs/development/ui/assets-and-images#loading-images

2)網絡加載圖片

給定一個圖片 url,執行下面代碼便可:

return Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240');

3)指定寬高

指定寬高是直接使用 widthheight 屬性。

好比網絡加載圖片指定寬高以下:

return Image.network(
      'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
      width: 300,
      height: 200,
    );

大體效果以下:

3. Column

前面兩個講的都是單個小組件。接下來咱們講的是相似於佈局的組件。(仍是組件,畢竟 Flutter 一切皆 Widget)

1)基本使用

你們看到這個詞,應該會直觀認爲這個就是對於一些佈局爲列的場景吧,可能有多列,然而不是哦。

點進去源碼能夠看到以下注釋:

/// Creates a vertical array of children.

大概意思是建立一組垂直的子組件集合。

若是你是 Android 開發,能夠聯想到 LinearLayout 裏面的 orientation 設置爲 vertical 時的佈局。

以下:

你也能夠這樣記憶,Column 是列,說明佈局只有一列。因此就是上面這種了。

因此上面的 Text 效果圖和 Image 效果圖應該就知道是如何顯示了吧?

咱們這裏給下示例代碼,固然若是你是用帶劉海屏的設備運行,可能頂部會看不到。後面咱們會繼續說明。

return Column(
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

效果以下:

寫法也很簡單,就是設置一下 children 屬性就能夠了。

而後裏面的 Widget 數組填充咱們要展現的 Widget 便可。

上面說了劉海屏設備頂部會看不到,那怎麼辦?

2)mainAxisAlignment

mainAxisAlignment 你能夠認爲是主軸的對齊方式。對於豎直的 Column,那就是豎直方向的對齊。

影響整個 Column

所以能夠設置以下:

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

你就會發現整個 Column 在豎直方向都居中了。

3)crossAxisAlignment

crossAxisAlignment 你能夠認爲是交叉軸的對齊方式,對於豎直的 Column,那就是水平方向的對齊。

影響 Column 裏面的每個 Widget

設置以下:

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

你會發現本來最後一張居中的圖片在水平方向向右邊對齊。

4. Row

1)基本使用

/// Creates a horizontal array of children.

大概意思是建立一組水平的子組件集合,能夠聯想到 LinearLayout 裏面的 orientation 設置爲 horizontal 時的佈局。

也能夠記憶爲 Row 表明行,所以只有一行。

以下:

Sample:

return Row(
      children: <Widget>[
        Text('Widget One', style: TextStyle(color: Colors.blue),),
        Text('Widget Two'),
      ],
    );

效果以下:

能夠看到只有一行,因此使用 Row。

寫法也是比較簡單,就是設置一下 children 屬性就能夠了。

而後裏面的 Widget 數組填充咱們要展現的 Widget 便可。

2)mainAxisAlignment

mainAxisAlignment 你能夠認爲是主軸的對齊方式,對於水平的 Row,那就是水平方向的對齊。

影響整個 Row

所以能夠設置以下:

return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Widget One', style: TextStyle(color: Colors.blue),),
        Text('Widget Two'),
      ],
    );

這樣效果顯示就是上圖居中。

3)crossAxisAlignment

crossAxisAlignment 你能夠認爲是交叉軸的對齊方式,對於水平的 Row,那就是豎直方向的對齊。

影響 Row 裏面的每個 Widget

設置以下:(這裏引入了一個後面纔會講到的 Widget,你們能夠暫時不理,看下效果)

return Container(
      width: 300,
      height: 300,
      color: Colors.grey,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: <Widget>[
          Container(
            width: 100,
            height: 100,
            color: Colors.blue,
            child: Text(
              'Widget One',
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: Colors.yellow,
            child: Text(
              'Widget Two',
            ),
          ),
        ],
      ),
    );

灰色是咱們的父容器,能夠看到兩個控件水平方面居中,豎直方面向下對齊。

5. Container

Container 的使用超級普遍。

咱們這裏略微講一下一些使用場景。

1)給一些沒有自帶寬高的屬性設置寬高。

好比咱們上面講到 Row 最後一個 Sample 的時候,給 Text、Row 設置寬高都是在外面套一層 Container。

2) 設置間距。

以上面 Column 的三張圖片爲例,他們一開始是下面代碼:

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

效果以下:

咱們但願第一張和第二張圖片有點距離,能夠這樣設置:

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Container(
          padding: EdgeInsets.only(top: 20.0),
          child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        ),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

效果以下:

咱們代碼裏面使用 Container 都是把 Widget 拿出來做爲 Container 的 child。

這裏的 padding 使用有三種經常使用寫法:

第一種:上下左右 padding 的值都同樣

源碼:

const EdgeInsets.all(double value)
      : left = value, top = value, right = value, bottom = value;

第二種:上下左右 padding 不一致或者只想設置某一個或某幾個方向

源碼:

const EdgeInsets.only({
    this.left = 0.0,
    this.top = 0.0,
    this.right = 0.0,
    this.bottom = 0.0
  });

第三種:設置水平或者垂直方向的 padding

源碼:

const EdgeInsets.symmetric({ double vertical = 0.0,
                             double horizontal = 0.0 })
    : left = horizontal, top = vertical, right = horizontal, bottom = vertical;

相信如今給出源碼,你們都知道怎麼寫了。

記得花括號是可選參數哈~

Sample:

padding: EdgeInsets.all(left : 20.0),
          padding: EdgeInsets.only(left : 20.0),
          padding: EdgeInsets.symmetric(horizontal : 20.0),

margin 和 padding 也是相似的,區別相信學過 Android 的都知道,你也能夠本身測試一下區別,這裏就不贅餘了。

另外注意 Container 源碼有個註釋:

/// The `height` and `width` values include the padding.

舉個例子就是假設有一張圖片寬 100,假設你左右預留 padding 10,那麼你寬須要設置爲 120。

6. SizedBox

你能夠用來替換須要套一層 Container 來設置 margin 或者 padding 的 Widget。

好比上面的代碼

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        Container(
          padding: EdgeInsets.only(top: 20.0),
          child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        ),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

能夠等效替換爲

return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.asset('assets/images/wechat.png'),
        SizedBox(
          height: 20.0,
        ),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        Image.network(
          'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
          width: 300,
          height: 200,
        )
      ],
    );

Container(
          padding: EdgeInsets.only(top: 20.0),
          child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
        ),

替換成了

SizedBox(
          height: 20.0,
        ),
        Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),

固然這裏因爲 Widget 沒有限制寬高,因此 padding 或者 margin 在這裏起到同樣做用。

嚴格來講 SizedBox 應該是替換 margin。替換 padding 須要注意上面說的寬高影響。

經常使用的 Widget 咱們就介紹到這裏。

其餘的咱們後續再介紹或者你們自行查閱官網 Widget 集合。

相信如今的你能夠根據官網的 Sample 和說明以及親自測試快速掌握新 Widget 的使用。

官網 Widget 集合:
https://flutter.dev/docs/development/ui/widgets

更多閱讀:
Flutter 即學即用系列博客——01 環境搭建
Flutter 即學即用系列博客——02 一個純 Flutter Demo 說明
Flutter 即學即用系列博客——03 在舊有項目引入 Flutter
Flutter 即學即用系列博客——04 Flutter UI 初窺
Flutter 即學即用系列博客——05 StatelessWidget vs StatefulWidget

相關文章
相關標籤/搜索