Android開發(fā)中實(shí)現(xiàn)點(diǎn)擊Webview中的圖片調(diào)用原生組件進(jìn)行展示

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

1.png

(文章列表)

2.png

(文章詳情)

3.png

(圖片瀏覽)

做什么?

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

怎么做?

因?yàn)橛玫搅薟ebView,那么話不多說了,直接要在Activity中初始化WebView組件才是正事:

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

之后再對WebView進(jìn)行初始化設(shè)置:

          mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
          mWebView.getSettings().setJavaScriptEnabled(true);  
          mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);  
          mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  //設(shè)置 緩存模式  
          // 開啟 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); //自動(dòng)加載圖片 
          mWebView.getSettings().setPluginState(PluginState.OFF);
          
          DisplayMetrics metrics = new DisplayMetrics();
          getWindowManager().getDefaultDisplay().getMetrics(metrics);

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

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

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

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

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

先看第一個(gè)參數(shù),看到可以new就應(yīng)該知道,這個(gè)應(yīng)該是一個(gè)類了,你可以把這個(gè)類寫成一個(gè)內(nèi)部類,也可以把它提取成一個(gè)獨(dú)立的類,現(xiàn)在來看看這個(gè)類的內(nèi)容:

// 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);
          }
      }

這段代碼就是用來實(shí)現(xiàn)程序在點(diǎn)擊后應(yīng)該執(zhí)行什么操作的,看代碼可以知道,我是將得到的圖片路徑當(dāng)作參數(shù)傳遞給ShowWebImageActivity的,這個(gè)Activity負(fù)責(zé)的就是根據(jù)圖片的Url地址加載圖片。
你可能著急了,這里的代碼也只是交互完畢后的工作內(nèi)容啊,具體怎么交互啊?
別急,我們來看剛才OnCreate方法的最后一行代碼:

mWebView.setWebViewClient(new MyWebViewClient());

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

  // 監(jiān)聽
      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加載完成之后,添加監(jiān)聽圖片的點(diǎn)擊js函數(shù)
              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);

          }
      }

可以看到,大部分都是調(diào)用的父類的方法,只是在OnPageFinished這個(gè)方法里加入了一個(gè)自己的方法,addImageClickListener()方法,這里其實(shí)就是交互的關(guān)鍵了,我們繼續(xù)看這個(gè)方法:

// 注入js函數(shù)監(jiān)聽
      private void addImageClickListner() {
          // 這段js函數(shù)的功能就是,遍歷所有的img幾點(diǎn),并添加onclick函數(shù),
          //函數(shù)的功能是在圖片點(diǎn)擊的時(shí)候調(diào)用本地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);  " + 
          "    }  " + 
          "}" + 
          "})()");
      }

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

window.imagelistner.openImage(this.src);

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評論 25 708
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    小莊bb閱讀 3,666評論 3 25
  • 這篇博客主要來介紹 WebView 的相關(guān)使用方法,常見的幾個(gè)漏洞,開發(fā)中可能遇到的坑和最后解決相應(yīng)漏洞的源碼,以...
    Shawn_Dut閱讀 7,572評論 3 55
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,875評論 0 19
  • (接上) 喻二皇子的勢力幾乎沒有觸及京城,但京城之外確早已遍及。那群老家伙們的嗅覺太過靈敏,在他們眼皮子底下發(fā)展而...
    蘇暮黎閱讀 532評論 1 0

友情鏈接更多精彩內(nèi)容