ExMobi+Agile Lite開發內置瀏覽器APP

pk3589 8年前發布 | 18K 次閱讀 移動Web開發框架 移動開發

來自: http://my.oschina.net/nandy007/blog/608359


微信對內置瀏覽器的定制封裝,使得H5的流量入口再次重新被定義。在原生程序中使用H5也成為非常必要的一種搭配。這也得益于H5對于簡單的瀏覽性質的內容可以很好的進行展現和傳播。

由于在實際項目中有需要在移動端使用到H5,而大部分H5頁面都是來源于網絡的,所以這里嘗試使用ExMobi+Agile Lite來開發一個內置瀏覽器的功能。

相對于傳統的瀏覽器功能,由于移動端具有豐富的本地能力可以調用,比如:二維碼掃描、本地存儲、各類第三方SDK分享等等,讓移動端的瀏覽器可以更加個性化。

而我們一般看到的移動端瀏覽器功能通常包括:

1.輸入地址跳轉頁面或者輸入關鍵字搜索。

2.更夠掃描二維碼讀取地址信息等進行展示。

3.能夠前進、后退、刷新頁面等基本導航操作。

4.可以收藏某些頁面

5.可以將頁面進行社會化分享。

更大一些的瀏覽器還可以做自己的門戶,有自己的用戶體系等等。

選擇ExMobi + Agile Lite,主要是由于ExMobi有強大的UI展現能力可以支持原生UI和webview的多窗口混合展現,以及豐富的本地能力以及與第三方SDK集成的接口,可以方便調用攝像頭、GPS、第三方SDK等能力,而Agile Lite作為開源、靈活的H5框架,對H5門戶的UI和交互處理非常便捷,而且它內置了很多操作ExMobi本地能力的JS橋接類。

由于現在處于起步階段,暫時功能做到1/2/3,首頁的門戶也比較簡單,后續會把各個部分和多窗口支持起來。

目前代碼很簡單,只需要兩個頁面,若干圖片和Agile Lite框架就可以。

先上效果圖再上源碼:

首頁門戶,目前只是一些熱門的網站的鏈接,后續可以借助ExMobi服務端的集成能力抓爬和采集一些熱門的資訊/新聞/天氣等信息進行展現,還可以結合企業系統把企業的一些待辦信息在此進行展示,形成一個以h5為入口的企業門戶。

點擊門戶的淘寶icon就會跳轉打開淘寶手機版頁面。當然如果做為企業使用,也可以通過門戶來打開獨立的app程序而不僅僅是H5鏈接地址。

如果用戶輸入的是關鍵字,自動調用百度進行搜索,后續規劃中會搭建一個內部搜索系統,可以對內部信息和系統進行查詢,返回符合企業信息的數據,展示的內容相較于百度搜索會更加豐富,可以是圖文/音頻/鏈接/app等,甚至還有一些實時的推送消息。

目前的瀏覽器客戶端還很簡單,只有兩個頁面,一個是UIXML,一個是HTML頁面,其中UIXML頁面作為程序首頁展現一個原生窗口和部分原生UI,中間放置一個webview組件指向HTML頁面展示門戶。

UIXML頁面的代碼如下:

<header>
        <div style="border-size:0; background-color: #ffffff;">
            <input type="text" id="urlDom" style="width:80%;border-size: 0;" prompt="請輸入網址或關鍵字"></input>
            <div style="width: 20%; text-align: right; padding:0 6 0 0;" id="goBtn" href="doGo()">
                <img class="footer_menu" src="res:image/app/ic_menu_search_holo_light.png"></img>
            </div>
            <hr/>
        </div>        

    </header>

    <body style="padding:0;margin:0;" onload="doLoad()">
        <webview id="wvDom" url="" plusready="doReady()" backmonitor="true"></webview>
    </body>
    <footer style="padding:10 0;">
        <div style="width: 25%; text-align: center;">
            <img class="footer_menu" id="backBtn" href="doBack()" src="res:image/app/back.png"></img>
        </div>
        <div style="width: 25%; text-align: center;">
            <img class="footer_menu" id="forwardBtn" href="doForward()" src="res:image/app/forward.png"></img>
        </div>
        <div style="width: 25%; text-align: center;">
            <img class="footer_menu" id="refreshBtn" href="doRefresh()" src="res:image/app/ refresh.png"></img>
        </div>
        <div style="width: 25%; text-align: center;">
            <img class="footer_menu" id="scalBtn" href="doScal()" src="res:image/app/qrcode.png"></img>
        </div>
    </footer>

這里充分利用的了ExMobi的UIXML原生組件進行布局,構建原生的窗口,在窗口頂部和底部放置原生的按鈕組件以及支持h5的webview組件,通過JS來達到原生UI與h5的交互,實現前進、后退、刷新、掃描、搜索等功能,這個頁面里執行了一些函數,如下:

var BMC = function(options){
            this.opts = {
                wvDom : document.getElementById(options.wvDom),
                firstUrl : options.firstUrl
            };
        };

        BMC.prototype.utils = {};
        BMC.prototype.utils.checkURL = function(URL){
            var str= URL||'';
            var Expression = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
            var objExp = new RegExp(Expression);
            return objExp.test(str);
        };

        BMC.prototype.utils.showToast = function(msg){
            var toast = new Toast();
           toast.setText(msg);
           toast.setDuration(1000);
           toast.show();
        };

        BMC.prototype.getOpts = function(){
            return this.opts;
        };

        BMC.prototype.init = function(){
            var opts = this.opts;
            opts.wvDom.loadUrl(opts.firstUrl);
        };

        BMC.prototype.go = function(url){
            if(!url){
                alert('請輸入網址');
                return;
            }
            if(this.utils.checkURL(url)){
                this.opts.wvDom.loadUrl(url);
            }else if(this.utils.checkURL('http://'+url)){
                this.opts.wvDom.loadUrl('http://'+url);
            }else{
                this.opts.wvDom.loadUrl('http://m.baidu.com/s?word='+EncryptionUtil.urlEncode(url, 1));
            }
        };

        BMC.prototype.refresh = function(){
            this.opts.wvDom.refresh();
        };

        BMC.prototype.back = function(){
            if(!this.opts.wvDom.canBack()){
                this.utils.showToast('已經是第一頁了');
                return;
            }
            this.opts.wvDom.back();
        };

        BMC.prototype.forward = function(){
            if(!this.opts.wvDom.canForward()){
                this.utils.showToast('已經是最后一頁了');
                return;
            }
            this.opts.wvDom.forward();
        };

        function doLoad(){
            var url = 'res:page/www/index.html';
            var bmc = new BMC({
                wvDom : 'wvDom',
                firstUrl : url
            });

            window.doReady = function(){
                var opts = bmc.getOpts();
                var url = opts.wvDom.getUrl();
                var urlDom = document.getElementById('urlDom');
                urlDom.value = url.indexOf('file')==0?'':url;

                opts.wvDom.executeScript('document.addEventListener("backmonitor",function(){ nativePage.executeScript("doCheckBack()"); history.go(-1);}, false);');    
            }

            window.doGo = function(){
                var url = document.getElementById('urlDom').value;
                bmc.go(url);
            };

            window.doBack = function(){
                bmc.back();
            };

            window.doForward = function(){
                bmc.forward();
            };

            window.doRefresh = function(){
                bmc.refresh();
            };

            window.decode = new Decode();
            window.doScal = function(){
                decode.onCallback = decodeCallback;/*設置解碼結束回調函數*/
                decode.startDecode();/*開始解碼*/
            };

            window.decodeCallback = function(){       
                if(!decode.isSuccess()){/*返回解碼是否成功*/
                     bmc.utils.showToast('二維碼錯誤');
                }else{
                    bmc.go(decode.result);
                }
            };

            window.doCheckBack = function(){
                var opts = bmc.getOpts();
                if(!opts.wvDom.canBack()) close();
            }

            bmc.init();
        }

可以看出,代碼中主要操作的就是ExMobi的webview組件,以達到對h5頁面的控制。、

再來看看HTMML頁面代碼:

<!-- HTML5文件 -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
        <title>首頁</title>
        <link rel="stylesheet" href="assets/agile/css/agile.layout.css">
        <link rel="stylesheet" href="assets/agile/css/flat/flat.component.css">
        <link rel="stylesheet" href="assets/agile/css/flat/flat.color.css">
        <link rel="stylesheet" href="assets/agile/css/flat/iconline.css">
        <link rel="stylesheet" href="assets/agile/css/flat/iconlogo.css">
    </head>
    <body >
        <div id="section_container">
            <section id="icon_logo_section" data-role="section" class="active">
                <article data-role="article" id="main_article" data-scroll="verticle" class="active" style="top:0px;bottom:0px;">
                    <div class="scroller padded text-center"> 
                        <div class="grid" data-col="3">
                            <div class="grid-cell" data->
                              <div class="grid-img bg-alizarin"><span class="iconfont iconlogo-logo-qq"></span></div>
                              <label class="grid-label">騰訊</label>
                            </div>


                            <div class="grid-cell" data->
                              <div class="grid-img bg-carrot"><span class="iconfont iconlogo-logo-taobao"></span></div>
                              <label class="grid-label">淘寶</label>
                            </div>

                            <div class="grid-cell" data->
                              <div class="grid-img bg-peter-river"><span class="iconfont iconlogo-logo-baidu"></span></div>
                              <label class="grid-label">百度</label>
                            </div>

                            <div class="grid-cell" data->
                              <div class="grid-img bg-wet-asphalt"><span class="iconfont iconlogo-logo-sinaweibo"></span></div>
                              <label class="grid-label">微博</label>
                            </div>

                            <div class="grid-cell" data->
                              <div class="grid-img bg-nephritis"><span class="iconfont iconlogo-logo-wechat"></span></div>
                              <label class="grid-label">微信</label>
                            </div>

                            <div class="grid-cell" data->
                              <div class="grid-img bg-orange"><span class="iconfont iconlogo-logo-starrysky"></span></div>
                              <label class="grid-label">烽火</label>
                            </div>
                            <div class="clearfix"></div>
                        </div>
                    </div>  

                </article>
            </section>
        </div>

        <!--- third --->
        <script src="assets/third/jquery/jquery-2.1.3.min.js"></script>
        <script src="assets/third/jquery/jquery.mobile.custom.min.js"></script>
        <script src="assets/third/iscroll/iscroll-probe.js"></script>
        <script src="assets/third/arttemplate/template-native.js"></script>
        <!-- agile -->
        <script type="text/javascript" src="assets/agile/js/agile.js"></script>       
        <!-- app -->
        <script type="text/javascript" src="assets/app/js/app.js"></script>
        <script>
            $('[data-href]').on(A.options.clickEvent, function(){
                location.href = $(this).data('href');
                return false;
            })
        </script>
    </body>
</html>

由于功能比較簡單,主要是引用了Agile Lite框架的基本JS和CSS進行布局。

我們可以看到,在UIXML中的布局既有UIXML原生組件,也可以由webview組件展示H5,可以讓原生UI和H5界面展現更好的融合在一起,相互搭配。

而UIXML中也調用了ExMobi提供的二維碼掃描JS API,后面要做的本地收藏、社會化分享等ExMobi都有很好的支持。特別是ExMobi特有的支持的多窗口模式,一個應用中可以打開多個UIXML文件,也就是一個一個獨立的窗口,并且都具有原生窗口的生命周期事件繼承,可以讓頁面之間的交互更加靈活。

后續的新功能再更新咯。

 

 本文由用戶 pk3589 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!