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

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

1. Opacity 透明度

??????小菜以前在處理 Widget 的顯隱性時用的是設(shè)置 Widget 寬高均為0,方式不太好,偶然間了解到 Opacity,可以通過處理透明度來處理 Widget 的顯隱性。

??????Opacity 可以使子控件透明,可以通過設(shè)置 0.0~1.0之間的值來設(shè)置透明度;對于 0.0 子控件基本沒有繪制過,對于 1.0 會立即繪制而不實用中間緩沖區(qū)。這種方式比直接在 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('當(dāng)前 opacity = 1.0')))),
      new Opacity(
          opacity: 0.0,
          child: new Container(
              height: 80.0,
              color: Colors.green,
              child: new Center(child: new Text('當(dāng)前 opacity = 0.0')))),
      new Opacity(
          opacity: 0.5,
          child: new Container(
              height: 80.0,
              color: Colors.redAccent,
              child: new Center(child: new Text('當(dāng)前 opacity = 0.5'))))
    ],
  );
}

2. Chip 標(biāo)簽

??????小菜以前自定義的標(biāo)簽都是用 Row 配合其他 Widget 來實現(xiàn)的,后來了解到 Chip 不僅節(jié)省了很多時間,效果也很好。配合 Wrap 流式布局可以解決很多問題。

const Chip({
    Key key,
    this.avatar,  // 左側(cè)圖標(biāo)
    @required this.label,  // 標(biāo)簽內(nèi)容,一般是文字
    this.labelStyle,  // 標(biāo)簽樣式
    this.labelPadding,  // 標(biāo)簽內(nèi)邊距
    this.deleteIcon,  // 刪除圖標(biāo),自己配置
    this.onDeleted,  // 刪除方法,必須調(diào)用才會顯示刪除圖標(biāo)
    this.deleteIconColor,  // 刪除圖標(biāo)顏色
    this.deleteButtonTooltipMessage,  // 刪除圖標(biāo)的提示消息
    this.shape,  // 形狀,主要是整個標(biāo)簽樣式,包括圓角等
    this.clipBehavior = Clip.none,
    this.backgroundColor,  // 背景顏色
    this.padding,  // 整個標(biāo)簽內(nèi)邊距
    this.materialTapTargetSize,  // 刪除圖標(biāo)點擊范圍,可不處理
})

Widget childChipWid(var string, var state) {
  Widget childChip;
  if (state == 1) {  // 默認(rèn)圓角
    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) {  // 設(shè)置形狀為圓角矩形
    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 {  // 添加前置圖標(biāo)樣式
    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: 如果要顯示刪除圖標(biāo),一定要實現(xiàn) onDeleted:(){} 方法,否則不顯示。

3. Color 顏色

??????Color 對于每個開發(fā)者都很熟悉,對于小菜來說也必須用的屬性,Flutter 提供了很多設(shè)置顏色的方式,小菜簡單整理一下。

Colors 方式

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

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

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

Colors.black54,
Colors.black87,
Color 方式

??????小菜在做 Android 開發(fā)時一般是用 16進(jìn)制的色值,Flutter 同樣支持,以 #EE5048 為例:

  1. ARGB 16進(jìn)制方式0x 代表16進(jìn)制,進(jìn)行拆分,第一個參數(shù)為透明度;
Color.fromARGB(0xFF, 0xEE, 0x50, 0x48)
  1. ARGB 10進(jìn)制方式:與16進(jìn)制使用相同,只是需要逐個轉(zhuǎn)成10進(jìn)制數(shù);
Color.fromARGB(255, 240, 80, 72)
  1. RGBO 16進(jìn)制方式:最后一個參數(shù)為 0.0~1.0 之間透明度;
Color.fromRGBO(0xEE, 0x50, 0x48, 1.0)
  1. RGBO 10進(jìn)制方式:與上16進(jìn)制使用相同;
Color.fromRGBO(240, 80, 72, 1.0)
  1. 直接使用16進(jìn)制方式:只需添加 0x 代表16進(jìn)制;
Color(0xFFEE5048)

??????Tips: 0x 后需要設(shè)置透明度 FF (完全不透明) 或其他透明度,如果不設(shè)置透明度,默認(rèn)是全透明。

4. Text 文字換行

??????Text 是我們?nèi)粘R欢〞玫降?Widget,根據(jù)設(shè)置不同的屬性產(chǎn)生不同的樣式效果。小菜主要嘗試了一下?lián)Q行時的效果。

  1. softWrap: false
    只有一行內(nèi)容時,若超過設(shè)置最大寬度,是否自動換行,true 為換行,false 為不換行;
  2. overflow: TextOverflow.clip 只有一行內(nèi)容,不換行時,默認(rèn)截斷超出內(nèi)容,與設(shè)置 clip 屬性效果相同;
  3. overflow: TextOverflow.fade
    只有一行內(nèi)容,不換行時,將超出的文本淡化為透明;當(dāng)設(shè)置多行顯示時,會將最后一行底部略透明顯示;
  4. overflow: TextOverflow.ellipsis
    只有一行內(nèi)容,不換行時,將超出部分用 ... 代替;當(dāng)設(shè)置超過多行時,最后內(nèi)容以 ... 顯示。但就目前小菜研究中,無法像 Android 設(shè)置 ... 在中間或跑馬燈效果,如果有哪位大神了解還請多多指教。
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 測試,超過內(nèi)容自動換行!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 測試,超過內(nèi)容不換行!默認(rèn)自動截斷,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 測試,超過內(nèi)容不換行!手動設(shè)置自動截斷,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 測試,超過內(nèi)容不換行!漸變隱藏,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 測試,超過內(nèi)容不換行!省略號樣式,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 測試,超過內(nèi)容換行!設(shè)置超出超出行數(shù)漸變隱藏,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 測試,超過內(nèi)容換行!設(shè)置超出超出行數(shù)漸變隱藏,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 均分大小而非固定大小,此時小菜想把圖片截取中間部分填充滿而不拉伸,采用 ImageBoxFit 不能很好的實現(xiàn),小菜學(xué)習(xí)了一下 BoxConstraints 布局約束方式,根據(jù)父類布局的最大最小寬高進(jìn)行填充。

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))
    ],
  );
}

??????小菜剛接觸 Flutter 時間不長,還有很多不清楚和不理解的地方,如果又不對的地方還希望多多指出。

來源:阿策小和尚

最后編輯于
?著作權(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)容