Reputation: 161
I am trying to create a screen that has a WebView (from webview_flutter: ^0.3.5+3) and an AppBar
that I want to scroll offscreen on user scroll.
I stumbled upon this guide and tried implementing something similar, but no dice.
Is there a way to use a WebView
in a CustomScrollView
with Slivers
or is this not supported yet?
I can get the scrolling app bar to work if I create regular Widgets in my SliverChildListDelegate
(I tried Row
, Text
, Container
etc.), but had no luck with a WebView
.
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverList(
delegate: SliverChildListDelegate([
Container(
child: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
),
)
]
),
)
],
)
);
}
Any pointers/suggestions/RTFMs welcome.
EDIT BOUNTY
The solution provided by jordan-davies works but is very choppy.
Whenever the SliverAppBar
is scrolled away the WebView
tries to resize itself to fill the remaining viewport. This makes for a very choppy/slow experience.
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverFillRemaining(
child: WebView(initialUrl: "http://stackoverflow.com"),
)
],
);
}
Upvotes: 16
Views: 8033
Reputation: 66
I think there is a scrolling conflict between the CustomScrollView and the WebView. To resolve this, you can disable scrolling in the CustomScrollView by using NeverScrollableScrollPhysics.
@override
Widget build(BuildContext context) {
return CustomScrollView(
physics: NeverScrollableScrollPhysics(), // Disables scrolling in CustomScrollView
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverFillRemaining(
child: WebView(initialUrl: "http://stackoverflow.com"),
),
],
);
}
Upvotes: 0
Reputation: 1
After many trial and errors I found a way to fix a similar issue by using gestureRecognizers
like so :
@override
Widget build(BuildContext context) {
return SliverFillRemaining(
child: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
gestureRecognizers: {
Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer(),
),
},
),
);
}
Upvotes: 0
Reputation: 6861
I actually wanted to make a comment but it is too long to fit
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 for drag gestures , hope that flutter team will implement this feature soon.
Upvotes: 1
Reputation: 10861
I think you should take a look at using a SliverFillRemaining
or SliverFillViewport
instead of SliverList
. Heres an example using SliverFillRemaining
https://docs.flutter.io/flutter/widgets/SliverFillRemaining-class.html
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverFillRemaining(
child: WebView(initialUrl: "http://stackoverflow.com"),
)
],
);
}
Upvotes: 0