Use Child Drag Behavior in PageView

Viewed 20

I would like to use a Slider in a PageView without the page transitioning when dragged.

I have tried wrapping the Slider in a GestureDetector, and using HorizontalDragStart and HorizontalDragEnd to change the PageViews physics with no luck. Code below:

  bool pageViewDisabled = false;
  late PageView pageView;

  sliderChanged(double value) {
    setState(() {
      sliderValue = value;
    });
  }

  disablePageView() {
    setState(() {
      pageViewDisabled = true;
    });
  }

  enablePageView() {
    setState(() {
      pageViewDisabled = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    pageView = PageView(
      physics: pageViewDisabled ? NeverScrollableScrollPhysics() : AlwaysScrollableScrollPhysics(),
      controller: PageController(),
      children: <Widget>[
        Center(child: Text('Page One')),
        GestureDetector(
          onHorizontalDragStart: disablePageView(),
          onHorizontalDragEnd: enablePageView(),
          child: Slider(
            value: sliderValue,
            onChanged: sliderChanged,
          ),
        ),
        Center(child: Text('Page Three')),
      ],
    );
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: pageView
    );
  }

Desired Slider Behaviour

Actual Slider Behaviour

2 Answers

maybe this can solve your problem I think it will happen if you do these operations through the controller object


late PageController controller;
void initState() {
    super.initState();
    controller = PageController();

  }

Looking at your use case, it seems to me that the problem is in the layout of the widget in the pageview and it is the only widget inside the page, try encapsulating it in another widget, such as column or list.

Scaffold(
  appBar: AppBar(title: const Text('DEMO')),
  body: PageView(
    controller: pageController,
    children: [
      const Center(child: Text('Page One')),
      Column(
        mainAxisSize: MainAxisSize.max,
        children: [
          Slider(
            value: sliderValue,
            onChanged: (value){
              setState(() {
                sliderValue = value;
              });
            },
          ),
        ],
      ),
      ListView(
        children: [
          Slider(
            value: sliderValue,
            onChanged: (value){
              setState(() {
                sliderValue = value;
              });
            },
          ),
        ],
      ),
    ],
  ),
);

enter image description here

Related