我怎么给 Flutter 的 widget 添加一个点击监听者?

在 Flutter 中,有两种方法来添加点击监听者:
1、如果 widget 本身支持事件监测,直接传递给它一个函数,并在这个函数里实现响应方法。例如,RaisedButton widget 拥有一个 RaisedButton 参数:

@override
Widget build(BuildContext context) {
  return RaisedButton(
    onPressed: () {
      print("click");
    },
    child: Text("Button"),
  );
}

2、如果 widget 本身不支持事件监测,则在外面包裹一个 GestureDetector,并给它的 onTap 属性传递一个函数:

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          child: FlutterLogo(
            size: 200.0,
          ),
          onTap: () {
            print("tap");
          },
        ),
      ),
    );
  }
}

我怎么处理 widget 上的其他手势?

使用 GestureDetector 你可以监听更广阔范围内的手势,比如:

Tapping
    onTapDown — 在特定位置轻触手势接触了屏幕。
    onTapUp — 在特定位置产生了一个轻触手势,并停止接触屏幕。
    onTap — 产生了一个轻触手势。
    onTapCancel — 触发了 onTapDown 但没能触发 tap。
Double tapping
    onDoubleTap — 用户在同一个位置快速点击了两下屏幕。
Long pressing
    onLongPress — 用户在同一个位置长时间接触屏幕。
Vertical dragging
    onVerticalDragStart — 接触了屏幕,并且可能会垂直移动。
    onVerticalDragUpdate — 接触了屏幕,并继续在垂直方向移动。
    onVerticalDragEnd — 之前接触了屏幕并垂直移动,并在停止接触屏幕前以某个垂直的速度移动。
Horizontal dragging
    onHorizontalDragStart — 接触了屏幕,并且可能会水平移动。
    onHorizontalDragUpdate — 接触了屏幕,并继续在水平方向移动。
    onHorizontalDragEnd — 之前接触屏幕并水平移动的触摸点与屏幕分离。

下面这个例子展示了一个 GestureDetector 是如何在双击时旋转 Flutter 的 logo 的:

import 'package:flutter/material.dart';

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AnimateApp(),
    );
  }
}

class AnimateApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _AnimateAppState();
  }
}

class _AnimateAppState extends State<AnimateApp>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<double> animation;
  CurvedAnimation curve;

  @override
  void initState() {
    super.initState();
    // 创建 AnimationController 对象
    controller = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 2000));
    curve = CurvedAnimation(parent: controller, curve: Curves.easeIn);
    // 通过 Tween 对象 创建 Animation 对象
    animation = Tween(begin: 50.0, end: 200.0).animate(controller)
      ..addListener(() {
        // 注意:这句不能少,否则 widget 不会重绘,也就看不到动画效果
        setState(() {});
      });
    // 执行动画
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'AnimateApp',
        theme: ThemeData(primaryColor: Colors.blue),
        home: Scaffold(
            appBar: AppBar(
              title: Text('AnimateApp'),
            ),
            body: Center(
              child: GestureDetector(
                child: RotationTransition(
                    turns: curve,
                    child: FlutterLogo(
                      size: 200.0,
                    )),
                onDoubleTap: () {
                  if (controller.isCompleted) {
                    controller.reverse();
                  } else {
                    controller.forward();
                  }
                },
              ),
            )));
  }

  @override
  void dispose() {
    // 资源释放
    controller.dispose();
    super.dispose();
  }
}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐