iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Mobile Development

攜手神隊友ChatGPT:攝護腺自我照護App開發歷程!系列 第 27

D27-解碼Flutter官方文件,一起來了解Layout、Material、Painting、Scrolling widgets

  • 分享至 

  • xImage
  •  

Part1: 今日目標

1.前言
2.內容
3.提問
4.參考連結

Part2: 今日內容

1.前言

2.內容: Part_3: User interface, Widget catalog

Section_9. Layout

這個網頁是關於 Flutter 中的 Layout widgets(佈局小部件),這些佈局小部件提供了豐富多樣的選擇,以滿足開發者在構建 Flutter 應用時的各種需求。

  • Layout widgets(佈局小部件)
    這些小部件可以幫助開發者在 Flutter 應用中安排其他小部件,例如列、行、網格等。

  • Single-child layout widgets(單子元件佈局小部件)
    這些小部件有一個子元件,例如 Align、Aspect Ratio、Baseline 等。

  • Multi-child layout widgets(多子元件佈局小部件)
    這些小部件可以有多個子元件,例如 Row、Column、Stack、Flow 等。

  • Sliver widgets(Sliver 小部件)
    這些小部件用於創建自定義滾動效果,例如 SliverAppBar、SliverGrid、SliverList 等。

  • GridView
    這是一個網格列表,由垂直和水平佈局的單元格組成,用於顯示其子元件。

  • ListView
    這是一個可滾動的線性小部件列表,是最常用的滾動小部件。
    Question: 舉例說明
    Ans: ListView 是 Flutter 中一個非常常用的滾動小部件,它允許開發者在垂直方向上排列一系列的小部件,並且當這些小部件超出螢幕範圍時,用戶可以滾動查看它們。

// 創建了一個 ListView。ListView 中包含了多個 ListTile 小部件,每個 ListTile 都有一個圖標和一個文本。
// 用戶可以垂直滾動 ListView 來查看所有的 ListTile。
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView Example'),
        ),
        body: MyListView(),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.map),
          title: Text('Map'),
        ),
        ListTile(
          leading: Icon(Icons.photo),
          title: Text('Photo'),
        ),
        ListTile(
          leading: Icon(Icons.phone),
          title: Text('Phone'),
        ),
        // 可以繼續添加更多的 ListTile 或其他小部件
      ],
    );
  }
}
  • Stack
    這個小部件可以重疊多個子元件。

  • Flow
    這個小部件實現了流佈局算法,可以安排多個子元件。

Question: 關於流佈局算法的詳細說明?
Ans:

  • 流布局算法(Flow Layout Algorithm)是一種動態計算和安排小部件位置和大小的算法。在 Flutter 中,Flow 小部件使用這種算法來安排其子小部件。流布局算法的主要特點是它可以讓子小部件按照預定的規則和方向排列,並且可以根據空間的可用性動態地調整它們的大小和位置。

  • Flow 小部件的特點:

    • 動態大小和位置:子小部件的大小和位置會基於它們的內容和可用空間動態計算。
    • 靈活性:它允許子小部件在任何方向上排列,並且可以定制排列的規則。
    • 效率:只有當子小部件的大小或位置改變時,Flow 小部件才會重新布局。
  • 範例

// 在這個例子中,Flow 小部件使用了一個自定義的 FlowDelegate 來安排子小部件。子小部件會按照它們的順序和大小在可用空間中排列,如果一行的空間不足,它們會自動換到下一行。
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flow Example')),
        body: Flow(
          delegate: ExampleFlowDelegate(),
          children: [
            Container(width: 80, height: 80, color: Colors.red),
            Container(width: 150, height: 80, color: Colors.green),
            // 更多子小部件...
          ],
        ),
      ),
    );
  }
}

class ExampleFlowDelegate extends FlowDelegate {
  @override
  Size getSize(BoxConstraints constraints) => Size(double.infinity, 200);

  @override
  void paintChildren(FlowPaintingContext context) {
    double x = 0;
    for (int i = 0; i < context.childCount; i++) {
      final width = context.getChildSize(i)!.width;
      if (x + width > context.size.width) x = 0;
      context.paintChild(i, transform: Matrix4.translationValues(x, 0, 0));
      x += width;
    }
  }

  @override
  bool shouldRepaint(covariant FlowDelegate oldDelegate) => false;
}
  • Flow 小部件是一個能夠根據 FlowDelegate 中的邏輯,有效地調整和定位子元件的小部件。這種流佈局對於使用變換矩陣重新定位子元件是優化過的。

  • Flow 容器的大小是獨立於子元件的,由 FlowDelegate.getSize 函數決定。

  • 子元件則是根據來自 FlowDelegate.getConstraintsForChild 函數的約束獨立調整大小的。

  • 子元件不是在佈局期間定位的,而是在繪製階段使用來自 FlowDelegate.paintChildren 函數的變換矩陣定位的。通過僅重新繪製流,可以有效地重新定位子元件,這發生在不再次佈局子元件的情況下。

  • 這個小部件提供了一個例子,展示了如何使用 Flow 小部件創建一個可以互動的菜單,菜單中的按鈕顏色會改變以指示哪一個被選中。

  • 這個小部件的一個有效的使用方式是將動畫提供給構造函數,Flow 會監聽這個動畫並在動畫每次滴答時重新繪製,避免了管道的構建和佈局階段。

  • Row 和 Column
    這些小部件可以將其子元件沿著給定的軸順序排列。

Question: Single-child layout widgets 和 Multi-child layout widgets 的差別為何?

Ans: 主要差別在於它們可以容納的子元件的數量。

  • Single-child layout widgets(單子元件佈局小部件)

    • 這類小部件只能有一個子元件。它們通常用於調整單個子元件的大小、位置或外觀。
    • 例如:Container、Align、Center、Padding等。
  • Multi-child layout widgets(多子元件佈局小部件)

    • 這類小部件可以容納多個子元件。它們通常用於定義多個子元件之間的佈局關係,例如排列(水平、垂直)、層疊等。
    • 例如:Row、Column、Stack、ListView、GridView等。

總結,單子元件佈局小部件專注於單一子元件的佈局和外觀調整,而多子元件佈局小部件則處理多個子元件之間的佈局和排列。


Section_10. Material Components

這個網頁介紹了實現 Material 3 設計規範的各種 Flutter widgets,該頁面還提供了更多 widgets 的目錄連結,用於查看 Flutter 的 widget 目錄。

  • 動作(Actions)
    包含可點擊的區塊,用於啟動某個動作,例如發送電子郵件、分享文檔或點贊評論。

  • 通訊(Communication)
    提供了各種與通訊相關的 widgets,例如消息提示和底部的補充內容容器。

  • 容器(Containment)
    包含了各種容器 widgets,例如用於顯示短小、相關內容的容器和用於顯示更多數據或做出決定的懸浮容器。

  • 導航(Navigation)
    包含了各種與導航相關的 widgets,例如用於在應用中切換主要目的地的持久容器和用於在應用的不同部分之間導航的滑動容器。

  • 選擇(Selection)
    包含了各種與選擇相關的 widgets,例如用於從一組選項中選擇一個或多個選項的表單控件和用於選擇一個值範圍的表單控件。

  • 文本輸入(Text Inputs)
    包含了各種與文本輸入相關的 widgets,例如用於輸入文本的文本框。

Section_11. Painting and effects

這個網頁介紹了Flutter中的「Painting and effects」小部件,這些小部件對子元件進行視覺效果的應用,但不會改變它們的佈局、大小或位置。以下是一些主要的小部件:
過濾小部件(Filter Widget):

這個小部件會對已有的繪製內容應用一個過濾器,然後繪製一個子元件。這種效果相對較為昂貴,尤其是如果過濾器很複雜的時候。

  • 橢圓剪裁小部件(Oval Clip Widget)
    這個小部件會使用一個橢圓來剪裁其子元件。

  • 路徑剪裁小部件(Path Clip Widget)
    這個小部件會使用一個路徑來剪裁其子元件。

  • 矩形剪裁小部件(Rectangle Clip Widget)
    這個小部件會使用一個矩形來剪裁其子元件。

  • 其他:畫布小部件(Canvas Widget)、裝飾小部件(Decoration Widget)、分數轉換小部件(Fractional Translation Widget)等等。


Section_12. Scrolling widgets

這個網頁介紹了Flutter中與滾動相關的小部件。

  • ScrollView: 使用slivers創建自定義滾動效果的滾動視圖。

  • DraggableScrollableSheet: 一個可以響應拖動手勢來調整滾動小部件大小的容器,直到達到一個限制,然後開始滾動。

  • GridView: 一個由垂直和水平布局的單元格組成的網格列表。

  • ListView: 一個可滾動的線性小部件列表,是最常用的滾動小部件。

  • NestedScrollView: 一個可以嵌套其他滾動視圖的滾動視圖,它們的滾動位置是固有聯繫的。

  • 其他: NotificationListener、PageView、RefreshIndicator、SingleChildScrollView等等。

善待生活,熱愛一切,經常開懷大笑
live well, love lots, and laugh often.
連假到朋友家住宿一晚,一起烤肉玩桌遊又吃了許多美味的食物,好不快樂呀!!


上一篇
D26-解碼Flutter官方文件,一起來了解輸入和交互小部件(Input、Interaction widgets)
下一篇
D28-解碼Flutter官方文件,一起來了解 Styling widgets和Beyond UI的設計: Data & backend
系列文
攜手神隊友ChatGPT:攝護腺自我照護App開發歷程!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言