如何使用颤动滑动/拖动按钮网格中的2个或更多按钮 [英] How to swipe/drag 2 or more buttons in a grid of buttons using flutter

查看:101
本文介绍了如何使用颤动滑动/拖动按钮网格中的2个或更多按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆