Flutter 21: 易忽略的【小而巧】的技術點彙總 (二)

TigerJin發表於2021-09-09

  小菜繼續整理一些個人不太注意但非常有用的小功能點,可能也是大家熟悉的,只是為了以後使用方便查詢。

1. Opacity 透明度

      小菜以前在處理 Widget 的顯隱性時用的是設定 Widget 寬高均為0,方式不太好,偶然間瞭解到 ,可以透過處理透明度來處理 Widget 的顯隱性。

      Opacity 可以使子控制元件透明,可以透過設定 0.0~1.0之間的值來設定透明度;對於 0.0 子控制元件基本沒有繪製過,對於 1.0 會立即繪製而不實用中間緩衝區。這種方式比直接在 Widget 中新增和刪除子控制元件更有效。

      Tips: opacity 的值必須在 0.0~1.0 之間,類似於 Android 中的 VisibleinVisible 效果。

Widget childOpacityWid(BuildContext context) {  return new Column(
    children: <Widget>[      new Opacity(
          opacity: 1.0,
          child: new Container(
              height: 80.0,
              color: Colors.blue,
              child: new Center(child: new Text('當前 opacity = 1.0')))),      new Opacity(
          opacity: 0.0,
          child: new Container(
              height: 80.0,
              color: Colors.green,
              child: new Center(child: new Text('當前 opacity = 0.0')))),      new Opacity(
          opacity: 0.5,
          child: new Container(
              height: 80.0,
              color: Colors.redAccent,
              child: new Center(child: new Text('當前 opacity = 0.5'))))
    ],
  );
}

圖片描述

2. Chip 標籤

      小菜以前自定義的標籤都是用 Row 配合其他 Widget 來實現的,後來瞭解到 Chip 不僅節省了很多時間,效果也很好。配合 Wrap 流式佈局可以解決很多問題。

const Chip({
    Key key,    this.avatar,  // 左側圖示
    @required this.label,  // 標籤內容,一般是文字
    this.labelStyle,  // 標籤樣式
    this.labelPadding,  // 標籤內邊距
    this.deleteIcon,  // 刪除圖示,自己配置
    this.onDeleted,  // 刪除方法,必須呼叫才會顯示刪除圖示
    this.deleteIconColor,  // 刪除圖示顏色
    this.deleteButtonTooltipMessage,  // 刪除圖示的提示訊息
    this.shape,  // 形狀,主要是整個標籤樣式,包括圓角等
    this.clipBehavior = Clip.none,    this.backgroundColor,  // 背景顏色
    this.padding,  // 整個標籤內邊距
    this.materialTapTargetSize,  // 刪除圖示點選範圍,可不處理})Widget childChipWid(var string, var state) {
  Widget childChip;  if (state == 1) {  // 預設圓角
    childChip = Chip(
      label: Text(string, style: new TextStyle(fontSize: 16.0)),
      deleteIcon: Icon(Icons.clear, color: Colors.black12),
      labelPadding: EdgeInsets.fromLTRB(6.0, 0.0, 6.0, 0.0),
    );
  } else if (state == 2) {  // 設定形狀為圓角矩形
    childChip = Chip(
      label: Text(string, style: new TextStyle(fontSize: 16.0)),
      deleteIcon: Icon(Icons.clear, color: Colors.black12),
      labelPadding: EdgeInsets.fromLTRB(2.0, 0.0, 2.0, 0.0),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3.0)),
      onDeleted: () {},
    );
  } else {  // 新增前置圖示樣式
    childChip = Chip(
      label: Text(string, style: new TextStyle(fontSize: 16.0)),
      avatar: Icon(Icons.search),
      deleteIcon: Icon(Icons.clear, color: Colors.black12),
      labelPadding: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
      onDeleted: () {},
    );
  }  return childChip;
}

      Tips: 如果要顯示刪除圖示,一定要實現 onDeleted:(){} 方法,否則不顯示。

圖片描述

3. Color 顏色

      Color 對於每個開發者都很熟悉,對於小菜來說也必須用的屬性,Flutter 提供了很多設定顏色的方式,小菜簡單整理一下。

Colors 方式

      Flutter 提供了很多便利的色值可以直接使用;大多數色值的顏色從 100 到 900,增量為 100,數字越小,顏色越淺,數字越大,顏色越深。重點樣本(例如redAccent)僅具有值 100/200/400/700。

Colors.redAccent,Colors.red[200],Colors.red,Colors.red[800],

      還有一系列具有常見不透明度的黑色和白色。例如:black54 是純黑色,具有 54% 的不透明度。

Colors.black54,Colors.black87,
Color 方式

      小菜在做 Android 開發時一般是用 16進位制的色值,Flutter 同樣支援,以 #EE5048 為例:

  1. ARGB 16進位制方式0x 代表16進位制,進行拆分,第一個引數為透明度;

Color.fromARGB(0xFF, 0xEE, 0x50, 0x48)
  1. ARGB 10進位制方式:與16進位制使用相同,只是需要逐個轉成10進位制數;

Color.fromARGB(255, 240, 80, 72)
  1. RGBO 16進位制方式:最後一個引數為 0.0~1.0 之間透明度;

Color.fromRGBO(0xEE, 0x50, 0x48, 1.0)
  1. RGBO 10進位制方式:與上16進位制使用相同;

Color.fromRGBO(240, 80, 72, 1.0)
  1. 直接使用16進位制方式:只需新增 0x 代表16進位制;

Color(0xFFEE5048)

      Tips: 0x 後需要設定透明度 FF (完全不透明) 或其他透明度,如果不設定透明度,預設是全透明。

圖片描述

4. Text 文字換行

      Text 是我們日常一定會用到的 Widget,根據設定不同的屬性產生不同的樣式效果。小菜主要嘗試了一下換行時的效果。

  1. softWrap: false
    只有一行內容時,若超過設定最大寬度,是否自動換行,true 為換行,false 為不換行;

  2. overflow: TextOverflow.clip 只有一行內容,不換行時,預設截斷超出內容,與設定 clip 屬性效果相同;

  3. overflow: TextOverflow.fade
    只有一行內容,不換行時,將超出的文字淡化為透明;當設定多行顯示時,會將最後一行底部略透明顯示;

  4. overflow: TextOverflow.ellipsis
    只有一行內容,不換行時,將超出部分用 ... 代替;當設定超過多行時,最後內容以 ... 顯示。但就目前小菜研究中,無法像 Android 設定 ... 在中間或跑馬燈效果,如果有哪位大神瞭解還請多多指教。

Widget childTextWid(BuildContext context) {  return ListView(
    children: <Widget>[
      Container( height: 50.0, color: Colors.green,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容自動換行!Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: true))),
      Container( height: 50.0, color: Colors.black54,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容不換行!預設自動截斷,Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: false))),
      Container( height: 50.0, color: Colors.black38,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容不換行!手動設定自動截斷,Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: false, overflow: TextOverflow.clip))),
      Container( height: 50.0, color: Colors.redAccent,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容不換行!漸變隱藏,Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: false, overflow: TextOverflow.fade))),
      Container( height: 50.0, color: Colors.blue,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容不換行!省略號樣式,Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: false, overflow: TextOverflow.ellipsis))),
      Container( color: Colors.blueGrey,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容換行!設定超出超出行數漸變隱藏,Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: true, maxLines: 2, overflow: TextOverflow.fade))),
      Container( color: Colors.brown, height: 50.0,
          child: Padding( padding: EdgeInsets.all(5.0),
              child: Text(                  'Text 測試,超過內容換行!設定超出超出行數漸變隱藏,Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?Hello, How are you?',
                  softWrap: true, maxLines: 2, overflow: TextOverflow.ellipsis))),
    ],
  );
}

圖片描述

5. BoxConstraints 佈局約束

      小菜在處理圖片時,為了方便適配,藉助 Expanded 均分大小而非固定大小,此時小菜想把圖片擷取中間部分填充滿而不拉伸,採用 Image 的 不能很好的實現,小菜學習了一下 佈局約束方式,根據父類佈局的最大最小寬高進行填充。

Widget childBoxImgWid(BuildContext context) {  return Column(
    children: <Widget>[
      Expanded(
          flex: 1,
          child: ConstrainedBox(
            child: Image.asset(              'images/icon_hzw01.jpg', fit: BoxFit.cover,
            ),
            constraints: new BoxConstraints.expand(),
          )),
      Expanded(
          flex: 1,
          child: ConstrainedBox(
            child: Image.asset(              'images/icon_hzw02.jpg', fit: BoxFit.cover,
            ),
            constraints: new BoxConstraints.expand(),
          )),
      Expanded(
          flex: 1,
          child: ConstrainedBox(
            child: Image.asset(              'images/icon_hzw03.jpg', fit: BoxFit.cover
            ),
            constraints: new BoxConstraints.expand(),
          )),
    ],
  );
}

圖片描述

Widget childBoxImgWid(BuildContext context) {  return Column(
    children: <Widget>[
      Expanded( flex: 1,
          child: Image.asset('images/icon_hzw01.jpg', fit: BoxFit.cover)),
      Expanded( flex: 1,
          child: Image.asset('images/icon_hzw02.jpg', fit: BoxFit.cover)),
      Expanded( flex: 1,
          child: Image.asset('images/icon_hzw03.jpg', fit: BoxFit.cover))
    ],
  );
}

圖片描述



作者:阿策神奇


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2144/viewspace-2822462/,如需轉載,請註明出處,否則將追究法律責任。

相關文章