捕獲和處理點選動作

我們的 app 不僅要把訊息展示給使用者,還要和使用者進行互動。怎麼回應使用者的點選,拖動等操作行為呢? ——使用 GestureDetector Widget。

你可以透過以下步驟來實現一個按鈕,當用戶點選的時候顯示 snackbar 訊息:

  1. 建立一個按鈕。

  2. GestureDetector 包裹按鈕,並傳入 onTap 回呼函式。

// The GestureDetector wraps the button.
GestureDetector(
  // When the child is tapped, show a snackbar.
  onTap: () {
    const snackBar = SnackBar(content: Text('Tap'));

    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  },
  // The custom button
  child: Container(
    padding: const EdgeInsets.all(12),
    decoration: BoxDecoration(
      color: Colors.lightBlue,
      borderRadius: BorderRadius.circular(8),
    ),
    child: const Text('My Button'),
  ),
)

注意

  1. 如果你想新增點按漣漪效果 (Material Design) 請參考文章 新增點按漣漪效果 (Material Design)

  2. 這裡為了說明原理,我們建立了自定義的按鈕,其實 Flutter 已經為我們準備了很多現成的按鈕供我們使用,比如: ElevatedButtonTextButtonCupertinoButton

互動式範例

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    const title = 'Gesture Demo';

    return const MaterialApp(
      title: title,
      home: MyHomePage(title: title),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: const Center(
        child: MyButton(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    // The GestureDetector wraps the button.
    return GestureDetector(
      // When the child is tapped, show a snackbar.
      onTap: () {
        const snackBar = SnackBar(content: Text('Tap'));

        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      },
      // The custom button
      child: Container(
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.lightBlue,
          borderRadius: BorderRadius.circular(8),
        ),
        child: const Text('My Button'),
      ),
    );
  }
}