Flutter 網頁開發人員

此頁面適用於熟悉 HTML 和 CSS 語法,用於排列應用程式 UI 組件的使用者。它會將 HTML/CSS 程式碼片段對應到其 Flutter/Dart 程式碼等效項。

Flutter 是用於建置跨平台應用程式的架構,它使用 Dart 程式語言。若要了解使用 Dart 程式設計與使用 Javascript 程式設計之間的一些差異,請參閱 學習 Dart 作為 JavaScript 開發人員

設計網頁配置和 Flutter 配置之間的一個基本差異,在於了解約束的工作原理,以及小工具的大小和位置。若要深入了解,請參閱 了解約束

範例假設

  • HTML 文件以 <!DOCTYPE html> 開頭,且所有 HTML 元素的 CSS 盒子模型都設定為 border-box,以符合 Flutter 模型。

    {
        box-sizing: border-box;
    }
    
  • 在 Flutter 中,「Lorem ipsum」文字的預設樣式由 bold24Roboto 變數定義如下,以保持語法簡潔

    TextStyle bold24Roboto = const TextStyle(
      color: Colors.white,
      fontSize: 24,
      fontWeight: FontWeight.bold,
    );

執行基本配置操作

下列範例顯示如何執行最常見的 UI 配置任務。

設定文字樣式和對齊

CSS 使用 font 和 color 屬性處理的字型樣式、大小和其他文字屬性,是 TextStyle 子項的個別屬性,而 Text 小工具的子項。

對於用於對齊文字的 CSS 中的 text-align 屬性,Text 小工具有一個 textAlign 屬性。

在 HTML 和 Flutter 中,預設情況下,子元素或小工具會錨定在左上角。

<div class="grey-box">
  Lorem ipsum
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Georgia;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: const Text(
    'Lorem ipsum',
    style: TextStyle(
      fontFamily: 'Georgia',
      fontSize: 24,
      fontWeight: FontWeight.bold,
    ),
    
    textAlign: TextAlign.center, 
  ),
);

設定背景顏色

在 Flutter 中,您可以使用 Containercolor 屬性或 decoration 屬性來設定背景顏色。但是,您不能同時提供這兩個屬性,因為這可能會導致裝飾覆蓋在背景顏色上。當背景為單一顏色時,應優先使用 color 屬性。對於其他情況,例如漸層或圖片,請使用 decoration 屬性。

CSS 範例使用十六進位顏色等效於 Material 顏色盤。

<div class="grey-box">
  Lorem ipsum
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  
  child: Text(
    'Lorem ipsum',
    style: bold24Roboto,
  ),
);
final container = Container(
  // grey box
  width: 320,
  height: 240,
  decoration: BoxDecoration(
    color: Colors.grey[300],
  ),
  
  child: Text(
    'Lorem ipsum',
    style: bold24Roboto,
  ),
);

置中元件

Center 小工具會將其子項水平和垂直置中。

要在 CSS 中達成類似的效果,父元素會使用 flex 或 table-cell 顯示行為。此頁面上的範例顯示 flex 行為。

<div class="grey-box">
  Lorem ipsum
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Text(
      'Lorem ipsum',
      style: bold24Roboto,
    ),
  ),
);

設定容器寬度

若要指定 Container 小工具的寬度,請使用其 width 屬性。這是一個固定寬度,與會調整容器寬度至最大值的 CSS max-width 屬性不同。若要在 Flutter 中模擬該效果,請使用 Container 的 constraints 屬性。建立一個新的 BoxConstraints 小工具,其中包含 minWidthmaxWidth

對於巢狀 Container,如果父項寬度小於子項寬度,子項 Container 會調整其大小以符合父項。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    width: 100%;
    max-width: 240px;
}
final container = Container(
  // grey box
  width: 320,
  
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      width: 240,
      // max-width is 240
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.red[400],
      ),
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
      ),
    ),
  ),
);

調整位置和大小

下列範例說明如何對小工具位置、大小和背景執行較複雜的操作。

設定絕對位置

預設情況下,小工具會相對於其父項定位。

若要為小工具指定絕對位置作為 x-y 座標,請將其巢狀在 Positioned 小工具中,而該小工具又巢狀在 Stack 小工具中。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    position: relative;
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    position: absolute;
    top: 24px;
    left: 24px;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Stack(
    children: [
      Positioned(
        // red box
        left: 24,
        top: 24,
        
        child: Container(
          padding: const EdgeInsets.all(16),
          decoration: BoxDecoration(
            color: Colors.red[400],
          ),
          child: Text(
            'Lorem ipsum',
            style: bold24Roboto,
          ),
        ),
      ),
    ],
  ),
);

旋轉元件

若要旋轉小工具,請將其巢狀在 Transform 小工具中。使用 Transform 小工具的 alignmentorigin 屬性分別以相對和絕對方式指定變換原點 (支點)。

對於簡單的 2D 旋轉,其中小工具在 Z 軸上旋轉,請建立新的 Matrix4 身分物件,並使用其 rotateZ() 方法,使用弧度 (度數 × π / 180) 來指定旋轉因子。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    transform: rotate(15deg);
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Transform(
      alignment: Alignment.center,
      transform: Matrix4.identity()..rotateZ(15 * 3.1415927 / 180),
      child: Container(
        // red box
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.red[400],
        ),
        child: Text(
          'Lorem ipsum',
          style: bold24Roboto,
          textAlign: TextAlign.center,
        ),
      ),
    ),
  ),
);

縮放元件

若要縮放小工具,請將其巢狀在 Transform 小工具中。使用 Transform 小工具的 alignmentorigin 屬性分別以相對或絕對方式指定變換原點 (支點)。

對於沿 x 軸的簡單縮放操作,請建立新的 Matrix4 身分物件,並使用其 scale() 方法來指定縮放因子。

當您縮放父小工具時,其子小工具會相應縮放。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    transform: scale(1.5);
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Transform(
      alignment: Alignment.center,
      transform: Matrix4.identity()..scale(1.5),
      child: Container(
        // red box
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.red[400],
        ),
        child: Text(
          'Lorem ipsum',
          style: bold24Roboto,
          textAlign: TextAlign.center,
        ),
      ),
    ),
  ),
);

套用線性漸層

若要將線性漸層套用至小工具的背景,請將其巢狀置於 Container 小工具中。然後使用 Container 小工具的 decoration 屬性來建立 BoxDecoration 物件,並使用 BoxDecorationgradient 屬性來轉換背景填滿。

漸層「角度」基於對齊 (x, y) 值

  • 如果開始和結束 x 值相等,則漸層為垂直 (0° | 180°)。
  • 如果開始和結束 y 值相等,則漸層為水平 (90° | 270°)。

垂直漸層

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    padding: 16px;
    color: #ffffff;
    background: linear-gradient(180deg, #ef5350, rgba(0, 0, 0, 0) 80%);
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment(0.0, 0.6),
          colors: <Color>[
            Color(0xffef5350),
            Color(0x00ef5350),
          ],
        ),
      ),
      
      padding: const EdgeInsets.all(16),
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
      ),
    ),
  ),
);

水平漸層

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    padding: 16px;
    color: #ffffff;
    background: linear-gradient(90deg, #ef5350, rgba(0, 0, 0, 0) 80%);
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      padding: const EdgeInsets.all(16),
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment(-1.0, 0.0),
          end: Alignment(0.6, 0.0),
          colors: <Color>[
            Color(0xffef5350),
            Color(0x00ef5350),
          ],
        ),
      ),
      
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
      ),
    ),
  ),
);

操作形狀

下列範例顯示如何製作和自訂形狀。

圓角

若要將矩形形狀的角落變圓,請使用 BoxDecoration 物件的 borderRadius 屬性。建立新的 BorderRadius 物件,指定每個角落的圓角半徑。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    border-radius: 8px;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red circle
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.red[400],
        borderRadius: const BorderRadius.all(
          Radius.circular(8),
        ), 
      ),
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
      ),
    ),
  ),
);

加入方塊陰影

在 CSS 中,您可以使用 box-shadow 屬性以簡寫方式指定陰影偏移和模糊。此範例顯示兩個方塊陰影,其屬性為

  • xOffset: 0px, yOffset: 2px, blur: 4px, color: black @80% alpha
  • xOffset: 0px,yOffset: 06x,模糊:20px,顏色:黑色 @50% alpha

在 Flutter 中,每個屬性和值都是分開指定的。使用 BoxDecorationboxShadow 屬性來建立 BoxShadow 小工具的清單。您可以定義一個或多個 BoxShadow 小工具,可以堆疊它們來自訂陰影深度、顏色等。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.8),
              0 6px 20px rgba(0, 0, 0, 0.5);
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  margin: const EdgeInsets.only(bottom: 16),
  decoration: BoxDecoration(
    color: Colors.grey[300],
  ),
  child: Center(
    child: Container(
      // red box
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.red[400],
        boxShadow: const <BoxShadow>[
          BoxShadow(
            color: Color(0xcc000000),
            offset: Offset(0, 2),
            blurRadius: 4,
          ),
          BoxShadow(
            color: Color(0x80000000),
            offset: Offset(0, 6),
            blurRadius: 20,
          ),
        ], 
      ),
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
      ),
    ),
  ),
);

製作圓形和橢圓形

在 CSS 中製作圓形需要對矩形的四個邊應用 50% 的邊框半徑,儘管有 基本形狀

儘管此方法受到 BoxDecorationborderRadius 屬性的支援,但 Flutter 提供一個 shape 屬性,其中包含 BoxShape 列舉,以達到此目的。

<div class="grey-box">
  <div class="red-circle">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-circle {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    text-align: center;
    width: 160px;
    height: 160px;
    border-radius: 50%;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red circle
      decoration: BoxDecoration(
        color: Colors.red[400],
        shape: BoxShape.circle, 
      ),
      padding: const EdgeInsets.all(16),
      width: 160,
      height: 160,
      
      child: Text(
        'Lorem ipsum',
        style: bold24Roboto,
        textAlign: TextAlign.center, 
      ),
    ),
  ),
);

操作文字

以下範例說明如何指定字型和其他文字屬性。它們也說明如何轉換文字字串、自訂間距和建立摘錄。

調整文字間距

在 CSS 中,您可以分別為 letter-spacing 和 word-spacing 屬性指定長度值,來指定每個字母或字詞之間的空白量。空白量可以是 px、pt、cm、em 等。

在 Flutter 中,您可以將空白指定為 TextStyle 子項的 letterSpacingwordSpacing 屬性的邏輯像素(允許負值)Text 小工具。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    letter-spacing: 4px;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.red[400],
      ),
      child: const Text(
        'Lorem ipsum',
        style: TextStyle(
          color: Colors.white,
          fontSize: 24,
          fontWeight: FontWeight.w900,
          letterSpacing: 4, 
        ),
      ),
    ),
  ),
);

進行內嵌格式變更

一個 Text 小工具可讓您顯示具有一些格式化特徵的文字。若要顯示使用多種樣式的文字(在此範例中,為一個帶有重點的單字),請改用 RichText 小工具。它的 text 屬性可以指定一個或多個 TextSpan 物件,這些物件可以個別設定樣式。

在以下範例中,「Lorem」在一個具有預設(繼承)文字樣式的 TextSpan 中,而「ipsum」在一個具有自訂樣式的獨立 TextSpan 中。

<div class="grey-box">
  <div class="red-box">
    Lorem <em>ipsum</em>
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
}
.red-box em {
    font: 300 48px Roboto;
    font-style: italic;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      decoration: BoxDecoration(
        color: Colors.red[400],
      ),
      padding: const EdgeInsets.all(16),
      child: RichText(
        text: TextSpan(
          style: bold24Roboto,
          children: const <TextSpan>[
            TextSpan(text: 'Lorem '),
            TextSpan(
              text: 'ipsum',
              style: TextStyle(
                fontWeight: FontWeight.w300,
                fontStyle: FontStyle.italic,
                fontSize: 48,
              ),
            ),
          ],
        ),
      ), 
    ),
  ),
);

建立文字摘錄

摘錄會顯示一段文字中的第一行(數行),並處理溢位文字,通常會使用省略號。

在 Flutter 中,請使用 Text 小工具的 maxLines 屬性來指定摘錄中要包含的行數,以及 overflow 屬性來處理溢位文字。

<div class="grey-box">
  <div class="red-box">
    Lorem ipsum dolor sit amet, consec etur
  </div>
</div>

.grey-box {
    background-color: #e0e0e0; /* grey 300 */
    width: 320px;
    height: 240px;
    font: 900 24px Roboto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.red-box {
    background-color: #ef5350; /* red 400 */
    padding: 16px;
    color: #ffffff;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}
final container = Container(
  // grey box
  width: 320,
  height: 240,
  color: Colors.grey[300],
  child: Center(
    child: Container(
      // red box
      decoration: BoxDecoration(
        color: Colors.red[400],
      ),
      padding: const EdgeInsets.all(16),
      child: Text(
        'Lorem ipsum dolor sit amet, consec etur',
        style: bold24Roboto,
        overflow: TextOverflow.ellipsis,
        maxLines: 1, 
      ),
    ),
  ),
);