karvulf / flutter-reorderable-grid-view

BSD 3-Clause "New" or "Revised" License
155 stars 22 forks source link

[Feature] Add support for InteractiveViewer #74

Open tsquillario opened 1 year ago

tsquillario commented 1 year ago

The idea is that the GridView of cards is too large for the screen and the user can pan/zoom around. The InteractiveViewer widget provides this capability.

  1. Drag and drop offset is not correct after you pan the screen
  2. Card size isn't adjusted after you zoom
  3. Scroll while dragging feature doesn't work.

https://github.com/tsquillario/flutter-reorderable-grid-view-example1/tree/interactiveviewer

karvulf commented 1 year ago

Hi @tsquillario Thanks for opening the issue. I never used it that way that I had 2 SingleChildScrollView. I have to check if that is even possible with my code. I think currently I just use the scroll position of one of your SingleChildScrollView which means that the drag and drop would be buggy in one scroll direction if you have two. If I can get access to both, then I think it should be possible to drag and drop in both scrolling directions. I will check that this week, possibly on the week-end.

tsquillario commented 1 year ago

Doing some more testing. It is definitely related to the scroll position. When the GridView is in the top left position when it first loads drag and drop works as expected. It's when you scroll it the drag is offset by the amount you scroll.

I was also playing around with InteractiveViewer with scaleEnabled which disables the zoom. This would achieve the same result. whichever is easier to implement would work.

InteractiveViewer(
    boundaryMargin: const EdgeInsets.all(20),
    constrained: false,
    scaleEnabled: false,
    child: Column(children: [
      Padding(
          padding: EdgeInsets.symmetric(
              vertical: 0, horizontal: 5),
          child: SizedBox(
              width: 800,
              height: 800,
              child: GridView(
                key: _gridViewKey,
                primary: true,
                shrinkWrap: false,
                physics: const NeverScrollableScrollPhysics(),
                gridDelegate:
                    const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 8,
                  mainAxisSpacing: 0,
                  crossAxisSpacing: 0,
                  childAspectRatio: 1,
                ),
                children: children,
              )))
    ]))
tsquillario commented 1 year ago

Found another potential issue. I added a zoom control to resize the GridView. When you zoom in or out the size of the card changes but the drag preview doesn't.

Create a separate branch for InteractiveViewer I think that may be the better widget to use for this.

https://github.com/tsquillario/flutter-reorderable-grid-view-example1/tree/interactiveviewer

untitled2

karvulf commented 1 year ago

Yeah the main issue is that I always expected that you return a GridView directly and not any other widgets like InteractiveViewer. So that's the reason why it does not work well with a zoom because at the beginning I save the size of every item but when the size changes, I don't get any notification about that. I think that might be a feature in the future like your other request having a two dimensional scrolling. I think this evening I have some time to think about a solution and if it's easy to implement or not. But thank you already for testing these things, that helps me a lot! :) @tsquillario

tsquillario commented 1 year ago

Found this, seems related https://github.com/flutter/flutter/pull/73143

Also https://github.com/flutter/flutter/issues/73208

Video on InteractiveViewer https://youtu.be/ChFa0A72Uto

Updated test repo to use transformationController to control the zoom. There is an onInteractionEnd that could be used to feedback the position and scale level. https://github.com/tsquillario/flutter-reorderable-grid-view-example1/tree/interactiveviewer

tsquillario commented 1 year ago

Realizing even if you can figure out how to get InteractiveViewer working it's probably going to be a lot of work and will take a while. I need a short term solution so I decided to hold off on InteractiveViewer. I can get away with vertical scrolling only (for use when in landscape orientation) and leave the GridView to fit to the screen width. I can readjust the fontSize accordingly when flipping from portrait to landscape.

I'm experiencing 2 issues here: 1. When you scroll the GridView down in landscape orientation on a phone emulator the drag and drop is incorrectly offset. Similar to the original issue.

  1. The enableScrollingWhileDragging isn't working

Maybe I'm doing something wrong here....

Updated the master branch to reproduce the issue. https://github.com/tsquillario/flutter-reorderable-grid-view-example1

untitled3

tsquillario commented 1 year ago
  1. Was fixed by adding a ScrollController.
  2. Still an issue
tsquillario commented 1 year ago

Update. When I remove ConstrainedBox enableScrollingWhileDragging works but the drag offset is off

karvulf commented 1 year ago

Thank you for testing so much, tomorrow I will also investigate that and come back if I have some news for you :) @tsquillario

karvulf commented 1 year ago

So one issue was that the widget you return doesn't have a key because usually I would expect a GridView with a key. If you add the key to the Padding, the scrolling works but there seems to be a bug because the position changes are incorrectly. @tsquillario

karvulf commented 1 year ago

Update: I fixed your issue, I did something wrong using the scrolling values and always calculated the positions in both directions with the same values. That leaded to wrong values in one direction. I faced another issue, that items aren't correctly visible, so I will try to fix that too and will release an update after that. @tsquillario

karvulf commented 1 year ago

I released version 5.0.0-dev.5 that should fix your issue. Make sure that the child, you return in builder has a key that you declared at the top. @tsquillario

tsquillario commented 1 year ago

Sweet, works great now! I'll leave this open and update the issue to be specific to InteractiveViewer support. That would be a nice feature but low on the priority list. None of the other reordable gridview packages support it either.

tsquillario commented 1 year ago

Well, we're so close! While implementing the changes in my app I have the GridView inside a Column as a child of a SingleChildScrollView. This breaks the drag auto scroll.

Updated the example https://github.com/tsquillario/flutter-reorderable-grid-view-example1

karvulf commented 1 year ago

Ill check that on Sunday 👍 @tsquillario