使用的WebView文本选择自定义上下文操作栏 [英] Use a custom contextual action bar for WebView text selection

查看:785
本文介绍了使用的WebView文本选择自定义上下文操作栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用从谷歌本指南和的this教程制作自己的上下文行动吧。

I have used this guide from Google and this tutorial to produce my own contextual action bar.

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;
    }
};

本菜单的设计,当用户选择的文本出现,因此它会覆盖本机复制/粘贴菜单。现在,我得到了我的问题。

This menu is designed to appear when the user selects text, so it overrides the native copy/paste menu. Now I get to my issue.

由于我重写功能文本选择,我还添加了一个 LongClickListener 的WebView 和实施 onLongClick(视图v)的方法,所以我可以检测用户进行选择。

Because I am overriding functions for text selection, I also added a LongClickListener to a WebView and implemented the onLongClick(View v) method so I can detect when users make the selection.

    myWebView.setOnLongClickListener(new View.OnLongClickListener() {

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

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

当我长按,我看到我的自定义菜单出现,但没有文字被高亮显示
我需要的文本选择功能;没有它,我的菜单是没有意义的。

When I long click, I see my custom menu appear, but no text is highlighted.
I need to have the text selection functionality; without it, my menu is pointless.

我如何重写 onLongClick(视图v),但保持搭载Android提供的文本选择?
如果这是不可能的,我可以调用 startActionMode(mActionModeCallback)其他地方,这样的文字将被选择为正常的,但我的自定义菜单也将出现?
如果这些都不是可能的...帮助。

How do I override onLongClick(View v), but maintain the text selection provided by Android?
If that is not possible, can I make the call to startActionMode(mActionModeCallback) somewhere else so that text will be selected as normal, but my custom menu will also appear?
If neither of those are possible... help.

推荐答案

还有一个更简单的方法!请参阅下面的更新:D


为了完整起见,这里是我如何解决了这一问题:

THERE IS AN EASIER WAY! See update below :D


For the sake of completeness, here is how I fixed the problem:

我跟着建议按照这个答案,多一点的调整,以更好地匹配重写code:

I followed the suggestion according to this answer, with a little more tweaking to more closely match the overridden code:

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);
    }
}

从本质上讲,这迫使你自定义的CAB出现,而不是Android的CAB。现在,您需要修改您的回调,这样的文本高亮显示会消失随着CAB:

Essentially, this forces your customized CAB to appear instead of the Android CAB. Now you have to modify your callback so that the text highlight will go away along with the 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;
        }
    }
}

这是所有有给它。请注意,只要您使用 MyWebView 的覆盖 startActionMode 有没有办法让本地CAB(复制/粘贴菜单,在web视图的情况下)。这可能是可以实现的这类行为,但不是这个code的工作方式。


更新:有一个更简单的方法来做到这一点!上述解决方案的效果很​​好,但在这里是一种替代,更简单的方法。

That's all there is to it. Be aware that as long as you are using MyWebView with the overridden startActionMode there is NO WAY to get the native CAB (the copy/paste menu, in the case of a WebView). It may be possible to implement that sort of behavior, but that is not the way this code works.


UPDATE: There is a much easier way to do this! The above solution works well, but here is an alternative, easier way.

该解决方案提供了较少的控制 ActionMode ,但它需要少得多的code比上面的解决方案。

This solution provides less control over the ActionMode, but it requires far less code than the above solution.

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);
    }
}

下面是一个例子菜单,让您开始:

Here is an example Menu to get you started:

<!-- 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 生命周期关心自己。

That's it! You're done! Now your custom menu will show up, you don't have to worry about the selection, and you barely have to concern yourself with the ActionMode lifecycle.

本作品几乎完美无缺了的WebView 占据其整个父活动。我不知道如何将工作,如果有多个查看是你活动中的一次。它可能会需要在这种情况下,一些调整。

This works nearly flawlessly with a WebView that occupies its entire parent Activity. I am not sure how well it will work if there are multiple Views within your Activity at one time. It will likely require some tweaking in that case.

这篇关于使用的WebView文本选择自定义上下文操作栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆