點燈坊

失くすものさえない今が強くなるチャンスよ

GestureDetector 模擬 TextButton

Sam Xiao's Avatar 2024-12-22

雖然 Flutter 有內建 TextButton,但亦可使用 GestureDetector 搭配 Text 模擬 TextButton

Version

Flutter 3.24.5

Flutter

button01

  • Android 與 iOS 都成功使用 GestureDetector + Text 實現 TextButton

GestureDector

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  
  State<Home> createState() => _Home();
}

class _Home extends State<Home> {
  
  Widget build(BuildContext context) {
    var appBar = AppBar(
      title: const Text('GestureDetector TextButton'),
    );

    var textButton = GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: const Text(
              'Hello World',
            ),
          ),
        );
      },
      child: Container(
        color: Colors.grey[100],
        padding: EdgeInsets.all(20),
        child: Text('Click Me'),
      ),
    );

    var body = Center(
      child: textButton,
    );

    return Scaffold(
      appBar: appBar,
      body: body,
    );
  }
}

Line 17

var textButton = GestureDetector(
  behavior: HitTestBehavior.opaque,
  onTap: () {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: const Text(
          'Hello World',
        ),
      ),
    );
  },
  child: Container(
    color: Colors.grey[100],
    padding: EdgeInsets.all(20),
    child: Text('Click Me'),
  ),
);
  • 使用 GestureDetector + Text 模擬 TextButton

Line 17

var textButton = GestureDetector(      
  child: Container(
    child: Text('Click Me'),
  ),
);
  • textButton:若要實現 TextButton,必須以 GestureDectorContainer 兩層包裹 Text

Line 28

Container(
  color: Colors.grey[100],
  padding: EdgeInsets.all(20),
  child: Text('Click Me'),
),
  • Container:以 Container 包裹 Text
    • color:設定 背景顏色,要有顏色才能被 GestureDetector 點擊,若設計 沒有顏色,也要以 Colors.transparent 設定為 透明色
    • padding:設定 paddingText 更容易被點擊,否則只有 Text 能被點擊

Line 17

var textButton = GestureDetector(
  behavior: HitTestBehavior.opaque,
  onTap: () {
  }
);
  • GestureDetector:偵測 Tap
    • behavior: HitTestBehavior.opaque:避免子 widget 將 event 吃掉

Conclusion

  • 雖然 Flutter 有內建 TextButton,但因為其內建 padding,所以很難調適到適合的 layout,但使用 GestureDetectorText 則很容易調出各種 layout
  • GestureDetector + Text 僅能對 Text 偵測,所以使用者會很難點擊,因此必須加上其他配套