1. 程式人生 > 其它 >Flutter不常用元件(二)

Flutter不常用元件(二)

ColoredBox

一般我們想要一個帶有背景顏色的元件我們會使用哪個元件?當然第一個想到的就是Container。其實在 Flutter 中還要一個專門用來設定顏色的元件ColoredBox

該元件有以下幾個屬性:

  • Key? key:標識鍵
  • Color color:顏色
  • Widget? child:子元件
const ColoredBox(
  color: Colors.blue,
  child: SizedBox.expand(),
),

![Slide 16_9 - 11](F:\學習\flutter\images\Slide 16_9 - 11.png)

ColorFiltered

顏色濾鏡。

該元件有以下幾個屬性:

  • Key? key:標識鍵
  • ColorFilter colorFilter:顏色濾鏡
  • Widget? child:子元素
ColorFiltered(
  colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.color),
  child: Image.asset("assets/images/hmbb.png", fit: BoxFit.cover),
),

CompositedTransformFollower 和 CompositedTransformTarget

可以讓CompositedTransformFollower

元件跟隨 CompositedTransformTarget元件移動

關於這兩個元件的用法可以檢視

文章:Flutter 元件 | 手牽手,一起走 CompositedTransformFollower 與 CompositedTransformTarget

視訊:Flutter:如何使用Layer Link(CompositedTransformFollower、CompositedTransformTarget)

GridPaper

繪製1px寬的直線網格

  • Key? key:標識鍵
  • Color color:網格線條的顏色。預設值為Color(0x7FC3E8F3)
  • double interval
    :網格中主線之間的距離,以邏輯畫素為單位
  • int divisions = 2:每個主網格單元內的主要分割槽數。預設值為2
  • int subdivisions = 5:預設值為5
  • Widget? child:子元件
const SizedBox.expand(
  child: GridPaper(
    color: Colors.blue,
    interval: 100.0,
    divisions: 2,
    subdivisions: 5,
    child: Text("Hello World 你好世界"),
  ),
),

GridTile

一個帶有 header 和 footer 的元件,一般放在GridView中使用,當然也可以單獨使用。

  • Key? key:標識鍵
  • Widget? header:頭部的元件
  • Widget? footer:尾部的元件
  • Widget child:子元件(中間的元件)
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    mainAxisSpacing: 8,
    crossAxisSpacing: 8,
  ),
  itemBuilder: (context, index) {
    return GridTile(
      header: Align(
        alignment: Alignment.topLeft,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 4),
          margin: const EdgeInsets.all(4),
          decoration: const BoxDecoration(
            color: Colors.red,
            borderRadius: BorderRadius.all(Radius.circular(2)),
          ),
          child: const Text(
            "Hot",
            style: TextStyle(color: Colors.white, fontSize: 12),
          ),
        ),
      ),
      footer: Container(
        color: Colors.white.withOpacity(.8),
        alignment: Alignment.center,
        child: Text("第$index個"),
      ),
      child: Image.asset("assets/images/sxt.jpg", fit: BoxFit.cover),
    );
  },
)

GridTileBar

用在GridTile中實現AppBar樣式的元件

  • Key? key:標識鍵
  • Color? backgroundColor:背景色
  • Widget? leading:最左邊的最近
  • Widget? title:標題
  • Widget? subtitle:副標題
  • Widget? trailing:最右邊的元件
Scaffold(
  body: SafeArea(
    child: GridTile(
      header: GridTileBar(
        backgroundColor: null,
        leading: const BackButton(),
        title: const Text("Favorite"),
        subtitle: const Text("最近更新:今天"),
        trailing: IconButton( icon: const Icon(Icons.share), onPressed: () {}),
      ),
      footer: ButtonBar(
        alignment: MainAxisAlignment.center,
        children: List.generate(
          5,
          (index) => Container(
            height: 12,
            width: 12,
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(index == _index ? 1 : .5),
              borderRadius: const BorderRadius.all(Radius.circular(100)),
            ),
          ),
        ),
      ),
      child: PageView.builder(
        itemCount: 5,
        onPageChanged: (index) {
          _index = index;
          setState(() {});
        },
        itemBuilder: (context, index) =>
            Image.asset("assets/images/sxt.jpg", fit: BoxFit.cover),
      ),
    ),
  ),
);

IgnorePointer

IgnorePointerAbsorbPointer功能一樣,都能讓子元素不再觸發命中測試/事件。

該元件有以下幾個屬性:

  • Key? key:標識鍵
  • bool ignoring:是否會在命中測試中吸收指標。預設為true
  • Widget? child:子元件
  • bool? ignoringSemantics:編譯語義樹時是否忽略此渲染物件的語義

我們來看看這兩個元件的區別:

Column(
  children: [
    Expanded(
      child: Stack(
        children: [
          GestureDetector(
            onTap: () {
              ScaffoldMessenger.of(context).clearSnackBars();
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("穿過了AbsorbPointer")),
              );
            },
            child: Container(color: Colors.blue),
          ),
          Align(
            alignment: Alignment.center,
            child: AbsorbPointer(
              child: ElevatedButton(
                onPressed: () {
                  ScaffoldMessenger.of(context).clearSnackBars();
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text("點選了AbsorbPointer")),
                  );
                },
                child: const Text("AbsorbPointer"),
              ),
            ),
          )
        ],
      ),
    ),
    Expanded(
      child: Stack(
        children: [
          GestureDetector(
            onTap: () {
              ScaffoldMessenger.of(context).clearSnackBars();
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("穿過了IgnorePointer")),
              );
            },
            child: Container(color: Colors.orange),
          ),
          Align(
            alignment: Alignment.center,
            child: IgnorePointer(
              child: ElevatedButton(
                onPressed: () {
                  ScaffoldMessenger.of(context).clearSnackBars();
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text("點選了IgnorePointer")),
                  );
                },
                child: const Text("IgnorePointer"),
              ),
            ),
          ),
        ],
      ),
    ),
  ],
)

我們可以看到,IgnorePointer會透過自身,將點選事件傳遞到下一層的元件,而AbsorbPointer並不會。

ImageFiltered

給圖片增加濾鏡。和BackdropFilter使用相比更簡單。

該元件有以下幾個屬性:

  • Key? key:標識鍵
  • ImageFilter imageFilter:圖片濾鏡效果
  • Widget? child:子元件
ImageFiltered(
  imageFilter: ImageFilter.blur(sigmaX: 50.0, sigmaY: 50.0),
  child: Image.asset("assets/images/sxt.jpg"),
),