x5 WebView自定义长按菜单¶
想要自定义长按菜单,重写startActionMode
的做法在x5 WebView上并不起作用。
x5 WebView底层并没有走startActionMode
方法。我们需要换个思路。
这里用menu来自定义菜单。
自定义menu¶
先新建一个menu文件web_view_x5_menu1.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/copy"
android:title="Copy"
app:showAsAction="always" />
<item
android:id="@+id/action1"
android:title="action1"
app:showAsAction="always" />
</menu>
操作x5 WebView¶
新建一个类继承ProxyWebViewClientExtension,实现onShowLongClickPopupMenu
方法。
长按弹出菜单时,会走这个方法。
新建ISelectionInterfaceX类实现ISelectionInterface接口。
updateHelperWidget
方法里对菜单进行操作。把默认的菜单换成我们的自定义菜单。
private class ProxyWebViewClientExtensionX extends ProxyWebViewClientExtension {
private WebView webView;
private Handler handler = new Handler(Looper.getMainLooper());
public ProxyWebViewClientExtensionX(WebView webView) {
this.webView = webView;
}
@Override
public boolean onShowLongClickPopupMenu() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
webView.getX5WebViewExtension().enterSelectionMode(false);
}
}, 30);
return true;
}
}
private class ISelectionInterfaceX implements ISelectionInterface {
boolean isInActionMode = false;
ActionMode actionMode;
private WebView webView;
View actionView;
private Handler handler = new Handler(Looper.getMainLooper());
public ISelectionInterfaceX(WebView webView) {
this.webView = webView;
}
@Override
public void onSelectionChange(Rect rect, Rect rect1, int i, int i1, short i2) {
Log.d(TAG, "onSelectionChange: ");
}
@Override
public void onSelectionBegin(Rect rect, Rect rect1, int i, int i1, short i2) {
Log.d(TAG, "onSelectionBegin: ");
}
@Override
public void onSelectionBeginFailed(int i, int i1) {
Log.d(TAG, "onSelectionBeginFailed: ");
}
@Override
public void onSelectionDone(Rect rect, boolean b) {
Log.d(TAG, "onSelectionDone: ");
}
@Override
public void hideSelectionView() {
System.out.println();
if (actionView != null) {
webView.removeViewInLayout(actionView);
actionView = null;
}
if (actionMode != null) {
actionMode.finish();
actionMode = null;
}
}
@Override
public void onSelectCancel() {
Log.d(TAG, "onSelectCancel: ");
}
@Override
public void updateHelperWidget(final Rect rect, final Rect rect1) {
System.out.println();
handler.postDelayed(new Runnable() {
@Override
public void run() {
final ActionMode.Callback callback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.web_view_x5_menu1, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode,
MenuItem item) {
final IX5WebViewExtension webViewExtension = webView.getX5WebViewExtension();
String selectionText = "";
if (webViewExtension != null) {
selectionText = webViewExtension.getSelectionText();
}
boolean leaveSelection = true;
switch (item.getItemId()) {
case R.id.copy:
Toast.makeText(WebViewX5ClickAct.this, selectionText, Toast.LENGTH_SHORT).show();
break;
case R.id.action1:
Toast.makeText(WebViewX5ClickAct.this, "(action1) " + selectionText, Toast.LENGTH_SHORT).show();
break;
}
final boolean finalLeaveSelection = leaveSelection;
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (finalLeaveSelection && webViewExtension != null) {
webViewExtension.leaveSelectionMode();
}
}
}, 30);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
isInActionMode = false;
}
};
Context context = webView.getContext();
// 生成actionView,并通过它启动ActionMode,解决定位问题
// actionView的大小和位置,大致和Selection相同,直接将其add到WebView中
if (actionView != null) {
webView.removeViewInLayout(actionView);
}
actionView = new View(context);
actionView.setBackgroundColor(0x33FF00FF);// 方便调试
int width = rect1.right - rect.left;
int height = rect1.bottom - rect.top;
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width <= 0 ? 10 : width, height <= 0 ? 10 : height);
lp.leftMargin = rect.left;
lp.topMargin = rect.top;
webView.addView(actionView, lp);
// 需要延迟startActionMode,给布局actionView的时间
actionView.post(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
actionMode = actionView.startActionMode(callback, ActionMode.TYPE_FLOATING);
} else {
actionMode = actionView.startActionMode(callback);
}
}
});
}
}, 0);
}
@Override
public void setText(String s, boolean b) {
Log.d(TAG, "setText: ");
}
@Override
public String getText() {
Log.d(TAG, "getText: ");
return null;
}
@Override
public void onRetrieveFingerSearchContextResponse(String s, String s1, int i) {
Log.d(TAG, "onRetrieveFingerSearchContextResponse: ");
}
}
对webView进行设置
mX5WebView2.getSettings().setJavaScriptEnabled(true);
IX5WebViewExtension x5WebViewExtension = mX5WebView2.getX5WebViewExtension();
if (x5WebViewExtension != null) {
x5WebViewExtension.enterSelectionMode(true);
x5WebViewExtension.setWebViewClientExtension(new ProxyWebViewClientExtensionX(mX5WebView2));
x5WebViewExtension.setSelectListener(new ISelectionInterfaceX(mX5WebView2));
} else {
Log.e(TAG, "x5还没有准备好 - x5WebViewExtension is null.");
}
mX5WebView2.loadDataWithBaseURL(null, mH1, "text/html", "UTF-8", null);
x5内核加载问题¶
手机上并不一定会有x5浏览器内核。 没有x5内核,不进行设置。长按菜单还是默认的。
App如何首次加载x5内核? App 在启动后(例如在 Application 的 onCreate 中)立刻调用 QbSdk 的预加载接口 initX5Environment ,可参考接入示例或API文档(https://x5.tencent.com/tbs/sdk.html). 需要注意的是: 当本地没有宿主x5内核可用,此时需要在wifi条件下下载x5内核(23M左右,耗时90秒左右),如果在此之前打开webview可能导致无内核可用而使用系统内核的情况
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~