Flutter 构建完整应用手册-处理手势

处理点击

我们不仅希望向用户展示信息,还希望我们的用户与我们的应用进行互动! 那么,我们如何回应基本操作,如点击拖动? 我们将使用GestureDetector部件!

假设我们想要制作一个自定义按钮,当点击时显示snackbar。 我们如何解决这个问题?

路线

  1. 创建按钮
  2. 用onTap回调将其包装在GestureDetector中
// Our GestureDetector wraps our button
new GestureDetector(
  // When the child is tapped, show a snackbar 
  onTap: () {
    final snackBar = new SnackBar(content: new Text("Tap"));

    Scaffold.of(context).showSnackBar(snackBar);
  },
  // Our Custom Button!
  child: new Container(
    padding: new EdgeInsets.all(12.0),
    decoration: new BoxDecoration(
      color: Theme.of(context).buttonColor,
      borderRadius: new BorderRadius.circular(8.0),
    ),
    child: new Text('My Button'),
  ),
);

笔记

完整例子

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'Gesture Demo';

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

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

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

class MyButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Our GestureDetector wraps our button
    return new GestureDetector(
      // When the child is tapped, show a snackbar
      onTap: () {
        final snackBar = new SnackBar(content: new Text("Tap"));

        Scaffold.of(context).showSnackBar(snackBar);
      },
      // Our Custom Button!
      child: new Container(
        padding: new EdgeInsets.all(12.0),
        decoration: new BoxDecoration(
          color: Theme.of(context).buttonColor,
          borderRadius: new BorderRadius.circular(8.0),
        ),
        child: new Text('My Button'),
      ),
    );
  }
}

添加材质涟漪效果

在设计应遵循材质设计指南的应用程序时,我们希望在点击时将涟漪动画添加到部件。

Flutter提供InkWell部件来达到这个效果。

路线

  • 创建一个我们想要点击的部件
  • 将其包装在InkWell部件中以管理点击回调和涟漪动画
// The InkWell Wraps our custom flat button Widget
new InkWell(
  // When the user taps the button, show a snackbar
  onTap: () {
    Scaffold.of(context).showSnackBar(new SnackBar(
      content: new Text('Tap'),
    ));
  },
  child: new Container(
    padding: new EdgeInsets.all(12.0),
    child: new Text('Flat Button'),
  ),
);

完整例子

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'InkWell Demo';

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

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

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

class MyButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // The InkWell Wraps our custom flat button Widget
    return new InkWell(
      // When the user taps the button, show a snackbar
      onTap: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
          content: new Text('Tap'),
        ));
      },
      child: new Container(
        padding: new EdgeInsets.all(12.0),
        child: new Text('Flat Button'),
      ),
    );
  }
}

实现划动消除

“划动消除”模式在很多移动应用中很常见。 例如,如果我们正在编写一个电子邮件应用程序,我们可能希望允许我们的用户在列表中划离邮件消息。 当他们这样做时,我们需要将该项目从收件箱移至垃圾箱。

Flutter通过提供Dismissible部件使这项任务变得简单。

路线

  • 创建条目列表
  • 将每个项目包裹在Dismissible部件中
  • 提供“向后消除”指标

1.创建条目列表

这个配方的第一步是创建一个我们可以滑动的项目列表。 有关如何创建列表的更多详细说明,请按照使用长列表配方进行操作。

创建一个数据源 在我们的例子中,我们需要20个样品条目。 为了简单起见,我们将生成一个字符串列表。

final items = new List<String>.generate(20, (i) => "Item ${i + 1}");

将数据源转换为List 首先,我们将简单地在屏幕上的列表中显示每个条目。 用户将无法用这些物品轻轻一扫!

new ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return new ListTile(title: new Text('${items[index]}'));
  },
);

2.将每个项目包裹在Dismissible部件中

现在我们正在显示项目列表,我们希望让用户能够将每个项目从列表中移除!

用户将该项目删除后,我们需要运行一些代码以从列表中删除该项目并显示Snackbar。 在真实的应用程序中,您可能需要执行更复杂的逻辑,例如从Web服务或数据库中删除项目。

这是Dismissible部件发挥作用的地方! 在我们的例子中,我们将更新我们的itemBuilder函数以返回一个Dismissible部件。

new Dismissible(
  // Each Dismissible must contain a Key. Keys allow Flutter to
  // uniquely identify Widgets.
  key: new Key(item),
  // We also need to provide a function that will tell our app
  // what to do after an item has been swiped away.
  onDismissed: (direction) {
    // Remove the item from our data source
    items.removeAt(index);

    // Show a snackbar! This snackbar could also contain "Undo" actions.
    Scaffold.of(context).showSnackBar(
        new SnackBar(content: new Text("$item dismissed")));
  },
  child: new ListTile(title: new Text('$item')),
);

3.提供“向后消除”指标

就目前来看,我们的应用程序将允许用户从列表中滑动项目,但它可能不会让他们看到他们做什么时会发生什么。 为了提供我们正在移除项目的提示,我们将在屏幕上滑动该项目时显示“划动消除”指示符。 在这种情况下,红色背景!

为此,我们将为Dismissible提供background参数。

new Dismissible(
  // Show a red background as the item is swiped away
  background: new Container(color: Colors.red),
  key: new Key(item),
  onDismissed: (direction) {
    items.removeAt(index);

    Scaffold.of(context).showSnackBar(
        new SnackBar(content: new Text("$item dismissed")));
  },
  child: new ListTile(title: new Text('$item')),
);

完整例子

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp(
    items: new List<String>.generate(20, (i) => "Item ${i + 1}"),
  ));
}

class MyApp extends StatelessWidget {
  final List<String> items;

  MyApp({Key key, @required this.items}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final title = 'Dismissing Items';

    return new MaterialApp(
      title: title,
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(title),
        ),
        body: new ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            final item = items[index];

            return new Dismissible(
              // Each Dismissible must contain a Key. Keys allow Flutter to
              // uniquely identify Widgets.
              key: new Key(item),
              // We also need to provide a function that will tell our app
              // what to do after an item has been swiped away.
              onDismissed: (direction) {
                items.removeAt(index);

                Scaffold.of(context).showSnackBar(
                    new SnackBar(content: new Text("$item dismissed")));
              },
              // Show a red background as the item is swiped away
              background: new Container(color: Colors.red),
              child: new ListTile(title: new Text('$item')),
            );
          },
        ),
      ),
    );
  }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术小黑屋

利用WebView实现网页的i18n

软件如果想在全球获得更多的用户,国际化与本地化(internationalization and localization 简称:i18n 和L10n)是非常必...

11320
来自专栏微信终端开发团队的专栏

iOS微信特殊字符保护方案

一般来说,特殊字符闪退是系统漏洞引起,只要更新系统就行。但大部分用户不愿意更新系统...

860140
来自专栏项勇

笔记78 | 解读一个闹钟代码

最近因工作需要做一个定时器,一看需求,深思极恐: 1.定时发送开关指令; 2.可设置周期循环; 这不就是一个标准的闹钟吗? 哎呀,烧脑~

9020
来自专栏武军超python专栏

2018年8月18日初识tkinter

把C盘里面的东西移动到其他盘对文件有影响吗?普通文件如音频视频没有影响,但是如果是软件的话 下载的时候会在注册表中记录打开文件的路径,如果移动到其他盘的话注册...

12620
来自专栏滕先生的博客

地图相关 CoreLocation框架介绍请求用户授权方法CLLocationManager 属性和方法CLLocation 位置对象介绍三、地理编码的实现

344120
来自专栏GIS讲堂

web中的树形结构【小结】

最近在做一个项目,是一个b/s架构的,在项目中,用到了树形结构,即如图1所示的结构。

32420
来自专栏恰童鞋骚年

操作系统核心原理-4.线程原理(下):死锁基础原理

我们都见过交通阻塞,一大堆汽车因为争夺行路权,互不相让而造成阻塞,又或者因为车辆发生故障抛锚或两辆车相撞而造成道路阻塞。在这种情况下,所有的车都停下来,谁也无...

13720
来自专栏Golang语言社区

golang 裸写一个pool池控制协程的大小

这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mi...

39280
来自专栏Golang语言社区

golang 裸写一个pool池控制协程的大小

这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mi...

39560
来自专栏有趣的Python和你

Python数据分析之贴吧的问与答读取数据库获取question列分词词云

13330

扫码关注云+社区

领取腾讯云代金券