混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条


现在关于混合开发也越来越多了,很多人喜欢跟随,比如HB,比如RN,其实这东西很早就有这么一个概念了,而且说实话,这方面的需求目前来讲,还是只针对一个别的应用的,不过日后会发展成什么样,那我就不知道了,不过在此之前,我们的WebView,还是用的比较多的,包括他浏览新闻,以及加载一些动作,也就是加载JS,这样的话,我们就可以拿出来讲一讲了,说真的,学习android也挺久的了,感觉很多东西,一出来的时候都哇哇哇的,到后来都是不了了之了,因为只在于型,而万变不离其宗,源码才是最好的老师,所以现在越来越往下面走了,不过我主要还是处于上层(framework和application),好像有点跑题了,我们就不废话了,我们直接进入主题吧,你在本章节中,将会学习到

  • WebView加载网页的技巧
  • WebView加载JavaScript的技巧
  • WebView增加加载进度条

一.加载网页

先来说说大家经常用的加载网页吧,其实前辈们已经走出来了一条道路了,这里我也比较推荐这个知乎

我们新建一个WebViewSample,然后给layout添加webview的组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <WebView
        android:id="@+id/mWebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

对了,这个要记得添加网络权限哦

<uses-permission android:name="android.permission.INTERNET"/>

好的,我们前期工作都准备OK了,开撸吧,骚年!!!

package com.lgl.webviewsample;

/*
 *  项目名:  WebViewSample
 *  包名:    com.lgl.webviewsample
 *  文件名:   UrlActivity
 *  创建者:   LGL
 *  创建时间:  2016/8/12 22:40
 *  描述:    加载网页
 */

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;

public class UrlActivity extends AppCompatActivity {

    private WebView mWebView;
    //地址
    private String url = "http://www.baidu.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_url);
        //初始化
        mWebView = (WebView) findViewById(R.id.mWebView);
        //加载网页
        mWebView.loadUrl(url);
    }
}

我们通过这段代码就可以去加载百度的网页,但是你会发现,只要一进去他就会跳转到浏览器,没错,这里我们需要做点处理了,因为他只是把url加载到我们本地的浏览器,这里也就牵扯到一个概念混合开发

混合开发比较火,这个是毋庸置疑的,我们还是的理解他的概念,混合开发有两种模式

  • 1.Web App
  • 2.Native App

比较主流的当然是Native App啦。因为他更加的灵活,等等

这里我们就简单的实现以下登录的效果,什么是登录?就是我们加载一个网站去完成登录的操作,但是在此之前,我们需要打开我们的TomCat去写怎么一个html网页了,关于tomcat怎么去搭建和使用我就不说了,不会的可以看下我的这篇博文:

然后我们就开始编写了

<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>login</title>

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html;charset=UTF-8">

    </head>

    <body>
        <form name="form1" action="" method="POST">
            <center>
                <table border="1" bordercolor="#CCCCCC" cellpadding="1" cellspacing="1">
                    <tr>
                        <td align="right">name:</td>
                        <td><input type="text" name="username" value=""></td>
                    </tr>

                    <tr>
                        <td align="right">password:</td>
                        <td><input type="password" name="pswd" value=""></td>
                    </tr>

                    <tr>
                        <td colspan="2" align="center">
                            <input type="submit" name="submit" value="login">
                            &nbsp;&nbsp;
                            <input type="reset" name="reset" value="cancel">
                        </td>
                    </tr>
                </table>
            </center>
    </body>
</html>

显示效果

HTML写的挫不是我的错哈,我们现在的地址是:

模拟器的话IP要改一下,不然是访问不了TomCat的

行,我们加载试试

到这里,看上去就想这么一回事了,而在这里你还可以发现,他不会跳转到本地浏览器了,如何加载百度也不跳到本地浏览器,我们可以加个监听

 //本地显示
 mWebView.setWebViewClient(new android.webkit.WebViewClient(){
       @Override
       public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

这样也是OK的

好的,到这里我们仍然还没看到高级的用法,我们继续

二.加载JavaScript

既然要执行,那我们的html要修改一下了,对了,这里要说一点的就是,所操作的一些数据响应都是在服务端的,其实就是web端,而我忘记写了,所以尽量避免吧,这么久了谁还记得那挫代码,哈,我们现在给html加上一些点击事件。也就是写上我们JavaScript的方法

<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>login</title>

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html;charset=UTF-8">

        <script type="text/javascript">
        function show(){
            var th = document.form1;
            if(th.username.value==""){
                alert("your username is null");
                return;
            }

            if(th.password.value==""){
                alert("your password is null");
                return;
            }

            th.action = "/myweb/servlet/Login";
            th.submit();
        }
        </script>
    </head>

    <body>
        <form name="form1" action="" method="POST">
            <center>
                <table border="1" bordercolor="#CCCCCC" cellpadding="1" cellspacing="1">
                    <tr>
                        <td align="right">name:</td>
                        <td><input type="text" name="username" value=""></td>
                    </tr>

                    <tr>
                        <td align="right">password:</td>
                        <td><input type="password" name="pswd" value=""></td>
                    </tr>

                    <tr>
                        <td colspan="2" align="center">
                            <input type="button" name="submit" value="login" onclick="show()">
                            &nbsp;&nbsp;
                            <input type="reset" name="reset" value="cancel">
                        </td>
                    </tr>
                </table>
            </center>
    </body>
</html>

好的,JavaScript方法加上去了,然后,我们就可以看下效果了

我们不用去管成功了之后是什么,我们只要知道输入框为空的话我们就弹出提示框,那我们现在放到项目里面去

但是这个时候你会发现,点击是没有什么效果的,如果细心的朋友看过android api文档就会发现,webview默认是不支持JavaScript的,需要我们去打开,打开还不够,还需要我们去拦截他的动作,我们这里只有对话框,所以我们就先拦截他的对话框

//支持JavaScript
mWebView.getSettings().setJavaScriptEnabled(true);
//本地客户端
mWebView.setWebChromeClient(new WebChromeClient(){
   //提示框
   @Override
   public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }
        });

对的,把属性打开就好了,我们运行一下

现在提示框就出来了,哈哈,但是这个对话框实在是太烂了,这里我们拦截到了对话框,可以对他进行包装,还是在onJsAlert方法里

    //本地客户端
    mWebView.setWebChromeClient(new WebChromeClient(){
            //提示框
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                //本地对话框
                AlertDialog.Builder builder = new AlertDialog.Builder(UrlActivity.this);
                builder.setTitle("温馨提示:");
                //服务器端
                builder.setMessage(message);
                //按钮
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //确认操作
                        result.confirm();
                    }
                });

                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        result.cancel();
                    }
                });
                builder.show();
                return true;
            }
        });

这里就比较清晰了,只是写了一个原生的提示框显示,我们看下效果

这个效果还是比较满意的

当然,要是只教这些的话,那只能说明在扯淡,这根本用不上开发,我们继续撸,现在撸什么?就是怎么把账号密码保存在本地,也就是应用里,这个要怎么做呢?跟着我一起去看

我们其实也是加一个属性

  //数据操作
  mWebView.addJavascriptInterface(new JSObjClass(),"JSObj");

这里的两个参数都是非常的有用的,第一个为一个接口回调,第二个是一个标识,我们服务端会用上,先看下我们的回调,写个类

    /**
     * 数据保存类
     */
    public class JSObjClass {
        //获取用户名和密码
        @JavascriptInterface
        public String getMessage(String name, String pass) {
            Log.i("TAG", "name:" + name + ":" + "pass:" + pass);
            return name + "," + pass;
        }
    }

这里要注意下声明@JavascriptInterface就好了,然后我们就去html那里改JavaScript了

<script type="text/javascript">
        function show(){
            var th = document.form1;
            var name = th.username.value;
            if(name==""){
                alert("your username is null");
                return;
            }
            var pass = th.pswd.value;
            if(pass==""){
                alert("your password is null");
                return;
            }
            //接口回传数据
            JSObj.getMessage(name,pass);
            th.action = "/myweb/servlet/Login";
            th.submit();
        }
        </script>

OK,这里的话,其实就是调用了一句话,大家应该能看出门道来吧!!!我们运行之后,点击登录,就可以拿到了

到这里,我们加载JavaScript也讲完了

三.加载进度条

这个实现其实是比较简单的,我们先再写个进度条,要在顶部哦

   <ProgressBar
        android:id="@+id/pb"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="4dip"
        android:indeterminateOnly="false"
        android:max="100"
        android:progressDrawable="@drawable/progress_bar_states"/>

他需要一个背景是因为我想实现他的渐变达到进度的效果

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">  

    <item android:id="@android:id/background">
        <shape>
            <gradient
                    android:startColor="#FFE4C4"
                    android:centerColor="#ccffff"
                    android:endColor="#ccffff"
            />
        </shape>
    </item>  

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                        android:startColor="#234"
                        android:centerColor="#234"
                        android:endColor="#a24"
                />
            </shape>
        </clip>
    </item>  

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <gradient
                    android:startColor="#33000001"
                    android:centerColor="#40000000"
                    android:endColor="#44000000"
                />
            </shape>
        </clip>
    </item>  

</layer-list>  

就是一个xml的渐变,然后,我们就可以去绑定进度了,首先初始化一下进度条

pb = (ProgressBar) findViewById(R.id.pb);
//设置最大值
pb.setMax(100);

然后直接监听就好了

 mWebView.setWebChromeClient(new WebViewClient());
     /**
     * 接口回调
     */
    public class WebViewClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            pb.setProgress(newProgress);
            if (newProgress == 100) {
                pb.setVisibility(View.GONE);
            }
            super.onProgressChanged(view, newProgress);
        }
    }

其实原理非常的简单,加载出来了就隐藏进度条,就是这样,效果如图

最后我还是想说一下我的观点,坚持下去,你不会的才叫难,你会了就不难了,所以学习,逆水行舟,不进则退

有兴趣的可以加群:555974449,氛围很不错的群哦!

Demo下载:正在上传

混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条的更多相关文章

  1. 仿微信中加载网页时带线行进度条的WebView的实现

    finddreams:http://blog.csdn.net/finddreams/article/details/44172639 为了仿微信中加载网页时带进度条的WebView的实现,首先我们来 ...

  2. css3实现loading效果--当页面加载过程中显示Loading的进度条,全部加载完成之后进度条消失

    一个页面等图片资源全部加载完成,会需要很长时间,用户体验会很差,所以我们需要loading来掩盖这个漫长的过程! emmm,定时器?写个定时器还要清除,万一造成内存泄露?定时器之间还会互相影响,呼呼呼 ...

  3. asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)

    上文件传很常见,现在就文件上传利用HTML的File控件(uploadify)的,这里为大家介绍一下(uploadify)的一些使用方法.在目前Web开发中用的比较多的,可能uploadify(参考h ...

  4. Android--------WebView+H5开发仿美团 预加载,加载失败和重新加载

    Android嵌入式开发已经占大多数了,很多界面都是以网页的形式展示,WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. 本博客主要是模仿美团的旅游出行模块的预加载,网页加载失 ...

  5. iOS之webview加载网页、文件、html的方法

    UIWebView  是用来加载加载网页数据的一个框.UIWebView可以用来加载pdf.word.doc 等等文件 生成webview 有两种方法,1.通过storyboard 拖拽  2.通过a ...

  6. iOS-WKWebview 带有进度条加载的ViewController【KVO监听Webview加载进度】

    前言 为什么要说 WKWebview,在之前做电子书笔记时已经提过 WKWebview 在iOS8之后已完全替代 Webview,原因就不多说了,主要还是内存过大: 封装 封装一个基于 UIViewC ...

  7. WebView 加载网页和java 与js交互

    [mw_shl_code=java,true]WebView是一个可以显示网页的控件.需求:通过WebView加载assets下的html文件.实现页面的缩放.向menu键添加:前进.后退和刷新,实现 ...

  8. UIWebView 加载网页、文件、 html-b

    UIWebView  是用来加载加载网页数据的一个框.UIWebView可以用来加载pdf word doc 等等文件 生成webview 有两种方法,1.通过storyboard 拖拽 2.通过al ...

  9. UIWebView 加载网页、文件、 html

    UIWebView  是用来加载加载网页数据的一个框.UIWebView可以用来加载pdf word doc 等等文件 生成webview 有两种方法,1.通过storyboard 拖拽 2.通过al ...

随机推荐

  1. codeforces 842C Ilya And The Tree

    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...

  2. 绝世好题bzoj4300

    Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). Input 输入文件共2行. 第一行包括一个整数 ...

  3. NOIP2014-5-24模拟赛

    Problem 1 护花(flower.cpp/c/pas) [题目描述] 约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时 ...

  4. 浅析Linux内核调度

    1.调度器的概述 多任务操作系统分为非抢占式多任务和抢占式多任务.与大多数现代操作系统一样,Linux采用的是抢占式多任务模式.这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器.调度 ...

  5. poj 1755 半平面交+不等式

    Triathlon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6461   Accepted: 1643 Descrip ...

  6. bzoj2338[HNOI2011]数矩形 计算几何

    2338: [HNOI2011]数矩形 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1535  Solved: 693[Submit][Status ...

  7. SQL Server 连接 MySQL

    1.在SQL SERVER服务器上安装MYSQL ODBC驱动; 驱动下载地址:http://dev.mysql.com/downloads/connector/odbc/ 2.安装好后,在管理工具- ...

  8. Python-闭包详解

    在函数编程中经常用到闭包.闭包是什么,它是怎么产生的及用来解决什么问题呢.给出字面的定义先:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个 ...

  9. 简易js进度条

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Python开发——利用正则表达式实现计算器算法

    Python开发--利用正则表达式实现计算器算法 (1)不使用eval()等系统自带的计算方法 (2)实现四则混合运算.括号优先级解析 思路: 1.字符串预处理,将所有空格去除 2.判断是否存在括号运 ...