因为所谓的敏捷开发,现在很多 App 都内嵌了网页,以此来满足快速迭代以及跨平台的需求,甚至大型 App 如『QQ』、『淘宝』、『支付宝』等等,除了最基础的功能外,大多数都交由网页来实现。

我们知道,在 Android 中想要加载网页,只需要嵌入 WebView 控件就可以了,但通常情况下,我们不会使 WebView 占满屏幕的整个空间,顶部还会加入一个 Toolbar 来与用户交互。比如,我们可以打开「开发者选项」中的「显示布局边界」功能来看看『QQ』的「会员中心」页面:

QQ 会员中心页面

Toolbar 在这里一般有两个作用,一是提供操作功能,比如左侧的回退按钮,以及右边的 Menu 菜单,可以在不占用界面太多空间的情况下为用户提供交互;二是展示 Title,让用户知晓当前页面的意义。

但是平时我们使用 Title 时大多数情况都是根据原生页面设置,即为每一个 ActivityFragment 设定一个 Title,即我们在开发中知道每一个页面对应的 Title 是什么。

而如果使用 WebView 的话,就存在了不确定性,因为 WebView 所加载的页面往往不是由我们自己开发,而且跳转也会更加随意,所以我们不能够直接确定 Title

不过不要慌,如果你写过 HTML 你就知道,HTML 中也是有一个叫 <title> 的标签的:

<html>
  <head>
    <title>Title</title>
  </head>
  ...
</html>

如果你没有写过 HTML,那么你打开网站的时候也会在浏览器的标签中见到相应的名字:

浏览器标签中的 Title

我们打开网页的源码,就可以看到定义这个名字的地方:

网页源码中的 Title

既然如此,我们就可以通过 WebView 获取所加载的网页设置的 <title> 并将其配置到 Toolbar 中去。

方法一:在 WebViewClient 内获取

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        String title = view.getTitle();
        if (!TextUtils.isEmpty(title)) {
            toolbar.setTitle(title);
        }
    }
});

我们知道 onPageFinished() 在网页加载完成的时候会调用,该方法中有两个参数,其中一个就是 WebView 实例,通过它的 getTitle() 方法即可获取到网页的 <title>,把它设置到 ToolbarTitle 中即可。

当然你也发现了其他几个接口如 shouldOverrideUrlLoading() 中也有 WebView 参数,那能否在其中使用上面的方式获取呢?理论上是可以的,但不建议,shouldOverrideUrlLoading() 的主要作用是给 WebView 提供时机,让其选择是否对 Url 进行拦截,如果拦截了就不加载对应的 Url 了,因此我们应该在网页加载完成后再获取。

方法二:在 WebChromeClient 内获取:

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onReceivedTitle(WebView view, String title) {
        if (!TextUtils.isEmpty(title)) {
            toolbar.setTitle(title);
        }
    }
});

WebChromeClient 内则提供了更加直截了当的接口 onReceivedTitle(),从函数命名就可以知道这个方法就是专门为了获取 <title> 而生的,直接设置到 Toolbar 中就可以。