[MUSIC PLAYING]
EMILY FORTUNA: Have you ever wanted
to display a web page in your app
without having to open the browser on your phone?
Do you have a payment flow on your website
you don't want to read implement in your app?
I'm Emily with the Flutter team.
And I'm here to tell you about the WebView plug-in which
just so conveniently helps you accomplish all those things.
Using WebView is really simple.
First add the WebView package to your pub spec.
Then in your code you can specify
an initial URL parameter for what page
you want to display first.
You can also optionally enable or disabled JavaScript
in your WebView with the JavaScript mode parameter.
By default JavaScript is disabled.
Finding out any interesting bits and controlling your WebView
is all done through the surprisingly named WebView
controller objects.
When the WebView is fully built, it returns this controller
through a callback.
The controller allows you to programmatically modify
the WebView or access properties like the current URL being
displayed.
To see how all this works in practice,
I wrote a simple Wikipedia browsing
app that allows me to bookmark pages for later.
This allows my inner perfectionist
to keep track of all the articles I
need to read in order to fulfill my lifelong quest to read
all of Wikipedia.
I believe in myself.
WebViews are just like any other widget in Flutter.
You can layer other widgets on top of them.
In my wiki browsing app, the floating action button
hovers over the WebView complete with the shadow
effect you would expect with the button.
Also when the dropdown menu from the app bar opens,
it partially covers the WebView, just
like any other widget underneath the menu.
To implement this, we want to use a completer
and a FutureBuilder.
In the class, I declare a completer instance variable,
which is like setting a placeholder for the WebView
controller.
Then in callback, we tell our program
that the WebView's been built and we now have
a working WebView controller.
We can check if we have a working WebView
controller by calling controller.isCompleted
that is completed.
Or using a FutureBuilder with the controller.future.
Using a FutureBuilder allows us to build new UI components
like the floating action button for adding favorites
only after we have a working WebView controller.
With that working WebView controller,
we can get information about the WebView,
like the current URL the WebView is displaying when we want
to save it to our favorites.
Flutter determines the priority that widgets receive gesture
events, like finger taps, through a system called
the Gesture Arena.
WebViews are no different.
But they tend to be low on the prioritization
list of getting gesture events.
This allows Flutter to control the gestures
that get sent to the WebView and which
Flutter captures for itself.
By default, a WebView view only responds to a gesture
if no other widgets have claimed it.
But you can more proactively claim gestures for your WebView
with the gesture recognizers.
An example of when you might want to use gesture recognizers
is if you have a WebView inside of a list view.
Both could respond to scrolling gestures.
But if you do nothing, the list view will get the gesture
and the WebView won't scroll.
If you watch the Boring Flutter Development Show,
this exact scenario comes up in the Hacker News reader app
that we developed.
To make the WebView scrollable inside the list view,
I capture the vertical drag gesture
with the gesture recognizer as parameter.
Gesture recognizers takes a set of all the gestures
that you want to capture.
And don't be scared by that factory object.
It's basically a glorified builder method.
Also you'll see I used darts cascade operator, which
means I return the calling object, which in this case
is the set with the new item added.
This saves me a line of code.
So I don't have to declare the set in a separate line.
The end result allows you to scroll both widgets
depending on where the touch event occurs.
If the WebView is inside a widget that
only captures gestures you don't care about,
no gesture detector is needed.
An example of that is a WebView inside of a page controller
or tab bar.
The page controller only responds
to horizontal drag gestures.
And if you just want the WebView you
to be able scroll vertically, you
don't need to add a gesture recognizer.
If you have multiple WebViews in your app,
you might need to use keys.
What are keys?
Keys are those optional parameters
in just about every widget constructor in the Flutter code
base.
If you have multiple stateful widgets of the same type that
are added, removed, or reordered,
you want to supply that key perimeter.
As it turns out, WebView is a stateful widget
since it keeps track of the current page and the browser
history.
So with a collection of WebView views
that you're adding or removing, you
can add a local key parameter.
Similarly, if you're doing something more complicated that
uses the same WebView across two views,
like with the Hero widget, you want
to use a global key so that Flutter
knows the two WebViews are actually the same
and doesn't try to re-render the second.
That was a really quick look at using keys.
But if you want to learn more about keys
it just so happens that someone who
looks an awful lot like me made a video about them
and you can check it out.
For more documentation and to learn more
about all the cool things you can do
with Flutter go to Flutter.io.
SPEAKER 1: Hey, if you thought that was
cool you should check out this, or check out that.
But don't forget to subscribe to the Flutter YouTube channel.
[MUSIC PLAYING]