普通网友 2024-03-07 11:37 采纳率: 30%
浏览 36

android webview自定义长按文本后弹出的菜单样式

一、需求描述:

基于android的webview实现如下长按文本后弹出的自定义菜单样式,要点包括:
1、全部使用自定义的按钮,按钮控件由上方图标+下方文案组成。
2、菜单背景框颜色、透明度、四个边角弧度可调整

``

二、当前实现效果:

和需求的差异: 1、菜单项的文字上方没有图标 2、菜单背景框不符合要求

三、当前实现方案:

参考https://blog.csdn.net/limonzet/article/details/102723688 这篇博客实现,在菜单样式上的总结实现要点如下:
1、继承webview类,重载startActionMode方法,

@Override
    public ActionMode startActionMode(ActionMode.Callback callback) {
        return super.startActionMode(buildCustomCallback(callback));
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
        return super.startActionMode(buildCustomCallback(callback), type);
    }

2、buildCustomCallback中重载Callback的onPrepareActionMode和onCreateActionMode方法,清理原来的默认菜单,add自己的菜单项目,通过Menu的add方法添加设置文本、setIcon设置图标

/**
     * 添加自定义菜单
     *
     * @param actionMode
     */
    private ActionMode addCustomMenu(ActionMode actionMode) {
        if (actionMode != null && mCustomMenuList != null) {

            Menu menu = actionMode.getMenu();
            menu.clear();
            int groupId = 0;
            //添加自定义选项
            int size = mCustomMenuList.size();
            for (int i = 0; i < size; i++) {
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(getContext().getPackageName(), ""));
                String title = mCustomMenuList.get(i);
                // 设置菜单文本、设置菜单图标
                menu.add(groupId, 0, 0, title).setIcon(R.drawable.copy).setIntent(intent);
            }
            mActionMode = actionMode;
        }
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-07 11:37
    关注

    引自免费微信小程序:皆我百晓生

    在Android中,为了自定义WebView长按文本后弹出的菜单样式,你需要遵循以下步骤:

    1. 继承并重载WebView类: 创建一个自定义的WebView子类,以便覆盖startActionMode()方法来创建自定义的ActionMode。
    public class CustomWebView extends WebView {
    
        private List<String> mCustomMenuList;
        private ActionMode mActionMode;
    
        public CustomWebView(Context context) {
            super(context);
            init();
        }
    
        public CustomWebView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init();
        }
    
        private void init() {
            // 初始化自定义菜单列表等数据
            // ...
        }
    
        @Override
        public ActionMode startActionMode(ActionMode.Callback callback) {
            return super.startActionMode(buildCustomCallback(callback));
        }
    
        @Override
        public ActionMode startActionMode(ActionMode.Callback callback, int type) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                return super.startActionMode(buildCustomCallback(callback), type);
            } else {
                return super.startActionMode(buildCustomCallback(callback));
            }
        }
    
        private ActionMode.Callback buildCustomCallback(ActionMode.Callback originalCallback) {
            return new ActionMode.Callback() {
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    // 清除默认菜单项
                    menu.clear();
    
                    // 设置菜单背景、透明度和圆角
                    // 这里假设你有一个自定义的布局文件用于菜单背景
                    View customView = LayoutInflater.from(getContext()).inflate(R.layout.custom_menu_layout, null);
                    mode.setCustomView(customView);
    
                    // 添加自定义菜单项
                    int groupId = 0;
                    for (String title : mCustomMenuList) {
                        Intent intent = new Intent(); // 实际使用时设置正确的Intent
                        MenuItem menuItem = menu.add(groupId, 0, 0, title);
                        menuItem.setIcon(R.drawable.your_icon); // 设置图标资源
                        // 如果需要可以进一步设置点击事件:menuItem.setOnMenuItemClickListener()
                        // 或者通过intent传递参数
                    }
    
                    // 返回true表示成功创建ActionMode
                    return true;
                }
    
                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                    // 可以在这里更新你的菜单项状态或内容
                    return false; // 返回false表示不需要更新
                }
    
                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                    // 处理菜单项点击事件
                    return false; // 返回true表示已处理该事件
                }
    
                @Override
                public void onDestroyActionMode(ActionMode mode) {
                    mActionMode = null;
                    // 执行清理工作
                    originalCallback.onDestroyActionMode(mode);
                }
            };
        }
    }
    
    1. 创建自定义菜单布局: 在res/layout/目录下创建一个名为custom_menu_layout.xml的布局文件,设计包含图片和文字的自定义菜单按钮样式。

    2. 应用自定义WebView: 在你的Activity或Fragment中使用自定义的CustomWebView替代原来的WebView。

    3. 填充自定义菜单项列表: 在init()方法中初始化mCustomMenuList,添加你想要显示的菜单项标题。

    请注意,上述代码示例仅展示了如何创建自定义的ActionMode回调,并未实现具体的自定义菜单样式。为了达到要求的样式(如背景颜色、透明度和边角弧度),你需要在onCreateActionMode()方法中为自定义的菜单布局设置相应的属性。例如,可以通过自定义LinearLayoutCardView作为菜单背景,并为其指定背景色、透明度和圆角属性。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月7日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见