0

I am trying to recreate the MediaPicker from Instagram.

The current structure of this screen looks like this:

    return Scaffold(
      appBar: buildAppBar(context),
      body: PageView(
        physics: NeverScrollableScrollPhysics(), //disable the "normal" pageview scrolling
        onPageChanged: (index) {
          setState(() {
            pageIndex = index;
          });
        },
        controller: pageController,
        children: [
          Column(
            children: [
              Expanded(
                flex: 3,
                child: buildPreviewWidget(selection, _buildCropPreview), //this cropview has a gesture recognizer on it
              ),
              const SizedBox(height: 2),
              Expanded(
                  flex: 2,
                  child: GestureDetector(
                    onHorizontalDragStart: (details) {
                      double offset = screenWidth - details.localPosition.dx;
                      pageController.jumpTo(offset);
                    },
                    onHorizontalDragUpdate: (details) {
                      double offset = screenWidth - details.localPosition.dx;
                      pageController.jumpTo(offset);
                    },
                    child:MediaGrid( //this is the media grid
                            allowMultiSelection: multiSelectable,
                            collection: allCollection),
                  )),
            ],
          ),
          CameraScreen(),
        ],
      ),
      bottomNavigationBar: buildBottomNavigationBar(),
    );
  

The initial problem was, that whenever I dragged around in the cropview, the swiping gesture of the pageview got triggered which was not what I wanted.

So my idea was to disable the standard way of scrolling with NeverScrollableScrollPhysics() and then wrap only the MediaGrid() with a GestureRecognizer() so that I can achieve the same swipe animation with the help of the PageViews pageController.jumpTo() but only on the MediaGrid()

However my implementation seems to be bad because the pageview is stuttering like this

https://i.stack.imgur.com/Guh9k.jpg

How do I smooth the stuttering or is there an even better way to achieve this?

Christian
  • 834
  • 7
  • 18
  • 1
    in `onHorizontalDragUpdate` case try `pageController.jumpTo(pageController.offset - details.delta.dx)` - the stuttering could be related to changed "local position" – pskink Nov 14 '20 at 04:20
  • Sorry, I didn`t have had the chance to test it yet, will let you know asap. – Christian Nov 15 '20 at 00:28
  • @pskink seems like this improved the stuttering by a lot but the pageview still wants to snap to one of the screens. So when I drag it to 50% offset it moves on its own. I have the feeling this is because I call `pageController.jumpTo()` only in the `onHorizontalDragUpdate` so when I stop and only hold the screen at 50%, the event doesn`t get fired any more. Is there a way to animate as long as I touch the screen? – Christian Nov 15 '20 at 18:58
  • 1
    most likely you need `onHorizontalDragEnd` – pskink Nov 15 '20 at 20:22
  • I finally found a solution. Turns out the PageView has a `pageSnapping` property which defaults to true. I am now setting `pageSnapping` to false when `onHorizontalDragStart` and to true when `onHorizontalDragEnd` works like a charm. Thanks! – Christian Nov 16 '20 at 12:51

0 Answers0