dart – 如何使用颤动在按钮网格中滑动/拖动2个或更多按钮
发布时间:2020-12-14 14:56:27 所属栏目:百科 来源:网络整理
导读:我使用颤动制作了一个按钮网格,但现在我想在一个拖动中滑过2个或更多按钮,这样我所拖动的所有按钮都会被选中. 我已经检查了一些相同的问题,我被重定向到使用手势检测器,但这还不够.我需要某些属性或更好的示例代码,以便我能够完成它. 可拖动应用程序的一个示
我使用颤动制作了一个按钮网格,但现在我想在一个拖动中滑过2个或更多按钮,这样我所拖动的所有按钮都会被选中.
我已经检查了一些相同的问题,我被重定向到使用手势检测器,但这还不够.我需要某些属性或更好的示例代码,以便我能够完成它. 可拖动应用程序的一个示例是http://a5.mzstatic.com/us/r30/Purple60/v4/6f/00/35/6f0035d3-1bab-fcbb-cb13-8ab46cf3c44d/screen696x696.jpeg 解决方法
您可以手动命中测试RenderBox并提取您选择的特定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; } 然后使用Listener提取指针下找到的所有_Foo. 这是使用此原则的完整应用程序: 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: MyHomePage(title: 'Flutter Demo Home Page'),); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key,this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title),),body: 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 = HitTestResult(); 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,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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |