先來簡單說一下本文所要實現的功能:用戶在瀏覽網頁的時候,長按某一區域,識別若是是圖片,則彈出彈框,出現保存圖片的功能。同時識別圖片是不是二維碼,若是是則在彈框中追加識別二維碼功能。git
細節上:保存圖片的彈框要顯示在手指長按的位置;選擇圖片保存後,可讓用戶直接去相冊查看;選擇識別二維碼,判斷是是否是網址,是的話可讓用戶選擇複製或訪問,不然可讓用戶選擇複製或搜索。github
而後再來看一下效果圖:緩存
WebView.HitTestResult
DialogFragment
Glide
Zxing
繼承WebView
記錄觸摸位置:bash
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
touchX = (int) event.getRawX();
touchY = (int) event.getRawY();
return super.onInterceptTouchEvent(event);
}
複製代碼
彈框我選擇DialogFragment
而不是poupwindow
的緣由是poupwindow
的顯示一般須要依託另外一個View,並且在7.0以上有兼容問題。 判斷長按位置的內容類型是不是圖片:網絡
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: // 處理撥號
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: // 處理長按圖片的菜單項
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;
}
});
複製代碼
HitTestResult
是一個實體類,只記錄兩個信息:當選選擇內容的類型和內容的具體值。能夠看到經過WebView.HitTestResult
,咱們能夠得到除了圖片外的不少內容類型。固然這裏咱們只須要判斷是不是圖片就行了,而後將長按位置和url一塊兒回調給外層。在手指長按處顯示彈框,主要就是DialogFragment
顯示位置的設定了:app
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;//橫座標位置
lp.y = LocationY;//縱座標位置
lp.width = UIHelper.dip2px(100);
lp.dimAmount = 0.0f;//外層背景透明,默認變暗
lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//內部背景透明
}
}
}
複製代碼
利用Glide
下載圖片,Glide
自帶預加載和圖片緩存功能,不須要每次都從網絡中下載:ide
GlideApp.with(appContext).asFile().load(url).submit().get();
複製代碼
能夠在長按識別出圖片的時候就行預加載:優化
GlideApp.with(appContext).asBitmap().load(url).preload();
複製代碼
將圖片保存在相冊:ui
public static void displayToGallery(Context context, File photoFile) {
if (photoFile == null || !photoFile.exists()) {
return;
}
String photoPath = photoFile.getAbsolutePath();
String photoName = photoFile.getName();
// 把文件插入到系統圖庫
try {
ContentResolver contentResolver = context.getContentResolver();
MediaStore.Images.Media.insertImage(contentResolver, photoPath, photoName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 最後通知圖庫更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + photoPath)));
}
複製代碼
顯示彈框的同時還要判斷圖片是否包含二維碼,這部分就是Zxing
自帶的功能,因此代碼就不貼了。注意不該該等是Zxing
判斷是否是二維碼後再顯示彈框,由於這部分操做耗時可能比較長(見圖二)。應當在識別二維碼內容後再去更新彈框列表的內容。url
整體來講這個功能實現注意的地方仍是挺多的,好在都不復雜。固然本例還存在待優化的地方,以及實現更高級的功能,好比以圖搜圖,查看大圖功能,也能夠利用WebView.HitTestResult
對獲取到其餘類型的內容進行處理,限於篇幅就再也不展開了。 最後貼下本項目Github地址,對WebView
感興趣的能夠了解下: