Skip to main content

淡入淡出小部件

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
// StatefulWidget 的作用是获取数据并创建一个 State 类。
// 在这种情况下,小部件获取一个标题,并创建一个 _MyHomePageState。
class MyHomePage extends StatefulWidget {
  final String title;

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

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

// State 类负责两件事:保存您可以更新的一些数据,并使用这些数据构建 UI。
class _MyHomePageState extends State<MyHomePage> {
  // 绿色方框是否应该可见。
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    // 绿色方框和其他一些小部件放在这里。
  }
}

3. 显示一个切换可见性的按钮

#

现在您有一些数据来确定绿色方框是否应该可见,您需要一种方法来更新这些数据。 在此示例中,如果方框可见,则将其隐藏。 如果方框隐藏,则显示它。

要处理此问题,请显示一个按钮。当用户按下按钮时, 将布尔值从 true 翻转到 false,或从 false 翻转到 true。 使用 setState() 进行此更改, 这是 State 类上的一个方法。 这告诉 Flutter 重建小部件。

有关处理用户输入的更多信息, 请参阅食谱的手势部分。

dart
FloatingActionButton(
  onPressed: () {
    // 调用 setState。这告诉 Flutter 使用更改重建 UI。
    setState(() {
      _visible = !_visible;
    });
  },
  tooltip: '切换不透明度',
  child: const Icon(Icons.flip),
)

4. 淡入淡出方框

#

屏幕上有一个绿色方框和一个按钮,可以将可见性切换为 truefalse。如何淡入淡出方框?使用 AnimatedOpacity 小部件。

AnimatedOpacity 小部件需要三个参数:

  • opacity:0.0(不可见)到 1.0(完全可见)之间的值。
  • duration:动画完成所需的时间。
  • child:要动画的小部件。在这种情况下,是绿色方框。
dart
AnimatedOpacity(
  // 如果小部件可见,则动画到 0.0(不可见)。
  // 如果小部件隐藏,则动画到 1.0(完全可见)。
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 500),
  // 绿色方框必须是 AnimatedOpacity 小部件的子项。
  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 = '不透明度演示';
    return const MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

// StatefulWidget 的作用是获取数据并创建一个 State 类。
// 在这种情况下,小部件获取一个标题,并创建一个 _MyHomePageState。
class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
    required this.title,
  });

  final String title;

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

// State 类负责两件事:保存您可以更新的一些数据,并使用这些数据构建 UI。
class _MyHomePageState extends State<MyHomePage> {
  // 绿色方框是否应该可见
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: AnimatedOpacity(
          // 如果小部件可见,则动画到 0.0(不可见)。
          // 如果小部件隐藏,则动画到 1.0(完全可见)。
          opacity: _visible ? 1.0 : 0.0,
          duration: const Duration(milliseconds: 500),
          // 绿色方框必须是 AnimatedOpacity 小部件的子项。
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 调用 setState。这告诉 Flutter 使用更改重建 UI。
          setState(() {
            _visible = !_visible;
          });
        },
        tooltip: '切换不透明度',
        child: const Icon(Icons.flip),
      ),
    );
  }
}