如果想定制Android 长按网页选中文字的弹出菜单;可以使用下面方法。
在Android WebView中定制长按网页选择文字的菜单,需要使用到Android的ActionMode和ActionMode.Callback。以下是一个基本的示例,展示了如何通过重写WebView的startActionMode方法来实现自定义的选择菜单:
创建一个自定义的WebView类,重写startActionMode方法。
package acr.browser.lightning;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import androidx.annotation.RequiresApi;
import acr.browser.lightning.utils.ComUtils;
public class CustomWebView extends WebView {
public CustomWebView(Context context) {
super(context);
}
public CustomWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public ActionMode startActionMode(ActionMode.Callback callback, int type) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActionMode.Callback wrappedCallback = new CustomActionModeCallback(callback);
return super.startActionMode(wrappedCallback, type);
} else {
return super.startActionMode(callback, type);
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private class CustomActionModeCallback extends ActionMode.Callback2 {
private final ActionMode.Callback originalCallback;
@Override
public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
if (originalCallback instanceof ActionMode.Callback2) {
((ActionMode.Callback2) originalCallback).onGetContentRect(mode, view, outRect);
}
}
public CustomActionModeCallback(ActionMode.Callback originalCallback) {
this.originalCallback = originalCallback;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 自定义菜单可以用这下方法
// menu.clear();
// menu.add(0, Menu.FIRST, 0, "自定义项1");
// return true;
// 返回false表示不创建任何菜单项,返回true表示接受原始菜单项
return originalCallback.onCreateActionMode(mode, menu);
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return originalCallback.onPrepareActionMode(mode, menu);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.i("TAG", "onActionItemClicked: item id:"
+ item.getItemId() + "; " + item.getTitle()+"; "
+ComUtils.getContext().getResources().getResourceEntryName(item.getItemId())
+"; "+ComUtils.getContext().getResources().getResourcePackageName(item.getItemId()));
if (item.getItemId() == ComUtils.getContext().getResources().getIdentifier("select_action_menu_share","id", "com.google.android.webview")) {
ComUtils.showMsg("分享文字");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
evaluateJavascript("(function(){return window.getSelection().toString();})()",
value -> Log.i("TAG", "onReceiveValue: html:"+ value.substring(1,value.length()-1)));
}
mode.finish();
return true;
}
return originalCallback.onActionItemClicked(mode, item);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
originalCallback.onDestroyActionMode(mode);
}
}
// 解码JSON字符串并去除引号
private static String unescapeJavaString(String st) {
StringBuilder sb = new StringBuilder(st.length());
for (int i = 1; i < st.length() - 1; i++) {
char ch = st.charAt(i);
if (ch == '\\' && i < st.length() - 1) {
char nextChar = st.charAt(i + 1);
if (nextChar == 'u') {
// 读取unicode字符
sb.append((char) Integer.parseInt(st.substring(i + 2, i + 6), 16));
i += 5;
} else {
// 对于其他转义字符,直接添加它们的字面值
sb.append(nextChar);
i++;
}
} else {
sb.append(ch);
}
}
return sb.toString();
}
}