How to lock page scrolling when moving a slider

3,439

Solution 1

So after a days work I've cracked two birds with one stone and found a solution which solves both this and my previous post here

Just wanted to leave an answer incase anyone else comes across this and has similar problems.

I basically used the RawGestureDetector below:

class _MyGestureDetector extends OneSequenceGestureRecognizer {
  final Function onHorizontalDragDown;
  final Function onHorizontalDragUpdate;
  final Function onHorizontalDragUp;

  _SingleDeviceGestureDetector({
    @required this.onHorizontalDragDown,
    @required this.onHorizontalDragUpdate,
    @required this.onHorizontalDragUp,
  });

  @override
  void addPointer(PointerEvent event) {
    //Returns true or false depending on whether there
    //is a pointer on screen already
    if (onHorizontalDragDown(event)) {
      startTrackingPointer(event.pointer);
      resolve(GestureDisposition.accepted);
    } else {
      stopTrackingPointer(event.pointer);
    }
  }

  @override
  void handleEvent(PointerEvent event) {
    //If the pointer is being dragged
    if (event is PointerMoveEvent) {
      //Sends the position of the drag
      onHorizontalDragUpdate(event.position);
    }
    //If the pointer is being lifted
    else if (event is PointerUpEvent) {
      onHorizontalDragUp(event);
      stopTrackingPointer(event.pointer);
    }
  }

  @override
  String get debugDescription => 'singlePointerDrag';

  @override
  void didStopTrackingLastPointer(int pointer) {}
}

Solution 2

good answer from 'saxophonix',but you need to change code

From :

startTrackingPointer(event.pointer);

To :

startTrackingPointer(event.pointer, event.transform);

to fix the bug which did not calculate the offset in widget

Share:
3,439
eFlat
Author by

eFlat

Updated on December 14, 2022

Comments

  • eFlat
    eFlat over 1 year

    In Flutter, I have an app with a custom Slider inside a custom ListView widget. The only problem is that when you move the slider handle (left to right), the page will still scroll (up and down) due to the ListView, whereas I would need the page to lock in place until the user stops moving the slider.

    I started off by having a look at the material app slider code but couldn't find anything that would help. I've also played around with the slider and it has the effect that I am trying to achieve, which tells me the problem lies in the my custom slider. *

    I am using a Listener in the slider widget to detect gestures so I would assume that I am missing a few lines in there somewhere? Any help would be appreciated, cheers.

    Update: * I have also tried changing the behaviour of the listener but that hasn't seemed to solve the problem.

    Here is the slider within the ListView - Note: the slider can have multiple handles (hence why it's custom) but in this case just showing a single to avoid confusion.

    @override
      Widget build(BuildContext context) {
        return ListView(children: <Widget>[
        Center(
         child: StagedSlider.single(
          value: point,
          //A function which changes the handle value
          onChanged: setHandleInfo,
         ),
        ),
    ...
    

    Here is the listener inside the slider:

    return Listener(
          behavior: HitTestBehavior.translucent,
          //The following return functions to calculate handle
          //position/progress...
          onPointerDown: someFunction(),
          onPointerMove: someFunction(),
          onPointerUp: someFunction(),
          //Child is a stack of handles/thumbs calculated higher up
          child: handles,
          ),
        );
    

    Just as an example, if you were to move the slider handle in a vertical-upwards motion, the handle would move along the horizontal axis and the whole page would move down vertically. On the other handle, the Material App Slider does not do this and in this case would only move the handle.

    Update2: So a quick fix for this would be to just use a Gesture Detector instead of a Listener. I tried it out and all the issues seemed to have been fixed. However, due to another unrelated issue I was having earlier if someone had a solution using the Listener that would be great.

    • Pablo Barrera
      Pablo Barrera over 4 years
      Could you post some code to see how the Slider interacts with the ListView?
    • eFlat
      eFlat over 4 years
      Apologies, I've added in some of the basic code.
  • eFlat
    eFlat over 4 years
    Thanks for the response, I do get where you're coming from though I'm not quite sure on how I would implement this. I'll also update the question to try and clarify things up.