Android 12 下WebView选中文本高亮时自定义菜单项不显示问题
Android 12 WebView自定义文本选择菜单不生效修复方案
问题根因
Android 12(API Level 31)对原生WebView的文本选择逻辑做了变更,原有在onActionModeStarted中修改菜单的逻辑执行后,WebView内部会再次触发菜单重绘,覆盖掉你添加的自定义菜单项,所以会出现日志能打印出自定义菜单项、但界面只显示系统默认菜单的现象。
修复方案
方案1:替换WebView的默认选择回调(推荐,稳定性最高)
不需要在Activity的onActionModeStarted中处理,直接给WebView设置自定义的选择ActionMode回调,示例代码如下:
webView.setCustomSelectionActionModeCallback(new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // 清空默认菜单 menu.clear(); // 添加自定义菜单项 menu.add(0, ReaderConstants.KEY_HIGHLIGHT, 0, " " + getString(R.string.native_reader_activity_popup_highlight)) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); menu.add(0, ReaderConstants.KEY_NOTES, 0, " " + getString(R.string.native_reader_activity_popup_note)) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // 这里返回false会禁止系统更新菜单,避免自定义项被覆盖 return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // 处理自定义菜单项的点击逻辑 switch (item.getItemId()) { case ReaderConstants.KEY_HIGHLIGHT: // 处理高亮逻辑 mode.finish(); return true; case ReaderConstants.KEY_NOTES: // 处理笔记逻辑 mode.finish(); return true; } return false; } @Override public void onDestroyActionMode(ActionMode mode) { } });
方案2:延迟修改原有逻辑的菜单(兜底兼容方案)
如果不想改动原有代码结构,可以在onActionModeStarted添加完自定义菜单后,给WebView post一个延迟任务重新设置菜单,延迟时间建议设为50-100ms,适配WebView的内部重绘逻辑。
注意事项
- Android 12及以上版本禁止在ActionMode回调中重复调用
super相关的菜单处理方法,避免触发系统默认菜单覆盖 - 自定义菜单项的
order参数建议设置为小于1的数值,保证自定义项排在系统默认项前面
内容的提问来源于stack exchange,提问作者Akshat sharma
相关产品推荐
相关产品推荐

