如何使用颤动滑动/拖动按钮网格中的2个或更多按钮 [英] How to swipe/drag 2 or more buttons in a grid of buttons using flutter
问题描述
我已经使用flutter制作了一个按钮网格,但是现在我想在一次拖动中滑动2个或更多按钮,以便选择要拖动的所有按钮。
我在同一个页面上检查了一些问题,我被重定向到使用手势检测器,但这还不够。我需要某些属性或更好的示例代码,以便能够进行处理。
可拖动应用的示例为
import'package:flutter / gestures.dart';
导入的 package:flutter / material.dart;
导入的 package:flutter / rendering.dart;
void main(){
runApp(MyApp());
}
类MyApp扩展了StatelessWidget {
@override
Widget build(BuildContext context){
return MaterialApp(
title:'Flutter演示,
主题:ThemeData(primarySwatch:Colors.blue),
主页:Grid(),
);
}
}
类Grid扩展StatefulWidget {
@override
GridState createState(){
return new GridState();
}
}
类GridState扩展了State< Grid> {
final Set< int> selectedIndexes = Set< int>();
最终键= GlobalKey();
final Set< _Foo> _trackTaped =设置< _Foo>();
_detectTapedItem(PointerEvent event){
最终的RenderBox框= key.currentContext.findRenderObject();
最终结果= BoxHitTestResult();
偏移量local = box.globalToLocal(event.position);
if(box.hitTest(result,position:local)){
for(最终在result.path中命中){
///临时变量,以便[is]允许访问[index]
最终目标= hit.target;
if(目标是_Foo&&!_trackTaped.contains(target)){
_trackTaped.add(target);
_selectIndex(target.index);
}
}
}
}
_selectIndex(int index){
setState((){
selectedIndexes.add (index);
});
}
@override
小部件构建(BuildContext上下文){
return Listener(
onPointerDown:_detectTapedItem,
onPointerMove:_detectTapedItem,
onPointerUp:_clearSelection,
子对象:GridView.builder(
键:键,
itemCount:6,
物理:NeverScrollableScrollPhysics(),
gridDelegate:SliverGridDelegateWithFixedCrossAxisCount (
crossAxisCount:3,
childAspectRatio:1.0,
crossAxisSpacing:5.0,
mainAxisSpacing:5.0,
),
itemBuilder:(上下文,索引) {
return Foo(
index:index,
child:Container(
color:selectedIndexes.contains(index)?Colors.red:Colors.blue,
) ,
),
},
),
);
}
void _clearSelection(PointerUpEvent event){
_trackTaped.clear();
setState((){
selectedIndexes.clear();
});
}
}
类Foo扩展了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;
}
}
类_Foo扩展了RenderProxyBox {
int index;
}
I have made a grid of buttons using flutter but now I want to swipe through 2 or more buttons in a single drag such that all the buttons through which I am dragging gets selected.
I have checked out some questions on the same and I was redirected to use gesture detector but that's not enough. I need certain properties or better a sample code such that I am able to work through it.
an example of the dragable app is http://a5.mzstatic.com/us/r30/Purple60/v4/6f/00/35/6f0035d3-1bab-fcbb-cb13-8ab46cf3c44d/screen696x696.jpeg
You can manually hit test RenderBox and extract a specific RenderObject of your choice.
We could for example add the following renderobject above our buttons:
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;
}
Then use a Listener to extract all _Foo
found under the pointer.
Here's a full application using this principle:
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;
}
这篇关于如何使用颤动滑动/拖动按钮网格中的2个或更多按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!