Android開發中實現點擊Webview中的圖片調用原生組件進行展示

去年有一段時間工作不忙,閑暇之余就自己做了一個閱讀類的應用——《知豆了》,這個應用很簡單,就是通過fiddler抓取豆瓣一刻,知乎日報,一個,每日一文和國家地理等應用的網絡APi,并分析他們的數據,然后將數據應用到自己的應用中去。
應用截圖:

1.png

(文章列表)

2.png

(文章詳情)

3.png

(圖片瀏覽)

做什么?

其實要做的很簡單,我們可以看到圖1是文章列表,這里的數據是豆瓣一刻的Api返回的Json數據,通過解析該數據就可以得到一個圖文混排的列表數據內容,之后再利用ListView的Adapter的getItemViewType方法實現三種不同的item混合調用即可。
之后,圖2是點擊進某個文章后看到的數據內容,這部分內容是Html數據,這個數據有Html代碼也有css代碼,利用的就是WebView來加載網頁的方式達到快速的實現圖文混排的目的,用原生的Android組件是沒辦法很快速很完美的實現這個效果的,所以這是最快的解決方案,但是這個方案就帶來了一個問題,那就是如果我想收藏或者單獨瀏覽這個網頁中的某張圖片便會很困難,因為無法快速的將圖片數據加載到原生的Android組件中去,于是便要想辦法,讓Android原生與Html進行交互,從而達到我們的目的。
其實說到底,我們只要在用戶點擊圖片的時候獲得這個圖片的Url然后將Url告訴我們的安卓圖片組件就可以了,前一步有過web開發經驗的朋友應該都很容易想到,只要利用JavaScript的onClick監聽就可以輕松實現獲取圖片Url的效果,但是如何將獲得Url告訴Android組件,則需要用到Android與JavaScript交互的相關知識了。

怎么做?

因為用到了WebView,那么話不多說了,直接要在Activity中初始化WebView組件才是正事:

  mWebView=(WebView) this.findViewById(R.id.news_detail_webView);

之后再對WebView進行初始化設置:

          mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
          mWebView.getSettings().setJavaScriptEnabled(true);  
          mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);  
          mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  //設置 緩存模式  
          // 開啟 DOM storage API 功能  
          mWebView.getSettings().setDomStorageEnabled(true);  
          //開啟 database storage API 功能  
          mWebView.getSettings().setDatabaseEnabled(true);   
          //開啟 Application Caches 功能  
          mWebView.getSettings().setAppCacheEnabled(true);  
          mWebView.getSettings().setBlockNetworkImage(false);
          mWebView.getSettings().setLoadsImagesAutomatically(true); //自動加載圖片 
          mWebView.getSettings().setPluginState(PluginState.OFF);
          
          DisplayMetrics metrics = new DisplayMetrics();
          getWindowManager().getDefaultDisplay().getMetrics(metrics);

設置的具體內容看代碼都能看懂,注意一定要加上setJavaScriptEnabled(true);這個設置,不然的話JavaScript在WebView中都不起作用,還談什么交互呢?
然后在Oncreate方法中繼續加入如下兩行代碼:

mWebView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");  
mWebView.setWebViewClient(new MyWebViewClient());

注意了,這兩行代碼就是Android與JavaScript交互的關鍵。
我們先看第一行代碼:

mWebView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");

這行代碼的意思就是,給WebView組件加上javaScript的接口,至于接口的內容是什么,接口叫什么名字,方法中的兩個參數就是了。

先看第一個參數,看到可以new就應該知道,這個應該是一個類了,你可以把這個類寫成一個內部類,也可以把它提取成一個獨立的類,現在來看看這個類的內容:

// js通信接口
      public class JavascriptInterface {

          private Context context;

          public JavascriptInterface(Context context) {
              this.context = context;
          }

          public void openImage(String img) {
              //
              Intent intent = new Intent();
              intent.putExtra("image", img);
              intent.setClass(context, ShowWebImageActivity.class);
              context.startActivity(intent);
          }
      }

這段代碼就是用來實現程序在點擊后應該執行什么操作的,看代碼可以知道,我是將得到的圖片路徑當作參數傳遞給ShowWebImageActivity的,這個Activity負責的就是根據圖片的Url地址加載圖片。
你可能著急了,這里的代碼也只是交互完畢后的工作內容啊,具體怎么交互啊?
別急,我們來看剛才OnCreate方法的最后一行代碼:

mWebView.setWebViewClient(new MyWebViewClient());

這個方法是用來自定義WebView加載過程中的操作的,具體看 MyWebViewClient 這個類:

  // 監聽
      private class MyWebViewClient extends WebViewClient {
          @Override
          public boolean shouldOverrideUrlLoading(WebView view, String url) {

              return super.shouldOverrideUrlLoading(view, url);
          }

          @Override
          public void onPageFinished(WebView view, String url) {

              view.getSettings().setJavaScriptEnabled(true);

              super.onPageFinished(view, url);
              // html加載完成之后,添加監聽圖片的點擊js函數
              addImageClickListner();

          }

          @Override
          public void onPageStarted(WebView view, String url, Bitmap favicon) {
              view.getSettings().setJavaScriptEnabled(true);

              super.onPageStarted(view, url, favicon);
          }

          @Override
          public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

              super.onReceivedError(view, errorCode, description, failingUrl);

          }
      }

可以看到,大部分都是調用的父類的方法,只是在OnPageFinished這個方法里加入了一個自己的方法,addImageClickListener()方法,這里其實就是交互的關鍵了,我們繼續看這個方法:

// 注入js函數監聽
      private void addImageClickListner() {
          // 這段js函數的功能就是,遍歷所有的img幾點,并添加onclick函數,
          //函數的功能是在圖片點擊的時候調用本地java接口并傳遞url過去
          mWebView.loadUrl("javascript:(function(){" +
          "var objs = document.getElementsByTagName(\"img\"); " + 
                  "for(var i=0;i<objs.length;i++)  " + 
          "{"
                  + "    objs[i].onclick=function()  " + 
          "    {  " 
                  + "        window.imagelistner.openImage(this.src);  " + 
          "    }  " + 
          "}" + 
          "})()");
      }

好了,這個就是注入的關鍵了,首先利用WebView的方法loadUrl("javascript:xxx")來實現注入,之后就可以看注入的方法內容了,學過JS的應該很容易理解,其實就是遍歷當前的Html,然后將Html中的Img組件全部獲取到后,再給每個IMG組件加入onClick事件,該事件的方法體就是:

window.imagelistner.openImage(this.src);

注意看這個imagelistenr其實就是 mWebView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner"); 定義的方法名,而openImage就是我們自定義的JavaScriptInterface中的openImage方法。

至此,Android與JavaScript的交互就已經完畢了,點擊WebView中的圖片就可以調用我們原生的Android組件來加載了,想縮放,想下載就隨你啦!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容