Flutter GestureDetector,onTap自动触发,怎么办? [英] Flutter GestureDetector, onTap gets triggered automatically, how to?

查看:743
本文介绍了Flutter GestureDetector,onTap自动触发,怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有状态的小部件,其中有一个简单的网格,每个网格单元中都有一个容器.

I have a stateful widget that has a simple grid and each grid cell has a container inside it.

我想单击一个单元格/容器并更改其内容.

I would like to click on a cell / container and have its content changed.

问题在于,对于所有cel,应用刷新时都会触发GestureDetector-> onTap方法.

The problem is that the GestureDetector -> onTap method gets triggered on app refresh for all cels.

在下面的示例中,_changeCell方法立即针对所有cel触发,并且onTap不起作用.

In the example below, the _changeCell method gets triggered instantly for all cels and onTap doesn't work.

有什么想法吗?

import 'package:flutter/material.dart';

class GridWidget extends StatefulWidget {
  @override
  _GridWidgetState createState() => new _GridWidgetState();
}

class _GridWidgetState extends State<GridWidget> {
  @override
  Widget build(BuildContext context) {

    Color cellColor = Colors.white;
    Text cellText = new Text('');

    // when a cell is tapped, change the color and text
    _changeCell(index) {
      setState(() {
        cellColor = Colors.lightBlue;
        cellText = new Text('clicked');
      });
      print("Container clicked " + index.toString());
    }

    // create a 5 by 5 grid 
    return new GridView.count(
      crossAxisCount: 5,
      children: new List.generate(5, (index) {
        return new GestureDetector(
          onTap: _changeCell(index),
          child: new Container(
            width: double.infinity,
            height: double.infinity,
            decoration: new BoxDecoration(
              color: cellColor,
            ),
            child: new Center(
              child: cellText,
            ),
          ),
        );
      }),
    );
  }
}

推荐答案

只需将onTap: _changeCell(index)更改为onTap: () => _changeCell(index)即可. _changeCell(index)会返回 null ,您将null设置为onTap并调用相同的函数.

just change onTap: _changeCell(index) to onTap: () => _changeCell(index) . _changeCell(index) this returns null and you setting null to onTap and calling the same function .

以下代码是为此

我玩了一些.

    import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new DemoScreen(),
  ));
}

class DemoScreen extends StatefulWidget {
  @override
  _DemoScreenState createState() => new _DemoScreenState();
}

class _DemoScreenState extends State<DemoScreen> {
  Color cellColor = Colors.white;

  Text _getText(index) {
    Text text;
    switch (index) {
      case 0:
        text = new Text('lightBlue');
        break;
      case 1:
        text = new Text('red');
        break;
      case 2:
        text = new Text('green');
        break;
      case 3:
        text = new Text('yellow');
        break;
      case 4:
        text = new Text('orange');
        break;
      default:
        text = new Text('brown');
        break;
    }

    return text;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Demo App"),
      ),
      body: new GridView.count(
        crossAxisCount: 5,
        children: new List.generate(5, (index) {
          return new MyWidget(
            index: index,
            color: cellColor,
            text: _getText(index),
          );
        }),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  final Color color;
  final Text text;
  final int index;

  MyWidget({this.color, this.text, this.index});

  @override
  _MyWidgetState createState() => new _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Color cellColor = Colors.white;
  Text cellText = new Text('white');

  @override
  void initState() {
    super.initState();
    cellColor = widget.color;
    cellText = widget.text;
  }

  _changeCell(index) {
    setState(() {
      switch (index) {
        case 0:
          cellColor = Colors.lightBlue;
          cellText = new Text('lightBlue');
          break;
        case 1:
          cellColor = Colors.red;
          cellText = new Text('red');
          break;
        case 2:
          cellColor = Colors.green;
          cellText = new Text('green');
          break;
        case 3:
          cellColor = Colors.yellow;
          cellText = new Text('yellow');
          break;
        case 4:
          cellColor = Colors.orange;
          cellText = new Text('orange');
          break;
        default:
          cellColor = Colors.brown;
          cellText = new Text('brown');
          break;
      }
    });
    print("Container clicked " + index.toString());
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: () => _changeCell(widget.index),
      child: new Container(
        margin: new EdgeInsets.symmetric(horizontal: 1.0),
        width: double.infinity,
        height: double.infinity,
        decoration: new BoxDecoration(
          color: cellColor,
        ),
        child: new Center(
          child: cellText,
        ),
      ),
    );
  }
}

希望它会有所帮助:)

这篇关于Flutter GestureDetector,onTap自动触发,怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆