当前位置: 首页 > 知识库问答 >
问题:

为WebView文本选择使用自定义上下文操作栏

陆雅志
2023-03-14
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

    // Called when the action mode is created; startActionMode() was called
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate a menu resource providing context menu items
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.annotation_menu, menu);
        return true;
    }

    // Called each time the action mode is shown.
    // Always called after onCreateActionMode, but
    // may be called multiple times if the mode is invalidated.
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false; // Return false if nothing is done
    }

    // Called when the user selects a contextual menu item
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.custom_button:
                // do some stuff
                break;
            case R.id.custom_button2:
                // do some other stuff
                break;
            default:
                // This essentially acts as a catch statement
                // If none of the other cases are true, return false
                // because the action was not handled
                return false;
        }
        finish(); // An action was handled, so close the CAB
        return true;
    }

    // Called when the user exits the action mode
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }
};
    myWebView.setOnLongClickListener(new View.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            if (mActionMode != null) {
                return false;
            }

            mActionMode = startActionMode(mActionModeCallback);
            v.setSelected(true);
            return true;
        }
    });

如何覆盖onlongclick(View v),但同时保持Android提供的文本选择?
如果这是不可能的,我是否可以在其他地方调用StartActionMode(mActionModeCallback),这样文本将被正常选择,但我的自定义菜单也将出现?
如果这两个选项都不可能...救命啊。

共有1个答案

叶修永
2023-03-14

有更简单的方法!请参阅以下更新:d

我根据这个答案遵循了建议,并进行了更多的调整,使其更接近于重写的代码:

public class MyWebView extends WebView {

    private ActionMode mActionMode;
    private mActionMode.Callback mActionModeCallback;

    @Override
    public ActionMode startActionMode(Callback callback) {
        ViewParent parent = getParent();
        if (parent == null) {
            return null;
        }
        mActionModeCallback = new CustomActionModeCallback();
        return parent.startActionModeForChild(this, mActionModeCallback);
    }
}

本质上,这迫使您的定制驾驶室出现,而不是Android驾驶室。现在您必须修改回调,以便文本高亮显示将与cab一起消失:

public class MyWebView extends WebView {
    ...
    private class CustomActionModeCallback implements ActionMode.Callback {
        ...
        // Everything up to this point is the same as in the question

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            clearFocus(); // This is the new code to remove the text highlight
             mActionMode = null;
        }
    }
}
public class MyActivity extends Activity {

    private ActionMode mActionMode = null;

    @Override
    public void onActionModeStarted(ActionMode mode) {
        if (mActionMode == null) {
            mActionMode = mode;
            Menu menu = mode.getMenu();
            // Remove the default menu items (select all, copy, paste, search)
            menu.clear();

            // If you want to keep any of the defaults,
            // remove the items you don't want individually:
            // menu.removeItem(android.R.id.[id_of_item_to_remove])

            // Inflate your own menu items
            mode.getMenuInflater().inflate(R.menu.my_custom_menu, menu);
        }

        super.onActionModeStarted(mode);
    }

    // This method is what you should set as your item's onClick
    // <item android:onClick="onContextualMenuItemClicked" />
    public void onContextualMenuItemClicked(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.example_item_1:
                // do some stuff
                break;
            case R.id.example_item_2:
                // do some different stuff
                break;
            default:
                // ...
                break;
        }

        // This will likely always be true, but check it anyway, just in case
        if (mActionMode != null) {
            mActionMode.finish();
        }
    }

    @Override
    public void onActionModeFinished(ActionMode mode) {
        mActionMode = null;
        super.onActionModeFinished(mode);
    }
}

下面是一个示例菜单,您可以开始:

<!-- my_custom_menu.xml -->
<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/example_item_1"
        android:icon="@drawable/ic_menu_example_1"
        android:showAsAction="always"
        android:onClick="onContextualMenuItemClicked"
        android:title="@string/example_1">
    </item>

    <item
        android:id="@+id/example_item_2"
        android:icon="@drawable/ic_menu_example_2"
        android:showAsAction="ifRoom"
        android:onClick="onContextualMenuItemClicked"
        android:title="@string/example_2">
    </item>

</menu>

就是这样!你完蛋了!现在您的自定义菜单将显示出来,您不必担心选择,也不必关心actionmode生命周期。

对于占用其整个父活动WebView来说,这几乎是完美无缺的。如果您的活动中同时存在多个视图,我不确定它的工作效果如何。在这种情况下,可能需要做一些调整。

 类似资料:
  • 我在styles.xml中使用一个主题,如下所示: 我在AndroidManifest.xml中将其声明为Android:theme: 问题在下图中以红色突出显示。 感谢所有的答案!

  • 所以我有了正确的实现,它被调用得很好,但是没有方法..所以,如果我不能传递任何要做出决定的东西,它如何做出决定呢? 有一个,但我无权访问它? 我需要有多个上下文(显然加载了不同的配置),在运行时根据自己的逻辑从中进行选择。 我已经找到了一个简单地创建LoggerContexts并配置它们的解决方案,但我只是不明白这种替代机制的意义所在。

  • 问题内容: 可以说我的网页中包含以下代码段: >这是一些文字> 我希望WebDriver在此文本中选择“一些”,就像用户选择它一样。我应该怎么做?我知道如何获取>元素: println打印“这是一些文本”。 我尝试将键发送到该元素,该键曾经可以工作(在selenium 2.0b中),但是我现在正在使用selenium 2.6.0,但它停止了工作: 有人有想法吗?我正在使用FirefoxDriver

  • 我在我的项目中实现了自定义actionBar。它有两个Textview,我想用编程的方式改变文本,怎么做。我尝试了以下代码,但在我的操作栏中没有任何变化

  • 宏碁Iconia a500平板电脑:10英寸:Android OS-3.0 宏碁Iconia a500平板电脑:10英寸:Android OS-3.2 三星Galaxy标签:10英寸:Android OS-4.0 三星Galaxy标签:7英寸:Android OS-4.0 模拟器:Skin-WVGA800:Android OS-4.1.2 不在以下设备上工作: 三星Galaxy标签:10英寸:An