国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現點擊WebView界面中圖片滑動瀏覽與保存圖片功能

2019-10-23 18:30:20
字體:
來源:轉載
供稿:網友

一、實現需求

最近在公司的項目中遇到需求如下:

1、點擊 WebView 頁面的圖片實現開啟查看圖片模式,即可以顯示點擊的圖片,然后android/54968.html">滑動顯示下一張圖片。

android,webview,滑動,圖片,webview長按保存圖片

3、長按 WebView 頁面圖片彈出對話框可以選擇保存長按的圖片到本地相冊。

android,webview,滑動,圖片,webview長按保存圖片

拿到這個需求筆者第一反應是沒做過 WebView 相關的交互,甚至分不清這個需求是否需要服務端配合完成 Java 與 JavaScript 的互相調用,一臉茫然。

遇到這種情況筆者的解決思路一般分兩個方向:

1、找一個比較出名的客戶端有類似功能的,然后 Google 搜索,仿 XXXX,先粗略看一下有沒有現成的 Demo 可以參考,比如我這個需要,先去搜索一下 ”Android 仿微信朋友圈瀏覽圖片效果“ (這個搜索關鍵字很關鍵啊),可是筆者沒找到符合該需要的 Demo。

2、在第一個方案不好使的情況下,我們沒有了參考,那么咱們就得自己思考這個大概實現思路,然后把這個需求進行拆分,逐一擊破。所以思考大概如下:

     (1)要想展示圖片那么就得先拿到圖片,要拿到圖片只有兩種可能,第一種可能是 WebView 本身緩存了圖片,我們去緩存中讀取圖片進行顯示,可是想一下,咱們瀏覽微博看圖的時候如果沒有網,這時候去點擊圖片那么圖片是加載不出來的,所以這種可能否定了;所以只有第二種可能就是點擊圖片的時候拿到該圖片對應的 URL 網址,然后咱們自己去網絡加載圖片進行顯示,所以這個點我們 Get 到了。

     (2)要滑動圖片進行顯示下一張,那么就需要我們能拿到所有要顯示的圖片的 URL ,然后放到一個數組里面,每次滑動就進行加載一張圖片,那么也就是我們一次性拿到所有 WebView 包含圖片的 URL,這個就不是在點擊圖片的時候去獲取,而是在 WebView 加載完成后獲取到,這怎么能拿到?再想一下,WebView 進行加載顯示的時候其實是加載 HTML(比如 Assets 目錄中的文件)文本的字符串,然后進行渲染處理顯示出來,所以 HTML文本文件里面包含了我們想要的圖片網址,大家看一下下面這張截圖就是一個帶圖片的 WebView 對應加載的 HTML文本文件部分截圖,

android,webview,滑動,圖片,webview長按保存圖片

其中標簽 src 對象的內容就是我們想要的圖片 URL,所以到這里我們就有了思路,我們先拿到 WebView 加載的 HTML 內容,然后在從 HTML 里面提取我要想要的 URL。

     (3)現在我們能拿到所有圖片對應的 URL,那么滑動圖片顯示下一張就簡單了,我們直接用一個 ViewPager 來實現滑動加載圖片即可。

總結要實現這個需要我們需要做的工作有:

  • 拿到 WebView 加載的 HTML 文本。
  • 從 HTML 文本中提取所有圖片對應的 URL。
  • 處理 WebView 中圖片的點擊和長按響應事件。
  • 用 ViewPager 來實現滑動加載下一張圖片。

下面我們就按照以上幾個步驟來實現我們想要的功能。

二、主要內容

2.1 獲取 WebView 頁面所有圖片對應地址

2.1.1 解析 WebView 頁面加載的 HTML文本文件

定義供 JavaScript 調用的交互接口

 /** *這個接口就是給 JavaScript 調用的,調用結果就是返回 HTML 文本, *然后 getAllImageUrlFromHtml(HTML)  *從 HTML文件中提取頁面所有圖片對應的地址對象 **/private class InJavaScriptLocalObj { /** * 獲取 WebView 加載對應的 HTML 文本 * @param HTML WebView 加載對應的 HTML 文本 */ @android.webkit.JavascriptInterface public void showSource(String html) {  //從 HTML 文件中提取頁面所有圖片對應的地址對象  getAllImageUrlFromHtml(html); } }

WebView 開啟 JavaScript 腳本執行,調用 JavaScript 代碼

 mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new InJavaScriptLocalObj(), "local_obj"); mWebView.setWebViewClient(new WebViewClient() {  // 網頁跳轉  @Override  public boolean shouldOverrideUrlLoading(WebView view, String url) {  view.loadUrl(url);  return true;  }  // 網頁加載結束  @Override  public void onPageFinished(WebView view, String url) {  super.onPageFinished(view, url);  //解析 HTML  parseHTML(view);  } /** * Java 調取 js 代碼, * @param view WebView */private void parseHTML(WebView view) { //這段 js 代碼是解析獲取到了 HTML 文本文件,然后調用本地定義的 Java 代碼返回 //解析出來的 HTML 文本文件 view.loadUrl("javascript:window.local_obj.showSource('<head>'+"  + "document.getElementsByTagName('html')[0].innerHTML+'</head>');");}

2.1.2 從獲取到的 HTML文本文件中提取頁面所有圖片對應的地址對象

 // 獲取 img 標簽正則 private static final String IMAGE_URL_TAG = "<img.*src=(.*?)[^>]*?>"; // 獲取 src 路徑的正則 private static final String IMAGE_URL_CONTENT = "http:/"?(.*?)(/"|>|//s+)";/*** * 獲取頁面所有圖片對應的地址對象, * 例如 <img src="http://sc1.hao123img.com/data/f44d0aab7bc35b8767de3c48706d429e" /> * @param HTML WebView 加載的 HTML 文本 * @return */private List<String> getAllImageUrlFromHtml(String html) { Matcher matcher = Pattern.compile(IMAGE_URL_TAG).matcher(html); List<String> listImgUrl = new ArrayList<String>(); while (matcher.find()) { listImgUrl.add(matcher.group()); } //從圖片對應的地址對象中解析出 src 標簽對應的內容 getAllImageUrlFormSrcObject(listImgUrl); return listImgUrl;} /*** * 從圖片對應的地址對象中解析出 src 標簽對應的內容,即 url * 例如 "http://sc1.hao123img.com/data/f44d0aab7bc35b8767de3c48706d429e" * @param listImageUrl 圖片地址對象例如 : *<img src="http://sc1.hao123img.com/data/f44daab" /> */ private List<String> getAllImageUrlFormSrcObject(List<String> listImageUrl) { for (String image : listImageUrl) {  Matcher matcher = Pattern.compile(IMAGE_URL_CONTENT).matcher(image);  while (matcher.find()) {  listImgSrc.add(matcher.group().substring(0, matcher.group().length() - 1));  } } return listImgSrc; }

到這里我們獲取到了 WebView 頁面中所有圖片對象對應的 URL 地址,下面就還差一步,就是在點擊 WebView 界面的圖片時候去響應點擊事件,然后把相應的 URL 地址傳遞給 ViewPager 進行顯示就齊活了。

2.2 響應 WebView 界面圖片的點擊事件

2.2.1定義供 JavaScript 調用的交互接口

// js 通信接口,定義供 JavaScript 調用的交互接口private class MyJavascriptInterface { private Context context; public MyJavascriptInterface(Context context) { this.context = context; } /** * 點擊圖片啟動新的 ShowImageFromWebActivity,并傳入點擊圖片對應的 url * 和頁面所有圖片對應的 url * @param url 點擊圖片對應的 url */ @android.webkit.JavascriptInterface public void openImage(String url) { Intent intent = new Intent(); intent.putExtra("image", url); //listImgSrc 該參數為頁面所有圖片對應的 url intent.putStringArrayListExtra(URL_ALL, (ArrayList<String>) listImgSrc); intent.setClass(context, ShowImageFromWebActivity.class); context.startActivity(intent); }}

2.2.2 WebView 開啟 JavaScript 腳本執行,調用 JavaScript 代碼

 mWebView.getSettings().setJavaScriptEnabled(true);//載入 jsmWebView.addJavascriptInterface(new MyJavascriptInterface(this), "imageListener");mWebView.setWebViewClient(new WebViewClient() { // 網頁跳轉 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } // 網頁加載結束 @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // web 頁面加載完成,添加監聽圖片的點擊 js 函數 addImageClickListener(); }  /** * 注入 js 函數監聽,這段 js 函數的功能就是,遍歷所有的圖片,并添加 onclick 函數, * 實現點擊事件, * 函數的功能是在圖片點擊的時候調用本地 java 接口并傳遞點擊圖片對應的 url 過去 */ private void addImageClickListener() { mWebView.loadUrl("javascript:(function(){" +  "var objs = document.getElementsByTagName(/"img/"); " +  "for(var i=0;i<objs.length;i++) " +  "{"  + " objs[i].onclick=function() " +  " { "  + " window.imageListener.openImage(this.src); " +  " } " +  "}" +  "})()"); }

到這里我們完成了前兩步,拿去到 WebView 界面圖片對應的所有 URL 地址和響應 WebView 界面圖片的點擊事件,下面的事情就簡單了,用 ViewPager 滑動顯示每一張圖片,再我們進行最后一步之前,我們再來實現一個功能就是長按 WebView 界面圖片,彈出對話框來,然后可以選擇保存圖片功能,代碼如下:

WebView 中圖片長按點擊事件處理

//長按點擊事件mWebView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //響應長按事件 responseWebLongClick(v); return false; }}); /** * 響應 WebView 長按圖片的點擊事件 * @param v */ private void responseWebLongClick(View v) { if (v instanceof WebView) {  WebView.HitTestResult result = ((WebView) v).getHitTestResult();  if (result != null) {  int type = result.getType();  //判斷點擊類型如果是圖片  if (type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {   longClickUrl = result.getExtra();   //彈出對話框   showDialog(longClickUrl);  }  } } } /** * 長按 WebView 中圖片彈出對話框,可以選擇保存圖片 * @param url 點擊圖片對應的 url */ private void showDialog(final String url) { new ActionSheetDialog(this)  .builder()  .setCancelable(true)  .setCanceledOnTouchOutside(true)  .addSheetItem(   "保存到相冊",   ActionSheetDialog.SheetItemColor.Blue,   new ActionSheetDialog.OnSheetItemClickListener() {    @Override    public void onClick(int which) {    //下載圖片    downloadImage(url);    }   }).show(); }

2.3 ViewPager 滑動顯示每一張圖片,PhotoView 實現自由縮放功能

由于這部分代碼比較簡單,這里就直接貼出部分代碼,文章中所用的 Demo 代碼最終會上傳到 GitHub上,有興趣可以去瞧一瞧完整的代碼,這里簡單介紹幾個類,ShowImageFromWebActivity.java 這個類內部就包含一個 ViewPager 和兩個按鈕, ViewPager 用來滑動顯示每一張圖片,按鈕用來顯示滑動的頁數和實現點擊保存圖片功能,代碼如下:

public class ShowImageFromWebActivity extends Activity implements View.OnClickListener { private ViewPager vpImageBrowser; private TextView tvImageIndex;//顯示滑動頁數 private Button btnSave;//保存圖片按鈕 private ImageBrowserAdapter adapter; private ArrayList<String> imgUrls;//WebView 頁面所有圖片 URL private String url;//WebView 頁面所有圖片中被點擊圖片對應 URL private int currentIndex;//標記被滑動圖片在所有圖片中的位置 private Handler mHandler;//異步發送消息 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_image_from_web); initView(); initListener(); initData(); } private void initView(){ vpImageBrowser = (ViewPager) findViewById(R.id.vp_image_browser); tvImageIndex = (TextView) findViewById(R.id.tv_image_index); btnSave = (Button) findViewById(R.id.btn_save); } private void initData(){ mHandler = new Handler(); imgUrls=getIntent().getStringArrayListExtra(MainActivity.URL_ALL); url=getIntent().getStringExtra("image"); //獲取被點擊圖片在所有圖片中的位置 int position=imgUrls.indexOf(url); adapter=new ImageBrowserAdapter(this,imgUrls); vpImageBrowser.setAdapter(adapter); final int size=imgUrls.size(); if(size > 1) {  tvImageIndex.setVisibility(View.VISIBLE);  tvImageIndex.setText((position+1) + "/" + size); } else {  tvImageIndex.setVisibility(View.GONE); } vpImageBrowser.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {  @Override  public void onPageSelected(int arg0) {  currentIndex=arg0;  int index = arg0 % size;  tvImageIndex.setText((index+1) + "/" + size);  }  @Override  public void onPageScrolled(int arg0, float arg1, int arg2) {  // TODO Auto-generated method stub  }  @Override  public void onPageScrollStateChanged(int arg0) {  // TODO Auto-generated method stub  } }); vpImageBrowser.setCurrentItem(position); } private void initListener(){ btnSave.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){  case R.id.btn_save :  Toast.makeText(getApplicationContext(), "開始下載圖片", Toast.LENGTH_SHORT).show();  downloadImage();  break; } /** * 開始下載圖片 */ private void downloadImage() { downloadAsync(imgUrls.get(currentIndex), Environment.getExternalStorageDirectory().getAbsolutePath() + "/ImagesFromWebView"); }  }

ShowImageFromWebActivity.java 對應 xml 文件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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" android:background="@android:color/black" tools:context="activity.ShowImageFromWebActivity"> <view.PhotoViewViewPager android:id="@+id/vp_image_browser" android:layout_width="match_parent" android:layout_height="match_parent" > </view.PhotoViewViewPager> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal" android:padding="16dp" > <TextView  android:textSize="18sp"  android:id="@+id/tv_image_index"  android:layout_width="56dp"  android:layout_height="36dp"  android:background="@drawable/shape_corner_rect_gray"  android:gravity="center"  android:paddingTop="3dp"  android:paddingBottom="3dp"  android:paddingRight="10dp"  android:paddingLeft="10dp"  android:text="1/9"  android:textColor="@android:color/white" /> <View  android:layout_width="0dp"  android:layout_height="1dp"  android:layout_weight="1" /> <Button  android:id="@+id/btn_save"  android:textSize="@dimen/_16sp"  android:layout_width="56dp"  android:layout_height="36dp"  android:background="@drawable/shape_corner_rect_gray"  android:gravity="center"  android:padding="4dp"  android:text="保存"  android:textColor="@color/white" /> </LinearLayout></RelativeLayout>

ImageBrowserAdapter.java 類代碼如下:

public class ImageBrowserAdapter extends PagerAdapter { private Activity context; private List<String> picUrls; public ImageBrowserAdapter(Activity context, ArrayList<String> picUrls) { this.context = context; this.picUrls = picUrls; } @Override public int getCount() { return picUrls.size(); }  @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public View instantiateItem(ViewGroup container, int position) { View view = View.inflate(context, R.layout.item_image_browser, null); ImageView iv_image_browser = (ImageView) view.findViewById(R.id.show_webimage_imageview); String picUrl = picUrls.get(position); final PhotoViewAttacher photoViewAttacher=new PhotoViewAttacher(iv_image_browser); photoViewAttacher.setScaleType(ImageView.ScaleType.FIT_CENTER); //顯示圖片 Glide.with(context).  load(picUrl)  .crossFade()  .placeholder(R.drawable.avatar_default)  .error(R.drawable.image_default_rect)  .into(new GlideDrawableImageViewTarget(iv_image_browser){  @Override  public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {   super.onResourceReady(resource, animation);   photoViewAttacher.update();  }  }); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); }

上面代碼也很簡單,就是根據 URL 來加載顯示圖片,然后利用 PhotoView 進行縮放。

//ImageBrowserAdapter Item 布局文件<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <RelativeLayout  android:orientation="horizontal"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:gravity="center_vertical">  <uk.co.senab.photoview.PhotoView  android:id="@+id/pv_show_image"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@android:color/white"  android:src="@drawable/image_default_rect" /> </RelativeLayout></RelativeLayout>

以上為本次學習內容,如有錯誤還望指正,謝謝!

文章中 Demo 已經上傳在 GitHub上,地址為ShowImageFromWebView,大家也可以通過本地下載

總結

以上就是這篇文章的全部內容了,希望本文的內容對各位Android開發者們能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 资阳市| 炎陵县| 宜春市| 昌都县| 沂源县| 崇义县| 辉南县| 宜兰县| 永福县| 河间市| 临颍县| 萨嘎县| 北川| 泗阳县| 确山县| 郁南县| 萍乡市| 曲水县| 宣汉县| 金寨县| 乌兰浩特市| 长治市| 徐水县| 平南县| 盈江县| 东辽县| 垫江县| 时尚| 灵台县| 建湖县| 惠安县| 土默特右旗| 渭南市| 榆林市| 邵东县| 秦安县| 麻城市| 新源县| 常德市| 遵化市| 绩溪县|