首页 > 解决方案 > 如何检测 Flutter 中另一个小部件中启动的拖动

问题描述

对不起,如果标题看起来不对,我找不到更好的方法来构图它。我在屏幕上有一个容器网格,我希望能够在屏幕上进行选择并在屏幕上拖动。我读到了这个GestureDetector类,但它只检测到从一个小部件开始的手势,我可以做一个onPanDown, onPanUpdateonPanEnd但这只是给了我光标的坐标,我觉得这不是最优雅的方式它。(我可能错了)。

块类:

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

class Block extends StatefulWidget {
  @override
  _BlockState createState() => _BlockState();
}

class _BlockState extends State<Block> {
  Color boxColor = Colors.white;
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        if (boxColor == Colors.blueGrey[900])
          boxColor = Colors.white;
        else
          boxColor = Colors.blueGrey[900];
        setState(() {});
      },
      child: Container(
        height: 20,
        width: 20,
        decoration: BoxDecoration(
            color: boxColor,
            border: Border.all(
              color: Colors.grey,
              width: 1,
            )),
      ),
    );
  }
}


PathFinding 类:(在网格中绘制块):

import 'package:flutter/material.dart';

import 'Block.dart';

class PathFinding extends StatefulWidget {
  @override
  _PathFindingState createState() => _PathFindingState();
}

class _PathFindingState extends State<PathFinding> {
  @override
  Widget build(BuildContext context) {
    List<List<Widget>> grid = [
      ...List.generate(
          40, (index) => [...List.generate(40, (index) => Block())])
    ];
    return Scaffold(
      body: Column(
        // crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          ...grid.map((e) => Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [...e],
              ))
        ],
      ),
    );
  }
}

标签: flutter

解决方案


_PathFindingState您创建一个Block.

首先,向您添加 2 个额外的参数,Block这些参数可以在创建时传递。

class Block extends StatefulWidget {

  final void onTap;   // The function from the parent to be called
  final int id;      // An id that is unique to this Block

  Block({ this.onTap, this.id });

  @override
  _BlockState createState() => _BlockState();
}

然后,在你的 中_BlockState,每当tap检测到 a 时,调用新函数通知Block类,然后通知_PathFindingState类。

InkWell(
  onTap: () {
    if (boxColor == Colors.blueGrey[900])
      boxColor = Colors.white;
    else
      boxColor = Colors.blueGrey[900];
    setState(() {});

    widget.onTap(widget.id); // This line will call the `onTap` function that is present in the `Block`
  },

最后,在您的_PathFindingState,

class _PathFindingState extends State<PathFinding> {

  void onTap (int id) {
     // A Block with `id` = id has been tapped,
  }

  @override
  Widget build(BuildContext context) {
    List<List<Widget>> grid = [
      ...List.generate(
          40, (index) => [...List.generate(40, 
            (index) => Block(id: index, onTap: onTap) // Pass index as id and the onTap function
      )])
    ];

Gesture对于任何在 any 上检测到的任何内容都可以遵循此架构Block,您将在类中收到回调,_PathFindingState您可以对它做任何您想做的事情。


推荐阅读