編輯:關於Android編程
效果圖(1.3M)
一、前言
** 戳這裡可以去DEMO,來吧 **
相信剛接觸android不久的同志們,在面對產品提出的 :
“自定義WebView頁面中,長按文本的彈出選項、點擊選擇後,分享、轉發、收藏選擇文本”
這樣的需求時,第一反應大部分是:這是系統行為,如果實現需要在web端實現。
但是web端實現的局限性太大,曾經也有過監聽系統粘貼板,在用戶點擊復制的時候實現其他的邏輯,但是這樣用戶體驗不好,所以自定義WebView中長按的彈出菜單,並在點擊時返回選中文本的小控件閃亮登場┏ (^ω^)=。
二、自定義長按彈出菜單
這一步實現其實很簡單,首先創建一個CustomActionWebView繼承系統WebView,然後重寫下面兩個方法。
這兩個方法會在用戶長按選擇web文本時,在彈出菜單前被調用。它們之間的區別在於,第一個方法的菜單彈出方式,指定了默認的type。我們並不關心彈出的item類型是什麼,我們只需要攔截下來ActionMode,然後返回我們自己的自定義ActionMode即可。
@Override public ActionMode startActionMode(ActionMode.Callback callback) { ActionMode actionMode = super.startActionMode(callback); return resolveActionMode(actionMode); } @Override public ActionMode startActionMode(ActionMode.Callback callback, int type) ActionMode actionMode = super.startActionMode(callback, type); return resolveActionMode(actionMode); }
這裡我們所做的事是:
1、把原本的actionMode對象保存到mActionMode中。
2、清空原本actionMode中的MenuItem。
3、添加我們自定義的item到actionMode中。
4、重定義每個menuItem的點擊事件。
5、在點擊事件中通過執行js,獲取選中文本。
6、通過上面保存的 mActionMode,釋放彈出菜單(不釋放會內存洩漏)。
7、返回新填充的actionMode給系統。
/** * 處理item,處理點擊 * @param actionMode */ private ActionMode resolveActionMode(ActionMode actionMode) { if (actionMode != null) { final Menu menu = actionMode.getMenu(); mActionMode = actionMode; menu.clear(); for (int i = 0; i < mActionList.size(); i++) { menu.add(mActionList.get(i)); } for (int i = 0; i < menu.size(); i++) { MenuItem menuItem = menu.getItem(i); menuItem.setOnMenuItemClickListener(new Item.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { getSelectedData((String) item.getTitle()); releaseAction(); return true; } }); } } mActionMode = actionMode; return actionMode; }
實現效果
三、獲取選中文本
光自定義菜單,拿不到選中文本也沒意義,那麼如何獲取選中文本呢?這裡如果不轉個彎,還真會在南牆在撞死( ̄^ ̄)ゞ,所以,我們偉大的js就出現了。
首先,我們自定義一個接口,用於監聽js方法,其中@JavascriptInterface是關鍵的所在, 在callback中獲取js端返回的數據。
然後將這個接口,在CustomActionWebView中add進去(一般是在初始化和頁面加載完成時都add一次),並指定js端調用的接口名稱為“ JSInterface”。(ps:別忘了開始webview的js允許哦。)
public void linkJSInterface() { addJavascriptInterface(new ActionSelectInterface(this), "JSInterface"); } ··· /** * js選中的回調接口 */ private class ActionSelectInterface { CustomActionWebView mContext; ActionSelectInterface(CustomActionWebView c) { mContext = c; } @JavascriptInterface public void callback(final String value, final String title) { if(mActionSelectListener != null) { mActionSelectListener.onClick(title, value); } } }
最後在點擊時,通過執行js來獲取web中選中的文本。在上面自定義菜單中第5項,點擊menu時,執行下方js代碼,便可以把選中的item和文本,回調到上面的接口中的callback。
熟悉js的小伙伴已經看出來吧:
其實就是定義了一個js的function,然後在webview中執行這個方法。
定義的這個名為function getSelectedText()的js方法,有兩個變量:txt和title。
title是從原生中傳入的item名字,txt是通過window去獲取web中選中的文本。
最後回到上面我們注冊的js方法名JSInterface,通過它的callback方法,將文本和name返回到原生代碼callback中。
根據版本不同,執行js方法的接口也不一樣。
/** * 點擊的時候,獲取網頁中選擇的文本,回掉到原生中的js接口 * @param title 傳入點擊的item文本,一起通過js返回給原生接口 */ private void getSelectedData(String title) { String js = "(function getSelectedText() {" + "var txt;" + "var title = \"" + title + "\";" + "if (window.getSelection) {" + "txt = window.getSelection().toString();" + "} else if (window.document.getSelection) {" + "txt = window.document.getSelection().toString();" + "} else if (window.document.selection) {" + "txt = window.document.selection.createRange().text;" + "}" + "JSInterface.callback(txt,title);" + "})()"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { evaluateJavascript("javascript:" + js, null); } else { loadUrl("javascript:" + js); } }
四、最後
既然自定義item實現了,點擊和選擇文本返回也實現了,在callback中,你就可以愉悅的收藏,或者分享你所選中的文本啦(◐‿◑),操作一氣呵成,有沒有被驚艷到呢?
如果感興趣的,可以下載demo看下,同時CustomActionWebView也封裝好了遠程依賴,歡迎使用。
https://github.com/CarGuo/CustomActionWebView
以上所述是小編給大家介紹的Android WebView自定義長按選擇實現收藏/分享選中文本功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
本文實例講述了Android編程實現調用系統圖庫與裁剪圖片功能。分享給大家供大家參考,具體如下:在Android開發中,調用系統圖庫和裁剪照片是很常見的需求。相對於自己實
現在側滑菜單使用很多,大都是通過SlidingMenu實現。現在也可以通過DrawerLayout創建抽屜布局 activity_main.xml
Palette非常好用,也非常好玩。 Palette的作用是從圖像中提取突出的顏色,這樣我們可以根據提取到的色值把它賦給Toolbar,標題,狀態欄等,可以使我們的整個界
要求 Tab 標簽可以橫向滾動,標簽可選擇,並且在選擇的時候有標線下劃線。 分析 可繼承HorizontalScrollView 實現,然後裡面標簽ITem可可以是Tex