有没有更好的方法在 #flutter 中检查左/右拖动?

14
有没有更好的方法来检查#flutter中的左/右拖动?我已经做过了,但有时它有效,有时则无效。
  new GestureDetector(
  onHorizontalDragEnd: (DragEndDetails details) {
      print("Drag Left - AddValue");

    setState((){
      _value++;
    });
    if (details.velocity.pixelsPerSecond.dx > -1000.0) {
      print("Drag Right - SubValue");

      setState((){
        _value--;
      });
    }
  },
  child: new Container(
    child:new Text("$_value"),
  ),
);

你能解释一下你想通过这个拖动手势实现什么吗?可能已经有一个现有的小部件可以使用。最好提供一个带有你目前所拥有的代码示例的简化版本。 - Collin Jackson
1
使用details.primaryDelta而不是details.velocity.pixelsPerSecond.axis来进行可消除操作。 - Rémi Rousselet
@CollinJackson 我更新了帖子。我认为这是缩减的代码示例。应该添加整个类/文件吗? - Ajay Kumar
@Darky 可以告诉我怎么做吗? - Ajay Kumar
8个回答

32

对于这个问题,我建议使用Dismissible小部件。它非常灵活。

video

注意:如果你不想在滑动时提供视觉反馈,可以使用Stack把一个透明的Dismissible放在另一个小部件上面。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  State createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Dismissible(
        resizeDuration: null,
        onDismissed: (DismissDirection direction) {
          setState(() {
            _counter += direction == DismissDirection.endToStart ? 1 : -1;
          });
        },
        key: new ValueKey(_counter),
        child: new Center(
          child: new Text(
            '$_counter',
            style: Theme.of(context).textTheme.display4,
          ),
        ),
      ),
    );
  }
}

正是我所需要的。谢谢! - WhiteFluffy
救命稻草!我正在尝试实现所有可解除的功能,这是一个非常复杂的解决方案。 - Alexandre Cavalcante

16

使用GestureDetector小部件及其panUpdate方法,计算移动距离。

    GestureDetector(
     onPanStart: (DragStartDetails details) {
      initial = details.globalPosition.dx;
     },
     onPanUpdate: (DragUpdateDetails details) {
      distance= details.globalPosition.dx - initial;  
     },
     onPanEnd: (DragEndDetails details) {
      initial = 0.0; 
     print(distance);
     //+ve distance signifies a drag from left to right(start to end)
     //-ve distance signifies a drag from right to left(end to start)
});

9
您可以使用onHorizontalDragUpdate
onHorizontalDragUpdate: (details){
    print(details.primaryDelta);
},

如果 details.primaryDelta 为正数,则拖动是从左到右的。 如果 details.primaryDelta 为负数,则拖动是从右到左的。

这个怎么使用并忽略对角线拖动? - Luke Irvin

4

onHorizontalDragEnd 中的 primaryVelocity 功能正常,只需检查它是否大于或小于零即可。

GestureDetector(
  onHorizontalDragEnd: (DragEndDetails drag) {
    if(drag.primaryVelocity == null) return;
    if(drag.primaryVelocity! < 0) {
      // drag from right to left
    }else{
      // drag from left to right
    }
  }
);

这是一个完美的方法,因为在horizontaldragupdate和onpanupdate事件中,您有多个命中,这使得在setstate中执行某些操作成本很高,例如它将多次重建。 - Marcel Dz

1

由于 DragUpdate 类实例返回 double 值,因此您可以这样做。(而且 Paageroute 默认提供此功能)


GestureDetector(
       onHorizontalDragUpdate: (details) {
        if(details.primaryDelta! > 1.0) {
           Navigator.pop(context);
                      }
          },
      child:Scaffold(..)

1

使用 GestureDetector,这是可以实现的。

onHorizontalDragUpdate: (DragUpdateDetails details) {
print(details.primaryDelta);}

上面的代码块告诉您拖动的值。如果是从左到右,则打印的值将为正,反之亦然。我猜您想要向前拖动或重新播放视频。在这种情况下,您需要一个if-else语句来设置条件。
onHorizontalDragUpdate: (DragUpdateDetails details) {
    print(details.primaryDelta);
    Duration currentPosition = controller.value.position;
    if (details.primaryDelta! < 0) {
      Duration targetPosition = currentPosition - const Duration(milliseconds: 200);
      controller.seekTo(targetPosition);
    } else {
      Duration targetPosition = currentPosition + const Duration(milliseconds: 200);
      controller.seekTo(targetPosition);
    }
  },

使用方法seekTo()只有在添加了video_player依赖项时才有效。点击https://pub.dev/packages/video_player下载依赖项。希望这能帮到你!

0
使用 TabBarView() 创建一个选项卡视图。 创建一个 TabController 并指定 TabBarView 子组件的长度。

-1
  onHorizontalDragEnd: (DragEndDetails details) {
    if (details.primaryVelocity! > 0) {
      // Swiped from left to right (right swipe)
      print('Swiped right');
    } else if (details.primaryVelocity! < 0) {
      // Swiped from right to left (left swipe)
      print('Swiped left');
    }
  },
  child: Container(
    // Your widget content
  ),
)```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接