Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CustomScrollView + SliverAppBar + WebView #31243

Open
timrijckaert opened this issue Apr 18, 2019 · 10 comments

Comments

@timrijckaert
Copy link

commented Apr 18, 2019

Hi,

When trying to implement a floating SliverAppBar in conjunction with a WebView Flutter drops a significant amount of frames.
It seems like the WebView is resizing itself whenever the SliverAppBar is scrolled out of view.

@override
Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: <Widget>[
      SliverAppBar(
        title: const Text("Heading"),
        floating: true,
      ),
      SliverFillRemaining(
        child: WebView(initialUrl: "http://stackoverflow.com"),
      )
    ],
  );
}

As seen on this GIF:

flutter_1

@Sun3

This comment has been minimized.

Copy link

commented Apr 18, 2019

I also have the same issue. But for me the full page article is not shown and gets cut off especially if you reload the page.

@dcov

This comment has been minimized.

Copy link

commented Apr 18, 2019

Yup that's exactly what's happening. SliverFillRemaining uses the remainingPaintExtent constraint, which is the extent that's yet to be painted on, to size its child. This changes as you scroll, which causes the AndroidView/WebView to resize as you noticed.

SliverFillViewport is what you're looking for. Although it still doesn't solve your problem of nested scrolling, which I don't think is possible as of now.

@Sun3

This comment has been minimized.

Copy link

commented Apr 19, 2019

I just tested with the SliverFillViewport and like you the end result is the same. No difference with the SliverFillRemaining. Short pages show up but longer pages they get cut off.

@Reekoooo

This comment has been minimized.

Copy link

commented Apr 19, 2019

partial solution in my repo

I will share my view here repeating what I wrote in my answer in stackoverflow may be it can help providing a solution

I can give you my view for why it is not possible to do that with the current state of the plugin ,by default the Webview only respond to drag gesture when no other views claim that gesture. On the other hand, Scrolling slivers like SliverList, which is needed to make the SliverAppBar to scroll up ,by default consumes all drag scrolling gestures -although you can disable that by providing noScrollPhysics - but once the WebView cover all the screen there is actually noway to report back to the slivers to start consume scroll again .

So the solution is to modify the WebView plugin itself to provide a callback

I already did that just for a proof of concept you can check my repo Plugins by adding a new callback to the webView
it will report back the ScrollY position which you can use to control your nested scroll

just to make it clear it works only for android api M or above right now

@lizhuoyuan

This comment has been minimized.

Copy link

commented May 17, 2019

the same issue.
I first get the html tag according to the url, then use flutter_html to load the obtained content.

var httpClient = new HttpClient();
      var request =
          await httpClient.getUrl(Uri.parse('$url'));
      var response = await request.close();
      var responseBody = await response.transform(utf8.decoder).join();
      setState(() {
        htmlData = responseBody;
      });

...

 SliverToBoxAdapter(
                      child: htmlData != null
                              ? Html(
                                  padding: EdgeInsets.only(left: 10, right: 10),
                                  data: htmlData,
                                  useRichText: true,
                                )
                              : SizedBox())
@do4Mother

This comment has been minimized.

Copy link

commented May 28, 2019

Same issues in here. I try 3 plugin webview. But can't use sliverappbar. My app cant scroll.

@phoenixsky

This comment has been minimized.

Copy link

commented Aug 13, 2019

same issue + 1

@conghaonet

This comment has been minimized.

Copy link

commented Aug 15, 2019

same issue:NestedScrollView + SliverAppBar + WebView

@stevemoreau

This comment has been minimized.

Copy link

commented Sep 5, 2019

To anyone following this issue, I'm getting into this, and will try to add some more information in a near future (hopefully, if I could understand it).

Meantime, the pending POC commit of @Reekoooo (see above) : Reekoooo/plugins@666b35f

Gesture arena of a valid use case
Standard AppBar (fixed) + Tabview with 5 tabs (so horizontal scrolling possible)
OUTPUT BEHAVIOR: The WebView allows scroll from the start to the end of the HTML

★ Opening new gesture arena.
Adding: Instance of '_CombiningGestureArenaMember'
Accepting: Instance of '_CombiningGestureArenaMember'
Adding: LongPressGestureRecognizer#cb2b8(debugOwner: GestureDetector, state: ready)
Adding: HorizontalDragGestureRecognizer#26c36(start behavior: start)
HorizontalDragGestureRecognizer#26c36(start behavior: start) calling onDown callback.
Closing with 3 members.
Eager winner: Instance of '_CombiningGestureArenaMember'
HorizontalDragGestureRecognizer#26c36(start behavior: start) calling onCancel callback.

Gesture arena of a invalid use case (partial HTML, then cut or infinite height)
Scaffold with SliverAppBar + Webview without EagerGestureRecognizer in gestureRecognizers property
OUTPUT BEHAVIOR: SliverAppBar correctly shrinked on scroll global scroll, but partial webview scroll (HTML wrapped to the height of the screen, and the WebView does not allow scroll from the start to the end of the HTML)

★ Opening new gesture arena.
Adding: Instance of '_CombiningGestureArenaMember'
Adding: LongPressGestureRecognizer#adde2(debugOwner: GestureDetector, state: ready)
Adding: VerticalDragGestureRecognizer#892bd(start behavior: start)
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onDown callback.
Closing with 3 members.
Rejecting: LongPressGestureRecognizer#adde2(debugOwner: GestureDetector, state: possible)
Accepting: VerticalDragGestureRecognizer#892bd(start behavior: start)
Self-declared winner: VerticalDragGestureRecognizer#892bd(start behavior: start)
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onStart callback.
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onUpdate callback.
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onUpdate callback.
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onUpdate callback.
VerticalDragGestureRecognizer#892bd(start behavior: start) calling onUpdate callback.

Scroll on SliverAppBar area from a screen with Webview using a EagerGestureRecognizer in gestureRecognizer property

★ Opening new gesture arena.
Adding: VerticalDragGestureRecognizer#6e279(start behavior: start)
VerticalDragGestureRecognizer#6e279(start behavior: start) calling onDown callback.
Closing with 1 member.
Default winner: VerticalDragGestureRecognizer#6e279(start behavior: start)
VerticalDragGestureRecognizer#6e279(start behavior: start) calling onStart callback.
VerticalDragGestureRecognizer#6e279(start behavior: start) calling onUpdate callback.

Scroll on the webview area from a screen with Webview using a EagerGestureRecognizer in gestureRecognizer property

★ Opening new gesture arena.
Adding: Instance of '_CombiningGestureArenaMember'
Accepting: Instance of '_CombiningGestureArenaMember'
Adding: LongPressGestureRecognizer#0061c(debugOwner: GestureDetector, state: ready)
Adding: VerticalDragGestureRecognizer#298e6(start behavior: start)
VerticalDragGestureRecognizer#298e6(start behavior: start) calling onDown callback.
Adding: VerticalDragGestureRecognizer#15566(start behavior: start)
VerticalDragGestureRecognizer#15566(start behavior: start) calling onDown callback.
Closing with 4 members.
Eager winner: Instance of '_CombiningGestureArenaMember'
VerticalDragGestureRecognizer#298e6(start behavior: start) calling onCancel callback.
VerticalDragGestureRecognizer#15566(start behavior: start) calling onCancel callback.

Scroll wherever in the screen (SliverAppBar or body) from a screen with SliverGrid

★ Opening new gesture arena.
Adding: VerticalDragGestureRecognizer#b55fd(start behavior: start)
VerticalDragGestureRecognizer#b55fd(start behavior: start) calling onDown callback.
Closing with 1 member.
Default winner: VerticalDragGestureRecognizer#b55fd(start behavior: start)
VerticalDragGestureRecognizer#b55fd(start behavior: start) calling onStart callback.
VerticalDragGestureRecognizer#b55fd(start behavior: start) calling onUpdate callback.

Next things to investigate for me VerticalDragGestureRecognizer and arena election process, and SliverList internals to check how it can properly scroll its own view and let the scroll to be handle by the VerticalDragGestureRecognizer which (I currently think) is the top gesture handler for Sliver based layouts.

Please advise if it is not the right approach.

@stevemoreau

This comment has been minimized.

Copy link

commented Sep 5, 2019

same issue:NestedScrollView + SliverAppBar + WebView

By the way, I've had NestedScrollView + SliverAppBar + WebView previously, and I recently moved to CustomScrollView + SliverAppBar + WebView because it would crash in release builds only.

Please see #30247 (comment) for more information

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants
You can’t perform that action at this time.