Hybrid小技巧:通過js調(diào)用原生對話框(Android)

在web開發(fā)中搞坝,我們會經(jīng)常使用到Alert、Confirm、Prompt等對話框怖亭,但是web自帶的對話框又很丑沐鼠,很多時候我們不得不自己寫一些彈窗或者用一些第三方庫來實現(xiàn)挚瘟,但是在Hybrid開發(fā)中,我們可以通過一些簡單操作饲梭,在web頁面用js調(diào)用原生的對話框乘盖,讓web頁面更接近原生體驗。

先看看效果吧

效果圖.gif

下面看看具體是怎么實現(xiàn)的

assets文件夾下面新建一個index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>

<body>
<p>通過JS調(diào)用三種不同的原生對話框</p>

<p>Alert對話框</p>
<p>
    <input type="submit" name="Submit1" value="展示Alert對話框" onclick="alertFun()" />
</p>
<p>Confirm對話框</p>
<p>
    <input type="submit" name="Submit2" value="展示Confirm對話框" onclick="confirmFun()" />
</p>
<p>Prompt對話框</p>
<p>
    <input type="submit" name="Submit3" value="展示Prompt對話框" onclick="promptFun()" />
</p>
<script language="JavaScript">
        function alertFun() {
            alert("這是js的alert,但是彈出的是原生的Alert警告對話框哦憔涉!")
        };

        function confirmFun() {
            if (confirm("訪問百度?")) {
                location.;
            } else alert("取消訪問!");
        };

        function promptFun() {
            var word = prompt("對YuTao說的話寫在下面吧", "對YuTao說的話寫在這里吧");
            if (word) {
                alert("你輸入了:" + word)
            } else {
                alert("呵呵,你什么都沒寫!");
            }
        }
    </script>
</body>

</html>

WebView布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/wView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp" />

</LinearLayout>

新建一個prompt_view布局

<?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">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollHorizontally="true"
        android:selectAllOnFocus="true" />

</LinearLayout>  

加載web頁面到webview

wView = (WebView) findViewById(R.id.wView);
//獲得WebSetting對象,支持js腳本,可訪問文件,支持縮放,以及編碼方式
WebSettings webSettings = wView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDefaultTextEncodingName("UTF-8");
//設(shè)置WebChromeClient,處理網(wǎng)頁中的各種js事件
wView.setWebChromeClient(new MyWebChromeClient());
wView.loadUrl("file:///android_asset/index.html");

自定義一個類實現(xiàn)WebChromeClient類,并重寫三種不同對話框

 //分別重寫onJsAlert,onJsConfirm,onJsPrompt方法
    class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message,
                                 final JsResult result) {
            //創(chuàng)建一個Builder來顯示網(wǎng)頁中的對話框
            new Builder(MainActivity.this).setTitle("Alert對話框").setMessage(message)
                    .setPositiveButton("確定", new OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            result.confirm();
                        }
                    }).setCancelable(false).show();
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message,
                                   final JsResult result) {
            new Builder(MainActivity.this).setTitle("Confirm對話框").setMessage(message)
                    .setPositiveButton("確定", new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            result.confirm();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            result.cancel();
                        }
                    }).setCancelable(false).show();
            return true;
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message,
                                  String defaultValue, final JsPromptResult result) {
            //①獲得一個LayoutInflater對象factory,加載指定布局成相應(yīng)對象
            final LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
            final View myview = inflater.inflate(R.layout.prompt_view, null);
            //設(shè)置TextView對應(yīng)網(wǎng)頁中的提示信息,edit設(shè)置來自于網(wǎng)頁的默認文字
            ((TextView) myview.findViewById(R.id.text)).setText(message);
            ((EditText) myview.findViewById(R.id.edit)).setText(defaultValue);
            //定義對話框上的確定按鈕
            new Builder(MainActivity.this).setTitle("Prompt對話框").setView(myview)
                    .setPositiveButton("確定", new OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //取得輸入的值,傳給網(wǎng)頁處理
                            String value = ((EditText) myview.findViewById(R.id.edit)).getText().toString();
                            result.confirm(value);
                        }
                    })
                    .setNegativeButton("取消", new OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            result.cancel();
                        }
                    }).show();
            return true;
        }

    }

其實原理很簡單订框,就是自定義一個類實現(xiàn)WebChromeClient類,并重寫三種不同對話框的處理方法

從html的js代碼可以看,我們在web中只寫了最簡單的js語法兜叨,沒有其他任何處理穿扳,所以這種實現(xiàn)還得Android配合。

最后送上源碼:源碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末国旷,一起剝皮案震驚了整個濱河市矛物,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跪但,老刑警劉巖履羞,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異特漩,居然都是意外死亡吧雹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門涂身,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雄卷,“玉大人,你說我怎么就攤上這事蛤售《○模” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵悴能,是天一觀的道長揣钦。 經(jīng)常有香客問我,道長漠酿,這世上最難降的妖魔是什么冯凹? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炒嘲,結(jié)果婚禮上宇姚,老公的妹妹穿的比我還像新娘匈庭。我一直安慰自己,他們只是感情好浑劳,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布阱持。 她就那樣靜靜地躺著,像睡著了一般魔熏。 火紅的嫁衣襯著肌膚如雪衷咽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天蒜绽,我揣著相機與錄音镶骗,去河邊找鬼。 笑死滓窍,一個胖子當著我的面吹牛卖词,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吏夯,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼此蜈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了噪生?” 一聲冷哼從身側(cè)響起裆赵,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎跺嗽,沒想到半個月后战授,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡桨嫁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年植兰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片璃吧。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡楣导,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畜挨,到底是詐尸還是另有隱情筒繁,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布巴元,位于F島的核電站毡咏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逮刨。R本人自食惡果不足惜呕缭,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧臊旭,春花似錦落恼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戴涝。三九已至滋戳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啥刻,已是汗流浹背奸鸯。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留可帽,地道東北人娄涩。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像映跟,于是被迫代替她去往敵國和親蓄拣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容