Android WebView實(shí)現(xiàn)長(zhǎng)按保存圖片及長(zhǎng)按識(shí)別二維碼功能
先來(lái)簡(jiǎn)單說(shuō)一下本文所要實(shí)現(xiàn)的功能:用戶在瀏覽網(wǎng)頁(yè)的時(shí)候,長(zhǎng)按某一區(qū)域,識(shí)別如果是圖片,則彈出彈框,出現(xiàn)保存圖片的功能。同時(shí)識(shí)別圖片是否是二維碼,如果是則在彈框中追加識(shí)別二維碼功能。
細(xì)節(jié)上:保存圖片的彈框要顯示在手指長(zhǎng)按的位置;選擇圖片保存后,可以讓用戶直接去相冊(cè)查看;選擇識(shí)別二維碼,判斷是是不是網(wǎng)址,是的話可以讓用戶選擇復(fù)制或訪問(wèn),否則可以讓用戶選擇復(fù)制或搜索。
然后再來(lái)看一下效果圖:
保存圖片

save.gif
識(shí)別包含普通文字的二維碼:

text.gif
識(shí)別包含網(wǎng)址的二維碼:

code.gif
上述功能所用到的類和庫(kù):
- 獲得長(zhǎng)按內(nèi)容: WebView.HitTestResult
- 彈框列表: DialogFragment
- 圖片下載: Glide
- 二維碼識(shí)別: Zxing
實(shí)現(xiàn)要點(diǎn)
記錄長(zhǎng)按位置
繼承 WebView 記錄觸摸位置:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
touchX = (int) event.getRawX();
touchY = (int) event.getRawY();
return super.onInterceptTouchEvent(event);
}
彈框我選擇 DialogFragment 而不是 poupwindow 的原因是 poupwindow 的顯示通常需要依托另一個(gè)View,而且在7.0以上有兼容問(wèn)題。
判斷長(zhǎng)按位置的內(nèi)容類型是否是圖片:
獲取圖片信息
setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
WebView.HitTestResult result = getHitTestResult();
if (null == result)
return false;
int type = result.getType();
switch (type) {
case WebView.HitTestResult.EDIT_TEXT_TYPE: // 選中的文字類型
break;
case WebView.HitTestResult.PHONE_TYPE: // 處理?yè)芴?hào)
break;
case WebView.HitTestResult.EMAIL_TYPE: // 處理Email
break;
case WebView.HitTestResult.GEO_TYPE: // 地圖類型
break;
case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超鏈接
break;
case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: // 帶有鏈接的圖片類型
case WebView.HitTestResult.IMAGE_TYPE: // 處理長(zhǎng)按圖片的菜單項(xiàng)
String url = result.getExtra();
if (mOnSelectItemListener != null && url != null && URLUtil.isValidUrl(url)) mOnSelectItemListener.onSelected(touchX, touchY, result.getType(), url);
}
return true;
case WebView.HitTestResult.UNKNOWN_TYPE: //未知
break;
}
return false;
}
});
在手指長(zhǎng)按位置處彈出彈框
HitTestResult 是一個(gè)實(shí)體類,只記錄兩個(gè)信息:當(dāng)選選擇內(nèi)容的類型和內(nèi)容的具體值。可以看到通過(guò) WebView.HitTestResult ,我們可以獲得除了圖片外的很多內(nèi)容類型。當(dāng)然這里我們只需要判斷是否是圖片就好了,然后將長(zhǎng)按位置和url一起回調(diào)給外層。在手指長(zhǎng)按處顯示彈框,主要就是 DialogFragment 顯示位置的設(shè)定了:
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams lp = window.getAttributes();
window.setGravity(Gravity.LEFT | Gravity.TOP);
lp.x = LocationX;//橫坐標(biāo)位置
lp.y = LocationY;//縱坐標(biāo)位置
lp.width = UIHelper.dip2px(100);
lp.dimAmount = 0.0f;//外層背景透明,默認(rèn)變暗
lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//內(nèi)部背景透明
}
}
}
保存到相冊(cè)
利用 Glide 下載圖片, Glide 自帶預(yù)加載和圖片緩存功能,不需要每次都從網(wǎng)絡(luò)中下載:
GlideApp.with(appContext).asFile().load(url).submit().get();
可以在長(zhǎng)按識(shí)別出圖片的時(shí)候就行預(yù)加載:
GlideApp.with(appContext).asBitmap().load(url).preload();
將圖片保存在相冊(cè):
public static void displayToGallery(Context context, File photoFile) {
if (photoFile == null || !photoFile.exists()) {
return;
}
String photoPath = photoFile.getAbsolutePath();
String photoName = photoFile.getName();
// 把文件插入到系統(tǒng)圖庫(kù)
try {
ContentResolver contentResolver = context.getContentResolver();
MediaStore.Images.Media.insertImage(contentResolver, photoPath, photoName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 最后通知圖庫(kù)更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + photoPath)));
}
識(shí)別圖片中的二維碼
顯示彈框的同時(shí)還要判斷圖片是否包含二維碼,這部分就是 Zxing 自帶的功能,所以代碼就不貼了。注意不應(yīng)該等是 Zxing 判斷是不是二維碼后再顯示彈框,因?yàn)檫@部分操作耗時(shí)可能比較長(zhǎng)(見(jiàn)圖二)。應(yīng)當(dāng)在識(shí)別二維碼內(nèi)容后再去更新彈框列表的內(nèi)容。
總結(jié)
總體來(lái)說(shuō)這個(gè)功能實(shí)現(xiàn)注意的地方還是挺多的,好在都不復(fù)雜。當(dāng)然本例還存在待優(yōu)化的地方,以及實(shí)現(xiàn)更高級(jí)的功能,比如以圖搜圖,查看大圖功能,也可以利用 WebView.HitTestResult 對(duì)獲取到其他類型的內(nèi)容進(jìn)行處理,限于篇幅就不再展開(kāi)了。
最后貼下本項(xiàng)目github地址,對(duì) WebView 感興趣的可以了解下:
總結(jié)
以上所述是小編給大家介紹的Android WebView實(shí)現(xiàn)長(zhǎng)按保存圖片及長(zhǎng)按識(shí)別二維碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
用Android MenuInflater創(chuàng)建菜單項(xiàng)的方法步驟
本篇文章小編為大家介紹,用Android MenuInflater創(chuàng)建菜單項(xiàng)的方法步驟。需要的朋友參考下2013-04-04
Android 中ListView的Item點(diǎn)擊事件失效的快速解決方法
這篇文章主要介紹了Android 中ListView的Item點(diǎn)擊事件失效的快速解決方法的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android源碼學(xué)習(xí)之組合模式定義及應(yīng)用
將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性,需要了解的朋友可以參考下2013-01-01
Android?AIDL通信DeadObjectException解決方法示例
這篇文章主要為大家介紹了Android?AIDL通信DeadObjectException解決的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
一文了解Android?ViewModelScope?如何自動(dòng)取消協(xié)程
這篇文章主要介紹了一文了解Android?ViewModelScope?如何自動(dòng)取消協(xié)程,文章圍繞主題站展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07
去除arraylist容器中的相同的對(duì)象元素的方法
下面小編就為大家?guī)?lái)一篇去除arraylist容器中的相同的對(duì)象元素的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
Flutter 實(shí)現(xiàn)酷炫的3D效果示例代碼
這篇文章主要介紹了Flutter 實(shí)現(xiàn)酷炫的3D效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Android開(kāi)發(fā)之背景動(dòng)畫簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了Android開(kāi)發(fā)之背景動(dòng)畫簡(jiǎn)單實(shí)現(xiàn)方法,涉及Android背景動(dòng)畫簡(jiǎn)單設(shè)置與使用技巧,需要的朋友可以參考下2017-10-10

