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

Closed
timrijckaert opened this issue Apr 18, 2019 · 48 comments
Closed

CustomScrollView + SliverAppBar + WebView #31243

timrijckaert opened this issue Apr 18, 2019 · 48 comments
Assignees
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: platform-views Embedding Android/iOS views in Flutter apps c: performance Relates to speed or footprint issues (see "perf:" labels) engine flutter/engine repository. See also e: labels. found in release: 1.20 Found to occur in 1.20 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: webview The WebView plugin P1 High-priority issues at the top of the work list package flutter/packages repository. See also p: labels. waiting for PR to land (fixed) A fix is in flight

Comments

@timrijckaert
Copy link

timrijckaert 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
Copy link

Sun3 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.

@jonahwilliams jonahwilliams added p: webview The WebView plugin c: performance Relates to speed or footprint issues (see "perf:" labels) labels Apr 18, 2019
@dcov
Copy link

dcov 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
Copy link

Sun3 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
Copy link
Contributor

Reekoooo 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
Copy link

lizhuoyuan 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
Copy link

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

@phoenixsky
Copy link

same issue + 1

@conghaonet
Copy link

same issue:NestedScrollView + SliverAppBar + WebView

@stevemoreau
Copy link

stevemoreau 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
Copy link

stevemoreau 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

@liyuqian
Copy link
Contributor

@iskakaushik, @amirh : is this also a known performance issue that will be solved once the thread-merging work is done for the WebView?

@timrijckaert
Copy link
Author

@liyuqian Is this a PR you are referencing that we can follow up upon?

@mklim mklim added a: platform-views Embedding Android/iOS views in Flutter apps engine flutter/engine repository. See also e: labels. and removed p: webview The WebView plugin labels Oct 9, 2019
@mklim
Copy link
Contributor

mklim commented Oct 9, 2019

This affects all platform views, not just webview. I expect that google_maps_flutter would also have this problem. @liyuqian I don't think this has anything to do with threading logic. We do resize the a platform view whenever we detect that the screen size has changed. The resize operation is extremely heavy because it involves detaching and creating a new virtual display of the new size to attach the platform view to. The expected behavior is to resize to make room for things like the system soft keyboard.

At a first glance I was going to say that it seems like the way we detect whether or not we should resize is broken, but I think there may be some complexity here with SliverAppBar actually effectively changing WebView's size as it moves that makes this especially difficult.

@mklim mklim added the p: webview The WebView plugin label Oct 9, 2019
@ollisal
Copy link

ollisal commented Nov 6, 2019

This other webview plugin https://pub.dev/documentation/flutter_inappbrowser/latest/ has a scroll callback that works on both iOS and Android, similarly to @reekoo Android PoC for webview_flutter.

Not sure if it works inside a NestedScrollView though to achieve the behavior that's attempted here.

Currently I have a setup where I just change the height of a top bar manually from the scroll callbacks of the InAppWebView. To solve the performance issue described here from resizing the webview, I made the webview constant size instead, with the top bar covering part of it in a Stack. This was possible because I'm showing a partially customized web page where I can add a top padding matching the covered-up part.

@mrifni
Copy link

mrifni commented Nov 11, 2019

Any updates on this ? I am having the same issue.

@sdlu1992
Copy link

I am having the same issue, Please fix the bug that webview will resizing itself and out the boundary of itself

@mathieusachet
Copy link

same problem here

@Khawlah-Mohammed
Copy link

same problem with me ... please give us any solution

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 5, 2020
@blasten
Copy link

blasten commented Sep 24, 2020

The performance issue seems to be fixed by hybrid composition, although there's a separate issue with the gesture disambiguation that I'm trying to figure out.

@blasten
Copy link

blasten commented Sep 25, 2020

@yjbanov this is the type of issues where having declarative gesture disambiguation would simplify or eliminate most of our current hacks.

@blasten blasten self-assigned this Sep 25, 2020
@blasten blasten added P2 and removed P2 Important issues not at the top of the work list labels Sep 25, 2020
@chinmaygarde chinmaygarde added this to the 1.23 - September 2020 milestone Sep 28, 2020
@blasten blasten added the waiting for PR to land (fixed) A fix is in flight label Sep 29, 2020
@blasten blasten added P1 High-priority issues at the top of the work list and removed P2 labels Sep 29, 2020
@Hixie Hixie modified the milestones: 1.23 - September 2020, Overdue Oct 6, 2020
@blasten
Copy link

blasten commented Oct 14, 2020

This has been fixed in Flutter 1.22/ WebView 1.0 - use hybrid composition in the Flutter WebView plugin.

https://github.com/flutter/plugins/tree/master/packages/webview_flutter#using-hybrid-composition

@blasten blasten closed this as completed Oct 14, 2020
@hanniiel
Copy link

hanniiel commented Oct 18, 2020

@blasten
I'm trying to implement CustomScrollView with SliverAppBar. I'm using SurfaceAndroidWebView the header scrolls with the webview that works just fine but when the header is collapsed the scroll doesn't scroll over the webview content and as a result the full webview content isn't visible.

before this update I achieved this functionality by injecting some js into the webview content to detect the scroll direction into the html content and by listening if the body top was visible then I changed the gestureRecognizers according to those events(exmaple:https://www.facebook.com/1792131602/videos/10213309766977319/ ) but It seems this update doesn't fix that or am I missing something?

best regards

@override void initState() { super.initState(); if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); } return CustomScrollView( slivers: <Widget>[ SliverAppBar( primary: false, title: const Text("Heading"), floating: true, toolbarHeight: 200, flexibleSpace: FlexibleSpaceBar(), ), SliverFillRemaining( child: WebView( initialUrl: "https://soompi.com", javascriptMode: JavascriptMode.unrestricted, ), ) ], )

using:
webview_flutter 1.0.3

Flutter 1.22.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 84f3d28 (3 days ago) • 2020-10-15 16:26:19 -0700
Engine • revision b8752bb
Tools • Dart 2.10.2

@heshaShawky
Copy link

heshaShawky commented Nov 12, 2020

Still the issue not fixed!! using Flutter 1.22.3 and flutter_webview 1.0.7 with enabling the Hybrid Composition on every layout possible:

  1. Using CustomScrollView with SliverAppBar and SliverFillRemaining
  2. or using NestedScrollView with headerSliverBuilder.

The current behavior: is scrolling only the app bar height and stop scrolling in the webpage after!!

[✓] Flutter (Channel stable, 1.22.3, on Mac OS X 10.14.5 18F132, locale en-EG)
    • Flutter version 1.22.3 at /Users/esham/Development/flutter
    • Framework revision 8874f21e79 (2 weeks ago), 2020-10-29 14:14:35 -0700
    • Engine revision a1440ca392
    • Dart version 2.10.3

 
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/esham/Library/Android/sdk
    • Platform android-30, build-tools 29.0.2
    • ANDROID_HOME = /Users/esham/Library/Android/sdk
    • ANDROID_SDK_ROOT = /Users/esham/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.3.1, Build version 11C504
    • CocoaPods version 1.8.4

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 39.0.3
    • Dart plugin version 191.8423
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.51.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.16.0

[✓] Connected device (1 available)
    • Redmi Note 8 Pro (mobile) • hev4t4bqo7hyvsnf • android-arm64 • Android 10 (API 29)

@PerLycke
Copy link

@blasten When you say fixed, more specifically what is fixed? In 1.22.4, with hybrid composition, you cannot use a CustomScrollView with a SliverAppBar and then a SliverFillRemaining with a webview. The webview just won't scroll

@heshaShawky
Copy link

This bug indeed still exists and not fixed yet!! I can't scroll on the webview itself and the sliverappbar even is glitchy, that in the latest version on flutter 1.22.4

This has been fixed in Flutter 1.22/ WebView 1.0 - use hybrid composition in the Flutter WebView plugin.

https://github.com/flutter/plugins/tree/master/packages/webview_flutter#using-hybrid-composition

@edisonywh
Copy link

Hey team, any update on this or should we create another issue to track this? I tried it out with the new Hybrid Composition awhile back and that didn't seem to work. There is a new issue at #72888 but I believe that's a different issue.

The original problem as reported in this issue is to have a SliverAppBar + a WebView, and that scrolling on the WebView should collapse the SliverAppBar. The code example and a GIF that accompanies it describes it pretty well.

@blasten
Copy link

blasten commented Feb 22, 2021

This issue is about the scroll performance while having (a) a platform view and (b) a SilverAppBar. This issue was closed because hybrid composition did solve the root cause to the issue, which is the performance of resizing the webview.

I hear that it would be useful to have an example that deals with other issues:

  1. Nested content scrolling while a platform view is present.

I'd love to hear if any of you would be interested in sending a PR to the WebView plugin example app that accomplishes exactly this. Some ideas about how to approach it:

  1. Use WebViewController#evaluateJavascript (For example) to get the height of the HTML document. e.g. document.scrollingElement.scrollHeight.
  2. Add a SizedBox as a child of SliverFillRemaining, and set the height to the value you received from the JS controller.

@emvaized
Copy link
Contributor

emvaized commented Jun 30, 2021

I guess the best solution I came up with for now is:

  1. Wrap webview with Scaffold which has empty preferred size widget as an appbar
  2. Wrap webview with Listener widget, and update animation controller value on vertical movement
  3. Change empty appbar height according to animation controller value
  4. Display separate app bar widget in a stack on top of all these, and animate it with SlideTransition according to animation controller value

Here is quick snippet for illustration: https://gist.github.com/emvaized/fa1ce586109196d7357652de2843b8ff

However, it has issues — for example app bar jumps back and forth when finger movement is very slow. Also animation is choppy sometimes.
But at least, for now this approach seems to work

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 30, 2021
@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: platform-views Embedding Android/iOS views in Flutter apps c: performance Relates to speed or footprint issues (see "perf:" labels) engine flutter/engine repository. See also e: labels. found in release: 1.20 Found to occur in 1.20 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: webview The WebView plugin P1 High-priority issues at the top of the work list package flutter/packages repository. See also p: labels. waiting for PR to land (fixed) A fix is in flight
Projects
None yet
Development

No branches or pull requests