我已经用Ffltter制作了一个按钮网格,但是现在我想要在一次拖动中滑动2个或更多按钮,这样我拖动的所有按钮都会被选中.

我在上面查了一些问题,我被重定向到使用手势检测器,但这还不够.我需要某些属性或更好的示例代码,以便我能够通过它工作.

可拖放应用程序的一个示例是http://a5.mzstatic.com/us/r30/Purple60/v4/6f/00/35/6f0035d3-1bab-fcbb-cb13-8ab46cf3c44d/screen696x696.jpeg

推荐答案

您可以手动点击test RenderBox并提取您 Select 的特定RenderObject.

例如,我们可以在按钮上方添加以下renderobject:

class Foo extends SingleChildRenderObjectWidget {
  final int index;

  Foo({Widget child, this.index, Key key}) : super(child: child, key: key);

  @override
  RenderObject createRenderObject(BuildContext context) {
    return _Foo()..index = index;
  }

  @override
  void updateRenderObject(BuildContext context, _Foo renderObject) {
    renderObject..index = index;
  }
}

class _Foo extends RenderProxyBox {
  int index;
}

然后使用侦听器提取指针下找到的所有_Foo个.

以下是使用此原则的完整应用程序:

enter image description here

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Grid(),
    );
  }
}

class Grid extends StatefulWidget {
  @override
  GridState createState() {
    return new GridState();
  }
}

class GridState extends State<Grid> {
  final Set<int> selectedIndexes = Set<int>();
  final key = GlobalKey();
  final Set<_Foo> _trackTaped = Set<_Foo>();

  _detectTapedItem(PointerEvent event) {
    final RenderBox box = key.currentContext.findRenderObject();
    final result = BoxHitTestResult();
    Offset local = box.globalToLocal(event.position);
    if (box.hitTest(result, position: local)) {
      for (final hit in result.path) {
        /// temporary variable so that the [is] allows access of [index]
        final target = hit.target;
        if (target is _Foo && !_trackTaped.contains(target)) {
          _trackTaped.add(target);
          _selectIndex(target.index);
        }
      }
    }
  }

  _selectIndex(int index) {
    setState(() {
      selectedIndexes.add(index);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: _detectTapedItem,
      onPointerMove: _detectTapedItem,
      onPointerUp: _clearSelection,
      child: GridView.builder(
        key: key,
        itemCount: 6,
        physics: NeverScrollableScrollPhysics(),
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          childAspectRatio: 1.0,
          crossAxisSpacing: 5.0,
          mainAxisSpacing: 5.0,
        ),
        itemBuilder: (context, index) {
          return Foo(
            index: index,
            child: Container(
              color: selectedIndexes.contains(index) ? Colors.red : Colors.blue,
            ),
          );
        },
      ),
    );
  }

  void _clearSelection(PointerUpEvent event) {
    _trackTaped.clear();
    setState(() {
      selectedIndexes.clear();
    });
  }
}

class Foo extends SingleChildRenderObjectWidget {
  final int index;

  Foo({Widget child, this.index, Key key}) : super(child: child, key: key);

  @override
  _Foo createRenderObject(BuildContext context) {
    return _Foo()..index = index;
  }

  @override
  void updateRenderObject(BuildContext context, _Foo renderObject) {
    renderObject..index = index;
  }
}

class _Foo extends RenderProxyBox {
  int index;
}

Dart相关问答推荐

是否从 Dart 中删除了interface关键字?

Flutter 中带有导航栏的永久视图

Dart 包 - 如何隐藏内部方法和类?

在dart polymer重复模板中获取索引

通常由 TextField 创建的 InputDecorator 不能具有无限宽度

Flitter中的谷歌 map 没有出现

如何组织混合HTTP服务器+web客户端Dart元素文件?

不推荐使用AnteStorStateofType,请改用findAncestorStateOfType

如何从 ExpansionTile 的标题中删除默认填充

如何更改手机屏幕上的Flutter应用程序名称显示?

如何从 JavaScript 调用 Dart 函数

何时使用polymer点击或点击?

为什么不推荐使用 context2d.backingStorePixelRatio?

Dart,对泛型的限制?

如何在 Dart 中读取控制台输入/标准输入?

如何在 Dart 中使用 Switch Case 语句

Dart 字符串比较器

在 Dart 中将类型化函数作为参数传递

如何在 Dart 中将 double 转换为 int?

const 构造函数实际上是如何工作的?