【问题标题】:Flutter GestureDetector, onTap gets triggered automatically, how to?Flutter GestureDetector,onTap自动触发,如何?
【发布时间】:2018-10-07 13:09:51
【问题描述】:

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

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

问题在于 GestureDetector -> onTap 方法会在所有 cel 的应用刷新时触发。

在下面的示例中,_changeCell 方法会立即为所有 cel 触发,onTap 不起作用。

有什么想法吗?

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,
            ),
          ),
        );
      }),
    );
  }
}

【问题讨论】:

    标签: flutter setstate


    【解决方案1】:

    只需将 onTap: _changeCell(index) 更改为 onTap: () =&gt; _changeCell(index) 即可。 _changeCell(index) 这将返回 null 并且您将 null 设置为 onTap 并调用相同的函数。

    以下代码用于此

    我玩了一下。

        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,
            ),
          ),
        );
      }
    }
    

    希望对你有帮助:)

    【讨论】:

    • 我改变了调用_changeCell 方法的方式.. 但颜色和文字似乎没有改变
    • 我只想在我点击的单元格上更改颜色和文本
    • 帮助,当我在onTap 属性中调用myMethod 时,我收到only static members can be accessed in initializers 错误
    • 如何重置,框的其余部分为默认值?
    • @AkhilGite 只是设置了初始索引。
    【解决方案2】:

    您的代码在这一行有问题:

    onTap: _changeCell(index),
    

    基本上,您不是将 onTap 设置为方法,而是直接调用该方法并将 onTap 设置为该调用的结果(null)。每次构建小部件时,它都会调用该函数。

    你应该做的是:

    onTap: () => _changeCell(index)
    

    【讨论】:

      【解决方案3】:

      为寻求快速解决方案的人提供的 TLDR 答案。

      更改:

      onTap: () => myMethod,
      

      至此:

       onTap: (){ myMethod();},
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-24
        • 2020-05-04
        • 1970-01-01
        • 2022-10-16
        • 1970-01-01
        • 1970-01-01
        • 2021-11-23
        相关资源
        最近更新 更多