android_webview/docs/full-screen.md
[TOC]
Note: In this doc, WebView in code font means the WebView class that's a
subclass of View, whereas WebView in normal font means the WebView product in
general.
You can see an example of how to support WebView full screen in your application
in the WebView
shell.
The app overrides WebChromeClient#onShowCustomView to do something like:
@Override
public void onShowCustomView(
View view, WebChromeClient.CustomViewCallback callback) {
if (mFullscreenView != null) {
((ViewGroup) mFullscreenView.getParent()).removeView(mFullscreenView);
}
mFullscreenView = view;
requireActivity()
.getWindow()
.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requireActivity()
.getWindow()
.addContentView(
mFullscreenView,
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER));
}
Essentially, when the web contents requests to go full screen, WebView creates a
View (a
FullScreenView)
and hands it to the app to attach to the window. Usually the existing WebView
remains attached to the window, but obscured by the full screen View.
When the user exits full screen through the web contents, or through invoking
the callback, onHideCustomView is called, where the app should remove
mFullscreenView from the window.
@Override
public void onHideCustomView() {
if (mFullscreenView == null) {
return;
}
requireActivity()
.getWindow()
.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
((ViewGroup) mFullscreenView.getParent()).removeView(mFullscreenView);
mFullscreenView = null;
}
Of all the apps that override WebChromeClient, ~85% of them override
onShowCustomView. If an app does not, WebView reports to the web page that
fullscreen mode is not supported.
Broadly speaking, the API on the WebView class can be split into two parts -
stuff to do with the web content (eg, loadUrl, goBack) and stuff to do with
integrating into the View hierarchy (eg, onDraw, requestFocus). Inside
AwContents, the View responsibilities are collected in the AwViewMethods
interface, so we end up with the following:
When full screen is triggered, the web page starts being drawn through
FullScreenView
instead, so all the integration with the View hierarchy must come from there
instead. At the same time, we don’t want AwViewMethods being triggered by both
the FullScreenView and the WebView, so we attach the WebView to a
NullAwViewMethods,
where everything is effectively a no-op.
This means that a call to WebView#loadUrl will trigger a page load, but it
will still be drawn through the FullScreenView.
The main thing you need to keep in mind is that AwContents can be moved
between Views (between WebView and FullScreenView).
Currently, the code is a little confused, with
AwContents#onAttachedToWindow
tying features (such as the window coverage tracker, the display cutout
controller, the frame metrics listener) to the WebView that should be moved
over to the FullScreenView when it’s used, but aren’t. These should get fixed
soon.