Ajay
Ajay

Reputation: 16310

Is there a better way to check Left/Right Drag in #flutter?

Is there a better way to check Left/Right Drag in #flutter. I have done it but somtime it works sometime it doesn't.

  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"),
  ),
);

Upvotes: 14

Views: 21407

Answers (8)

Adil Ayoub
Adil Ayoub

Reputation: 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
  ),
)```

Upvotes: -1

Ndukwe Victory
Ndukwe Victory

Reputation: 21

Using GestureDetector, this is achievable.

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

The above code block tells you the value of the drag. The printed value will be positive if it's from left-to-right and vice versa from right-to-left. I'm guessing you want to drag forward or replay a video. In that case, you'll need an if-else statement to set the condition.

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);
    }
  },

Using the method seekTo() will only work when video_player dependency has been added. Click https://pub.dev/packages/video_player to download the dependency. I hope this helps!

Upvotes: 1

Apoleo
Apoleo

Reputation: 2500

primaryVelocity on onHorizontalDragEnd works fine, just check for greater or lesser than zero.

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

Upvotes: 6

FEELIX
FEELIX

Reputation: 427

Since details which is a DragUdate class instance returns double , you can do.( And also Paageroute provides this by default)


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

Upvotes: 1

Xoltawn
Xoltawn

Reputation: 1885

You can use onHorizontalDragUpdate:

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

if details.primaryDelta is positive ,the drag is left to right. if details.primaryDelta is negative ,the drag is right to left

Upvotes: 10

Keezy Silencer
Keezy Silencer

Reputation: 61

Use TabBarView() Create a TabController specify the length of the widgets in TabBarView children .

Upvotes: 0

Gabriel Ezenwankwo
Gabriel Ezenwankwo

Reputation: 432

using the GestureDetector widget and its panUpdate method, calculate the distance moved.

    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)
});

Upvotes: 16

Collin Jackson
Collin Jackson

Reputation: 116838

I would just use a Dismissible widget for this. It's pretty configurable.

video

Note: If you don't want to provide visual feedback on the swipe, you could use a Stack to put a transparent Dismissible on top of another widget.

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,
          ),
        ),
      ),
    );
  }
}

Upvotes: 33

Related Questions