Android开发Android开发Android技术知识

Android WebView 完全使用手册

2018-12-25  本文已影响6人  小村医

一、简介

为了方便开发者实现在app内展示网页并与网页交互的需求,Android SDK提供了WebView组件。它继承自AbsoluteLayout,展示网页的同时,也可以在其中放入其他的子View。现如今,Hybrid应用似乎占据的APP的主流类型,那么关于WebView的使用就变得越发的重要。从Android 4.4(KitKat)开始,原本基于WebKit的WebView开始基于Chromium内核,这一改动大大提升了WebView组件的性能以及对HTML5,CSS3,JavaScript的支持。

二、相关类及API

1、WebView

基本:

加载网页:

导航:

JavaScript:

其他:

2、WebSettings

3、WebViewClient

从名字上不难理解,这个类就像WebView的委托人一样,是帮助WebView处理各种通知和请求事件的

一些关键方法调用流程:

4、WebChromeClient

5、CookieManager

三、特殊场景介绍

1、视口(viewport)

视口是一个为网页提供绘图区域的矩形。
你可以指定数个视口属性,比如尺寸和初始缩放系数(initial scale)。其中最重要的是视口宽度,它定义了网页水平方向的可用像素总数(可用的CSS像素数)。
多数 Android 上的网页浏览器(包括 Chrome)设置默认视口为一个大尺寸(被称为"wide viewport mode",宽约 980px)。
也有许多浏览器默认会尽可能缩小以显示完整的视口宽度(被称为"overview mode")

// 是否支持viewport属性,默认值 false
// 页面通过`<meta name="viewport" ... />`自适应手机屏幕
// 当值为true且viewport标签不存在或未指定宽度时使用 wide viewport mode
settings.setUseWideViewPort(true);
// 是否使用overview mode加载页面,默认值 false
// 当页面宽度大于WebView宽度时,缩小使页面宽度等于WebView宽度
settings.setLoadWithOverviewMode(true);

viewport 语法

<meta name="viewport"
      content="
          height = [pixel_value | "device-height"] ,
          width = [pixel_value | "device-width"] ,
          initial-scale = float_value ,
          minimum-scale = float_value ,
          maximum-scale = float_value ,
          user-scalable = ["yes" | "no"]
          " />

通过WebView设置初始缩放(initial-scale)

// 设置初始缩放百分比
// 0表示依赖于setUseWideViewPort和setLoadWithOverviewMode
// 100表示不缩放
web.setInitialScale(0)

2、长按保存图片或者拨打电话

一般浏览器都有长按保存图片或者拨打图片的功能,实现这个功能和WebView.HitTestResult这个类有关,这个类会将你触摸网页的地方的类型和其他信息反馈给你。

WebView.HitTestResult的常用方法:

  1. 给WebView设置长按监听事件;
  2. 获取WebView长按时的WebView.HitTestResult的事件类型,如果是图片,则做处理。
webView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
        WebView.HitTestResult result = ((WebView) view).getHitTestResult();
        if(result != null){
            switch (result.getType()){
                case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
                    String imgUrl = result.getExtra();
                    ...
                    return true;
                ...
            }
        }
        return false;
    }
});

3、与Javascript交互

启用Javascript

// 是否支持Javascript,默认值false
settings.setJavaScriptEnabled(true); 

注入对象到Javascript

// 注入对象'jsobj',在网页中通过`jsobj.say(...)`调用
web.addJavascriptInterface(new JSObject(), "jsobj") 

在API17后支持白名单,只有添加了@JavascriptInterface注解的方法才会注入JS

public class JSObject {
    @JavascriptInterface
    public void say(String words) {
      // todo
    }
}

移除已注入Javascript的对象

web.removeJavascriptInterface("jsobj")

执行JS表达式

// 弹出提示框
web.loadUrl("javascript:alert('hello')");
// 调用注入的jsobj.say方法
web.loadUrl("javascript:jsobj.say('hello')"); 

在API19后可异步执行JS表达式,并通过回调返回值

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    vWeb.evaluateJavascript("111+222", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // value => "333"
        }
    });
}

4、全屏(Fullscreen)

  1. manifest
    自己处理屏幕尺寸方向的变化(切换屏幕方向时不重建activity)
    WebView播放视频需要开启硬件加速
<activity
    android:name=".WebViewActivity"
    android:configChanges="orientation|screenSize"
    android:hardwareAccelerated="true"
    android:screenOrientation="portrait" />
  1. 处理全屏回调
CustomViewCallback mCallback;
View vCustom;

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    setFullscreen(true);
    vCustom = view;
    mCallback = callback;
    if (vCustom != null) {
        ViewGroup parent = (ViewGroup) vWeb.getParent();
        parent.addView(vCustom);
    }
}

@Override
public void onHideCustomView() {
    setFullscreen(false);
    if (vCustom != null) {
        ViewGroup parent = (ViewGroup) vWeb.getParent();
        parent.removeView(vCustom);
        vCustom = null;
    }
    if (mCallback != null) {
        mCallback.onCustomViewHidden();
        mCallback = null;
    } 
} 
  1. 设置全屏,切换屏幕方向
void setFullscreen(boolean fullscreen) { 
    if (fullscreen) {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        vToolbar.setVisibility(View.GONE);
        vWeb.setVisibility(View.GONE);
    } else {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        vToolbar.setVisibility(View.VISIBLE);
        vWeb.setVisibility(View.VISIBLE);
    }
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
}

参考:
1、Android WebView 详解
2、WebView·开车指南
3、Android WebView 常用API参考手册

上一篇 下一篇

猜你喜欢

热点阅读