天天看點

Flutter Widget(1):基礎Widget

1.Container

  • Container類似于android中的ViewGroup。可以實作設定背景顔色、背景圖檔、加邊框、加圓角、各方向對齊等功能,是項目中經常用到的Widget。
  • 對于一個沒有子Widget的Container,在沒有一些限制的條件時,它會盡可能的大;而一旦有了限制或者子Widget,它就會變得盡可能小。
  • key:Container唯一辨別符,用于查找更新。
  • alignment:控制child的對齊方式,如果container或者container父節點尺寸大于child的尺寸,這個屬性設定會起作用,有很多種對齊方式。
  • padding:decoration内部的空白區域,如果有child的話,child位于padding内部。padding與margin的不同之處在于,padding是包含在content内,而margin則是外部邊界,設定點選事件的話,padding區域會響應,而margin區域不會響應。
  • color:用來設定container背景色,如果foregroundDecoration設定的話,可能會遮蓋color效果。
  • decoration:Decoration是對Container進行裝飾的描述。其概念類似與android中的shape。一般實際場景中會使用他的子類BoxDecoration。BoxDecoration提供了對背景色,邊框,圓角,陰影和漸變等功能的定制能力。注意設定了decoration,就不能設定color屬性,否則會報錯,此時應該在decoration中進行顔色的設定。
  • foregroundDecoration:繪制在child前面的裝飾。
  • width:container的寬度,設定為double.infinity可以強制在寬度上撐滿,不設定,則根據child和父節點兩者一起布局。
  • height:container的高度,設定為double.infinity可以強制在高度上撐滿。
  • constraints:添加到child上額外的限制條件。
  • margin:圍繞在decoration和child之外的空白區域,不屬于内容區域。
  • transform:設定container的變換矩陣,類型為Matrix4。
  • child:container中的内容widget。
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'container',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('container'),
        ),
        body: Container(
          child: Text('xhhsasasashs'),
          height: 400.0,
          alignment: Alignment.bottomCenter,
//          color: Colors.redAccent,
          padding: EdgeInsets.all(20.0),
          margin: EdgeInsets.all(12.0),
          decoration: BoxDecoration(
            border: Border.all(
                color: Color(0xffff2200), width: 8.0, style: BorderStyle.solid
            ),
            color: Colors.grey,
            borderRadius: BorderRadius.all(Radius.circular(20)),
            image: new DecorationImage(
              image: NetworkImage('https://www.baidu.com/img/bd_logo1.png'),
              fit: BoxFit.fitWidth
            ),
          ),
          constraints: BoxConstraints(
            maxHeight: 500.0
          )
        ),
      ),
    );
  }
}
           

2.Text

Text 控件是用來顯示一段文本的
  • style:設定文本的樣式,要求TextStyle類型,可以設定字型顔色、大小、字間距等等。
const TextStyle({
    this.inherit: true,         // 為false的時候不顯示
    this.color,                    // 顔色 
    this.fontSize,               // 字号
    this.fontWeight,           // 繪制文本時使用的字型粗細,加粗也用這個字段 
    this.fontStyle,                // FontStyle.normal  FontStyle.italic斜體
    this.letterSpacing,        // 字元間距  就是單個字母或者漢字之間的間隔,可以是負數
    this.wordSpacing,        // 字間距 句字之間的間距
    this.textBaseline,        // 基線,兩個值,字面意思是一個用來排字母的,一人用來排表意字的(類似中文)
    this.height,                // 當用來Text控件上時,行高(會乘以fontSize,是以不以設定過大)
    this.decoration,        // 添加上劃線,下劃線,删除線 
    this.decorationColor,    // 劃線的顔色
    this.decorationStyle,    // 這個style可能控制畫實線,虛線,兩條線,點, 波浪線等
    this.debugLabel,
    String fontFamily,    // 字型
    String package,
  }) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily',
       assert(inherit != null);
           
  • textAlign:對齊方式
  • textDirection:跟textAlign相似,TextDirection.ltr文本從左到右
  • softWrap:是否需要換行。預設為true
  • overflow:超出文本處理,clip 裁剪,ellipsis 顯示省略号,fade 文本淡化
  • maxLines:最大行數
RichText
RichText:Text 隻能顯示一種樣式的文字,如果你想在一段文字中顯示多種樣式的話 ,就需要使用 RichText 了。
RichText(
  text: TextSpan(
    text: 'Hello ',
    style: DefaultTextStyle.of(context).style,
    children: <TextSpan>[
      TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
      TextSpan(text: ' world!'),
    ],
  ),
)
           

3.Image

  • Image:通過ImageProvider來加載圖檔
  • Image.asset:用來加載本地資源圖檔
  • Image.file:用來加載本地(File檔案)圖檔
  • Image.network:用來加載網絡圖檔
  • Image.memory:用來加載Uint8List資源(byte數組)圖檔

圖檔格式上支援: JPEG , PNG ,GIF , 動态 GIF , WebP , 動态WebP , BMP WBMP .

  • width & height

    用來指定顯示圖檔區域的寬高(并非圖檔的寬高)

  • fit

    設定圖檔填充,類似于Android中的ScaleType

    • BoxFit.none

      原始大小居中

    • BoxFit.contain

      包含,不改變原有比例讓容器包含整個圖檔,容器多餘部分填充背景

    • BoxFit.cover

      覆寫,不改變原有比例,讓圖檔充滿整個容器,圖檔多餘部分裁剪

    • BoxFit.fill

      填充,忽略原有的寬高比,填滿為止

    • BoxFit.fitHeight

      縱向圖檔填充

    • BoxFit.fitWidth

      橫向圖檔填充

    • BoxFit.scaleDown

      圖檔大小小于容器事相當于none,圖檔大小大于容器時縮小圖檔大小實作contain

  • color & colorBlendMode

    這兩個屬性需要配合使用,就是顔色和圖檔混合,就類似于Android中的Xfermode,一般少用到

  • alignment

    用來控制圖檔擺放的位置

  • repeat

    用來設定圖檔重複顯示(repeat-x水準重複,repeat-y垂直重複,repeat兩個方向都重複,no-repeat預設情況不重複),就是填充view時候的不同方式。

  • centerSlice

    設定圖檔内部拉伸,相當于在圖檔内部設定了一個.9圖,但是需要注意的是,要在顯示圖檔的大小大于原圖的情況下才可以使用這個屬性,要不然會報錯.理由是下面這個源碼:

    assert(sourceSize == inputSize, 'centerSlice was used with a BoxFit that does not guarantee that the image is fully visible.');

  • matchTextDirection

    這個需要配合Directionality進行使用

  • gaplessPlayback

    當圖檔發生改變之後,重新加載圖檔過程中的樣式

例子
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';

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

//assets/images/tzd.jpg
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
//    debugPaintSizeEnabled = true;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image demo'),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              //加載網絡圖檔
              Image.network(
                'https://www.baidu.com/img/bd_logo1.png?where=super',
                width: 100.0,
                height: 100.0,
              ),

              //加載Assets
              Image.asset(
                'assets/images/tzd.jpg',
                width: 200.0,
                height: 200.0,
              ),

              //Memory
              MemoryImageWidget(),

              //從檔案加載圖檔
              FileImageWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

class FileImageWidget extends StatefulWidget {
  @override
  _FileImageWidgetState createState() => _FileImageWidgetState();
}

class _FileImageWidgetState extends State<FileImageWidget> {
  File _image;

  Future getImge() async {
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image = image;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Center(
          child: _image == null
              ? Text('未選擇圖檔!')
              : Image.file(
                  _image,
                  width: 200.0,
                  height: 200.0,
                ),
        ),
        FlatButton(
          onPressed: getImge,
          child: Text(
            '選擇圖檔',
            style: TextStyle(
              color: Color(0xff0000ff),
            ),
          ),
        ),
      ],
    );
  }
}

//stf StatefulWidget快捷鍵, stl StatelessWidget快捷鍵
class MemoryImageWidget extends StatefulWidget {
  @override
  _MemoryImageWidgetState createState() => _MemoryImageWidgetState();
}

class _MemoryImageWidgetState extends State<MemoryImageWidget> {
  Uint8List bytes;

  @override
  void initState() {
    super.initState();
    rootBundle.load('assets/images/tzd.jpg').then((data) {
      if (mounted) {
        setState(() {
          bytes = data.buffer.asUint8List();
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final _decoration = BoxDecoration(
      image: bytes == null ? null : DecorationImage(image: MemoryImage(bytes)),
    );
    return Container(
      width: 100.0,
      height: 100.0,
      decoration: _decoration,
    );
  }
}

           

4.Icon

圖示元件Icon展示圖示的元件,該元件不可互動,要實作互動圖示,可以考慮使用IconButton元件。圖示相關元件有以下幾個:

  • IconButton:可互動的Icon
  • Icons:架構自帶Icon集合
  • IconTheme:Icon主題
  • ImageIcon:通過AssetImages或者其他圖檔顯示Icon
常用屬性
屬性名 類型 預設值 說明
color Color null 圖示的顔色,例如Colors.green[500]
icon IconData null 展示的具體圖示,可使用Icons圖示清單中的任意一個圖示即可,如Icons.phone表示一個電話的圖示
style TextStyle null 文本樣式,可定義文本的字型大小、顔色、粗細等
size Double 24.0 圖示的大小,注意需要帶上小數位
textDirection TextDirection TextDirection.ltr Icon元件裡也可以添加文本内容。有些文本書寫的方向是從左到右,有些則是從右到左。從左到右使用TextDirection.ltr,從右到左使用TextDirection.rtl
IconButton

圖示按鈕元件IconButton是基于Meterial Design風格的元件,可以響應按下的事件,并且按下時帶水波紋效果。如果它的onPressed回調函數為null,那麼這個按鈕處于禁用狀态,并且不可按下。

常用屬性
屬性名 類型 預設值 說明
alignment AlignmentGeometry Alignment.center 定義IconButton的Icon對齊方式,預設為居中。Alignment可以設定x,y的偏移量
icon Widget null 展示的具體圖示,可以使用Icons圖示清單中任意一個圖示即可,如Icons.phone表示一個電話圖示
color Color null 圖示元件的顔色
disabledColor Color ThemeData.disabledColor 圖示元件禁用狀态的顔色,預設為主題裡的禁用顔色,也可以設定為其他顔色
iconSize double 24.0 圖示的大小,注意需要帶上小數點
onPressed VoidCallback null 當按鈕按下時會觸發此回調事件
tooltip String “” 當按鈕長按下時的提示語句