前言

虽然项目主体是原生Android开发,但是难免会遇到一些H5页面,如:首页Banner的活动推送。我们之所以选择H5来实现,因为它相对灵活,可以多平台运行,从而提高开发效率,节约开发成本。

文章分为两个章节:Android与H5交互、WebView加载进度条。

一、Android与H5交互

Android与H5的简单交互.gif
1、WebView加载HTML页面
// 加载一个网页:webView.loadUrl("http://www.baidu.com/");// 加载assets文件夹下的test.html页面webView.loadUrl("file:///android_asset/test.html");

为了点击HTML的内部的链接不跳到外部浏览器,我们还需要setWebViewClient:

// 帮助WebView处理各种通知、请求事件,不写html页面里的链接会跳到外部浏览器哦mWebView.setWebViewClient(new WebViewClient());
2、本地Java调用js方法

想要调用js方法,就需要让webView支持才可以:

WebSettings webSettings = mWebView.getSettings();// 设置为可调用js方法webSettings.setJavaScriptEnabled(true);

若调用的js方法没有返回值,则直接可以调用mWebView.loadUrl("javascript:show()"),其中show是js中的方法;
若有返回值时我们可以调用mWebView.evaluateJavascript()方法:

// 直接访问H5里不带返回值的方法,show()为H5里的方法mWebView.loadUrl("JavaScript:show()");// Android调用有返回值js方法,安卓4.4以上才能用这个方法mWebView.evaluateJavascript("sum(1,2)", new ValueCallback() {    @Override    public void onReceiveValue(String value) {        Log.e(TAG, "js返回的结果为 = " + value);        Toast.makeText(MainActivity.this, "js返回的结果为 = " + value, Toast.LENGTH_LONG).show();    }});

js代码如下:

3、js调用本地Java方法

在Android4.2以上可以直接使用@JavascriptInterface注解来声明,下面是在一个本地Java方法:

 public class JsInteration {    // 一定要写,不然H5调不到这个方法    @JavascriptInterface    public String back() {        return "我是java方法的返回值";    }    @JavascriptInterface    public void goNewAct(String str) {        // 也可接收js中的参数        Log.e(TAG, "goNewAct: " + str);        startActivity(new Intent(MainActivity.this, NewActivity.class));    }}

定义完这个方法后再调用mWebView.addJavascriptInterface()方法:

// 打开js接口給H5调用,参数1为本地类名,参数2为别名;h5用window.别名.类名里的方法名才能调用方法里面的内容// 例如:window.android.back();mWebView.addJavascriptInterface(new JsInteration(), "android");

js代码如下:

4、WebView监听返回键

当webview包含多个页面的时候,当我们点击返回键的时候,更多时候我们需要的是返回上个页面,而不是直接关闭webview。所以我们需要重写返回键事件:

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {    if ((keyCode == KeyEvent.KEYCODE_BACK)) {        if (webView.canGoBack()) {            // goBack()表示返回WebView的上一页面            webView.goBack();            return true;        } else {            finish();            return true;        }    }    return false;}

项目源码在文章末尾给出,已上传至GitHub。

二、WebView加载进度条

在实现基本功能的同时,我们还要注重用户体验,所以加载进度条也就变得不可或缺。本着用户是上帝的原则,还能说些什么(摊手)。。


ProgressWebView.gif
实现思路

首先在自定义的WebView中加入了一个水平方向的ProgressBar,然后为这个ProgressBar设置progressDrawable;创建WebChromeClient 继承 WebChromeClie,监听加载进度的变化onProgressChanged,并做出相应的设置;重写onScrollChanged方法,防止因滑动而造成ProgressBar的移动。
完整代码如下:

public class ProgressWebView extends WebView {    private ProgressBar mProgressBar;    public ProgressWebView(Context context) {        super(context);    }    public ProgressWebView(Context context, AttributeSet attrs) {        super(context, attrs);        // 使用ProgressBar作为加载进度条,当然也可使用其他view作为进度显示        mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 8);        mProgressBar.setLayoutParams(layoutParams);        // 获取Drawable资源,并为ProgressBar设置setProgressDrawable        Drawable drawable = ContextCompat.getDrawable(context, R.drawable.web_progress_bar_states);        mProgressBar.setProgressDrawable(drawable);        addView(mProgressBar);        // 辅助WebView处理js的对话框,网站图标,网站title,加载进度等        setWebChromeClient(new WebChromeClient());    }    public class WebChromeClient extends android.webkit.WebChromeClient {        @Override        public void onProgressChanged(WebView view, int newProgress) {            if (newProgress == 100) {                // 加载完成,将进度条隐藏                mProgressBar.setVisibility(GONE);            } else {                if (mProgressBar.getVisibility() == GONE) {                    mProgressBar.setVisibility(VISIBLE);                }                // 设置加载进度                mProgressBar.setProgress(newProgress);            }            super.onProgressChanged(view, newProgress);        }    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        // 使进度条始终固定在顶部位置,快速滑动时还是会有影响,日常使用ok        // 使用ViewGroup.LayoutParams滑动会消失,原因不详,求大神告知        LayoutParams lp = (LayoutParams) mProgressBar.getLayoutParams();        lp.x = l;        lp.y = t;        mProgressBar.setLayoutParams(lp);        super.onScrollChanged(l, t, oldl, oldt);    }}

进度条Drawable这里写的比较简单,当然也可以写的炫酷点。web_progress_bar_states.xm代码如下:

                                                                                

完整的MainActivity代码:

public class MainActivity extends AppCompatActivity {    private static final String TAG = "--->";    private ProgressWebView mWebView;    @SuppressLint({"JavascriptInterface", "SetJavaScriptEnabled"})    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mWebView = findViewById(R.id.webview);        // 加载本地asset下面的test.html文件        mWebView.loadUrl("file:///android_asset/test.html");        // 加载普通网页//        mWebView.loadUrl("http://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gbk&word=%CD%BC%C6%AC&fr=ala&ala=1&alatpl=others&pos=0");        WebSettings webSettings = mWebView.getSettings();        // 打开js支持        webSettings.setJavaScriptEnabled(true);        // 打开js接口給H5调用,参数1为本地类名,参数2为别名;h5用window.别名.类名里的方法名才能调用方法里面的内容,例如:window.android.back()        mWebView.addJavascriptInterface(new JsInteration(), "android");        // 帮助WebView处理各种通知、请求事件,不写html页面里的链接会跳到外部浏览器哦        mWebView.setWebViewClient(new WebViewClient());        // 辅助WebView处理js的对话框,网站图标,网站title,加载进度等,非必须(由于ProgressWebView重写了该方法,这里应该注销,否则自定义无效)//        mWebView.setWebChromeClient(new WebChromeClient());        // 缓存模式(方便测试加载进度条)        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);    }    /**     * 自己写一个类,里面是提供给H5访问的方法     */    public class JsInteration {        /**         * 一定要写,不然H5调不到这个方法         */        @JavascriptInterface        public String back() {            return "我是java方法的返回值";        }        @JavascriptInterface        public void goNewAct(String str) {            // 可接收js中的参数            Log.e(TAG, "goNewAct: " + str);            Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();            startActivity(new Intent(MainActivity.this, NewActivity.class));        }    }    /**     * 点击按钮,访问H5里带返回值的方法     */    @TargetApi(Build.VERSION_CODES.KITKAT)    public void onClick(View v) {        // 直接访问H5里不带返回值的方法,show()为H5里的方法        mWebView.loadUrl("JavaScript:show()");        // 传固定字符串可以直接用单引号括起来        // 访问H5里带参数的方法,alertMessage(message)为H5里的方法        mWebView.loadUrl("javascript:alertMessage('哈哈')");        // 当出入变量名时,需要用转义符隔开        String content = "2333";        mWebView.loadUrl("javascript:alertMessage(\"" + content + "\")");        // Android调用有返回值js方法,安卓4.4以上才能用这个方法        mWebView.evaluateJavascript("sum(1,2)", new ValueCallback() {            @Override            public void onReceiveValue(String value) {                Log.e(TAG, "js返回的结果为 = " + value);                Toast.makeText(MainActivity.this, "js返回的结果为 = " + value, Toast.LENGTH_LONG).show();            }        });    }}

项目源码:https://github.com/princekin-f/webview
随缘点赞,传播正能量~

更多相关文章

  1. Android(安卓)Service生命周期及用法!
  2. android多线程编程总结
  3. Android(安卓)Activity生命周期具体内容概述
  4. Android的SQLite学习及使用方法(1)
  5. Android自适应不同屏幕几种方法
  6. Android:异步调用详解
  7. Android(安卓)AIDL(Android(安卓)Interface Definition Language
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. android 版本更新 同时清除旧版本数据
  2. Android(安卓)Permission大全1.0最终版本
  3. android sdk manager不显示更新,只显示已
  4. Android Handler(一)
  5. Android标题栏、状态栏图标文字颜色及背
  6. Android(安卓)5.X新特性-Material Design
  7. Android应用程序自启动,已用于售卖机开机
  8. Android 帧动画
  9. Android(安卓)ToggleButton
  10. ANDROID 经典开源项目