关于flutter:flutter系列之移动端手势的具体使用

3次阅读

共计 3837 个字符,预计需要花费 10 分钟才能阅读完成。

简介

之前咱们介绍了 GestureDetector 的定义和其提供的一些根本的办法,GestureDetector 的益处就是能够把任何一个 widget 都赋予相似 button 的性能。

明天将会通过几个具体的例子来解说一下 GestureDetector 的具体应用。

赋予 widget 能够点击的性能

个别状况下,咱们的一般 widget,比方文本是不能进行交互的,然而如果将其用 GestureDetector 进行包装之后,就能够将其假装成为一个 button。

比方咱们有这样一个伪装成 button 的 Container:

Container(padding: const EdgeInsets.all(12.0),
        decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.circular(8.0),
        ),
        child: const Text('My Button'),
      )

这个 Container 的实质是一个 Text,这个 Container 自身是没有交互性能的,那么如何对其增加交互性能呢?

最简略的方法就是将其应用 GestureDetector 包装起来,如下所示:

GestureDetector(
      // The custom button
      child: Container(padding: const EdgeInsets.all(12.0),
        decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.circular(8.0),
        ),
        child: const Text('My Button'),
      ),
    )

接下来咱们还要为其增加对应的手势,这里咱们增加一个 onTap 办法,

GestureDetector(onTap: ()=> showDialog<String>(
        context: context,
        builder: (BuildContext context) => AlertDialog(title: const Text('根本手势'),
          content: const Text('这是根本的手势,你学会了吗?'),
          actions: <Widget>[
            TextButton(onPressed: () => Navigator.pop(context, 'Cancel'),
              child: const Text('Cancel'),
            ),
            TextButton(onPressed: () => Navigator.pop(context, 'OK'),
              child: const Text('OK'),
            ),
          ],
        ),
      ),
      ...

这里 onTap 会调用一个 showDialog 来弹出一个对话框,运行之后后果如下:

会动的组件

在下面的例子中,咱们用手去 tap 按钮是没有互动成果的,也就是说按钮是不会变动的。

那么有没有可能模仿手指的按压成果呢?

答案是必定的,flutter 为咱们提供了一个 InkWell 组件,这样手指按压下组件会产生波纹的成果。

那么 InkWell 和 GestureDetector 有什么分割呢?

InkWell 和 GestureDetector 很相似,都提供了对手势的反对。

在 InkWell 中提供了多种 GestureTapCallback 接口,用接管手势的回调,十分的不便。

在应用上,InkWell 和 GestureDetector 也很相似,咱们能够齐全照搬 GestureDetector 的用法。

还是下面的例子,咱们能够将 GestureDetector 替换成为 InkWell, 如下所示:

  Widget build(BuildContext context) {
    return InkWell(onTap: () {ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Tap'),
        ));
      },
      child: const Padding(padding: EdgeInsets.all(12.0),
        child: Text('Flat Button'),
      ),
    );
  }

这里,为了更好的察看手势按压之后的成果,这里 onTap 抉择展现一个 flutter 自带的 SnackBar。

可删除的组件

在 app 中的手势利用上,有一个比拟常见的用法就是在 list 列表中,向左滑动一个 item,会呈现删除的按钮,这种滑动删除的成果,如何在 flutter 中实现呢?

flutter 提供了一个 Dismissible 的组件来实现这个成果。

咱们先来看下 Dismissible 的定义:

class Dismissible extends StatefulWidget {
    const Dismissible({
    required Key key,
    required this.child,
    this.background,
    this.secondaryBackground,
    this.confirmDismiss,
    this.onResize,
    this.onUpdate,
    this.onDismissed,
    this.direction = DismissDirection.horizontal,
    this.resizeDuration = const Duration(milliseconds: 300),
    this.dismissThresholds = const <DismissDirection, double>{},
    this.movementDuration = const Duration(milliseconds: 200),
    this.crossAxisEndOffset = 0.0,
    this.dragStartBehavior = DragStartBehavior.start,
    this.behavior = HitTestBehavior.opaque,
  }) : assert(key != null),
       assert(secondaryBackground == null || background != null),
       assert(dragStartBehavior != null),
       super(key: key);

能够看到 Dismissible 是一个 StatefulWidget,它有两个必须的参数别离是 key 和 child。

key 用来标记要删除 item 的 id,child 是能够滑动删除的组件。

为了演示不便,咱们应用 ListView 来展现如何应用 Dismissible。

首先咱们构建一个 items 的 list,外面蕴含了每个 item 要展现的内容:

 final items = List<String>.generate(10, (i) => '动物 ${i + 1}');

而后应用 ListView 的 builder 办法来构建 items。并且将每个 items 封装到 Dismissible 中去:

body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {final item = items[index];
            return Dismissible(key: Key(item),
              onDismissed: (direction) {setState(() {items.removeAt(index);
                });
                ScaffoldMessenger.of(context)
                    .showSnackBar(SnackBar(content: Text('$item 被删除了')));
              },
              child: ListTile(title: Text(item),
              ),
            );
          },
        )

这里 Dismissible 的 child 是 ListTile 组件,外面的具体内容就是 Text。

当初 Dismissible 实际上就能够工作了,当你滑动 ListTile 的时候,对应的 item 就会被删除。

为了显著起见,咱们能够给 Dismissible 增加一个 background 属性,这样滑动删除的时候就有了一个背景色彩:

              background: Container(color: Colors.red),

另外,Dismissible 还有一个 confirmDismiss 属性,能够用来判断是否真的要滑动删除,比方咱们只容许从右到左滑动删除,那么能够这样做:

Dismissible(
  ...
confirmDismiss:confirmResult,
...
)

  Future<bool> confirmResult(DismissDirection direction) async {if(direction == DismissDirection.endToStart){return true;}
    return false;
  }

这里的 confirmResult 是一个异步函数,它接管一个 DismissDirection 的参数,这个参数示意的是滑动删除的方向,咱们能够通过这个方向来判断是否真正的进行删除操作。

总结

以上就是日常手势的根本应用了,咱们能够通过 GestureDetector,InkWell 和 Dismissible 来和手势进行联合来实现相应的性能。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多内容请参考 www.flydean.com

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

正文完
 0