跳至主要內容

淡入和淡出 Widget

UI 開發人員經常需要在螢幕上顯示和隱藏元素。然而,快速彈出或關閉螢幕上的元素可能會讓最終使用者感到不協調。相反地,使用不透明度動畫淡入和淡出元素,以創造流暢的體驗。

AnimatedOpacity 小工具讓執行不透明度動畫變得容易。這個食譜使用以下步驟

  1. 建立一個淡入淡出的方塊。
  2. 定義一個 StatefulWidget
  3. 顯示一個切換可見性的按鈕。
  4. 淡入和淡出方塊。

1. 建立一個淡入淡出的方塊

#

首先,建立一些淡入和淡出的東西。在這個範例中,在螢幕上繪製一個綠色的方塊。

dart
Container(
  width: 200,
  height: 200,
  color: Colors.green,
)

2. 定義一個 StatefulWidget

#

現在您有一個可以動畫化的綠色方塊,您需要一種方法來知道方塊是否應該可見。為了實現這一點,請使用 StatefulWidget

StatefulWidget 是一個建立 State 物件的類別。State 物件保留有關應用程式的一些資料,並提供一種更新該資料的方法。在更新資料時,您也可以要求 Flutter 使用這些更改重建 UI。

在這個情況下,您有一條資料:一個布林值,表示按鈕是否可見。

要建構一個 StatefulWidget,請建立兩個類別:一個 StatefulWidget 和一個對應的 State 類別。專業提示:適用於 Android Studio 和 VSCode 的 Flutter 外掛程式包含 stful 片段,可以快速產生此程式碼。

dart
// The StatefulWidget's job is to take data and create a State class.
// In this case, the widget takes a title, and creates a _MyHomePageState.
class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

// The State class is responsible for two things: holding some data you can
// update and building the UI using that data.
class _MyHomePageState extends State<MyHomePage> {
  // Whether the green box should be visible.
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    // The green box goes here with some other Widgets.
  }
}

3. 顯示一個切換可見性的按鈕

#

現在您有一些資料可以決定綠色方塊是否應該可見,您需要一種更新該資料的方法。在此範例中,如果方塊可見,則將其隱藏。如果方塊被隱藏,則顯示它。

為了處理這個問題,請顯示一個按鈕。當使用者按下按鈕時,將布林值從 true 翻轉為 false,或從 false 翻轉為 true。使用 setState() 進行此變更,這是 State 類別的一個方法。這會告訴 Flutter 重建小工具。

有關使用使用者輸入的更多資訊,請參閱食譜的手勢部分。

dart
FloatingActionButton(
  onPressed: () {
    // Call setState. This tells Flutter to rebuild the
    // UI with the changes.
    setState(() {
      _visible = !_visible;
    });
  },
  tooltip: 'Toggle Opacity',
  child: const Icon(Icons.flip),
)

4. 淡入和淡出方塊

#

您在螢幕上繪製了一個綠色方塊,以及一個可以將可見性切換為 truefalse 的按鈕。如何淡入和淡出方塊?使用 AnimatedOpacity 小工具。

AnimatedOpacity 小工具需要三個引數

  • opacity:一個從 0.0 (不可見) 到 1.0 (完全可見) 的值。
  • duration:動畫完成所需的時間。
  • child:要動畫化的小工具。在這個情況下,是綠色方塊。
dart
AnimatedOpacity(
  // If the widget is visible, animate to 0.0 (invisible).
  // If the widget is hidden, animate to 1.0 (fully visible).
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 500),
  // The green box must be a child of the AnimatedOpacity widget.
  child: Container(
    width: 200,
    height: 200,
    color: Colors.green,
  ),
)

互動式範例

#
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const appTitle = 'Opacity Demo';
    return const MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

// The StatefulWidget's job is to take data and create a State class.
// In this case, the widget takes a title, and creates a _MyHomePageState.
class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
    required this.title,
  });

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

// The State class is responsible for two things: holding some data you can
// update and building the UI using that data.
class _MyHomePageState extends State<MyHomePage> {
  // Whether the green box should be visible
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: AnimatedOpacity(
          // If the widget is visible, animate to 0.0 (invisible).
          // If the widget is hidden, animate to 1.0 (fully visible).
          opacity: _visible ? 1.0 : 0.0,
          duration: const Duration(milliseconds: 500),
          // The green box must be a child of the AnimatedOpacity widget.
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Call setState. This tells Flutter to rebuild the
          // UI with the changes.
          setState(() {
            _visible = !_visible;
          });
        },
        tooltip: 'Toggle Opacity',
        child: const Icon(Icons.flip),
      ),
    );
  }
}