0

我正在自定义的WebView.

我的要求是从第一个 CAB 中选择一个特定选项将打开第二个 CAB。这是最终目标:

当用户进入选择模式时,会出现这个 CAB。 当他们点击荧光笔时,会出现第二个 CAB。

我已经做到了,但选择无法正常工作。我知道它看起来是正确的,但是如果用户点击其他三个图标中的任何一个,结果如下:

点击其他图标。 当不需要时,选择会挂起。

如果用户在按下四个初始图标中的任何一个后触摸选择,则应用程序由于空指针异常而崩溃。

当用户在选择操作后触摸延迟选择时,应用程序会尝试访问ActionMode(我们称之为firstActionMode)创建带有图标的 CAB 以使其无效/刷新。但是,firstActionMode在创建带有颜色的 CAB 时被破坏,(调用它secondActionMode)导致空指针异常。


为了清除选择,我发现clearFocus()onDestroyActionMode(firstActionMode)方法内调用可以很好地完成工作。

private class CustomActionModeCallback extends ActionMode.Callback {
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        clearFocus();
    }
}

secondActionMode但是,当实现这一点时,在创建其 CAB时选择不会持续存在:

和以前一样,但是... 单击任何图标时选择消失。

从这一点选择颜色实际上会产生所需的功能。然而,虽然这“有效”,但它(最不幸的是)不符合我的要求。当显示由创建的 CAB 时,我需要选择保持可见和功能secondActionMode


这是我的自定义类 ( WebView) 及其嵌套ActionMode的代码

public class CustomWebView extends WebView {

    private ActionMode.Callback mActionModeCallback;

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

    private class CustomActionModeCallback implements 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.first_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) {
            // This method is called when the handlebars are moved.
            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.copy:
                // Do stuff
                break;
            case R.id.bookmark:
                // Do stuff
                break;

            case R.id.highlight:
                startActionMode(new HighlightActionModeCallback());
                break;

            case R.id.note:
                // Do stuff
                break;
            default:
                return false;
            }

            mode.finish(); // Action picked, so close the CAB
            return true;
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            clearFocus(); // This is commented in the first four screens.
        }
    }

    private class HighlightActionModeCallback implements 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.highlight_colors, 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) {
            // This method is called when the handlebars are moved.
            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) {
            mode.finish(); // Action picked, so close the CAB
            return true;
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            // Remove the selection highlight and handles.
            clearFocus();
        }
    }

}


如何解决这个问题?任何和所有的帮助表示赞赏。

4

1 回答 1

0

我现在已经解决了这个问题;我想多了。解决方案不在菜单中ActionMode,而是在菜单中。

如果选择了荧光笔,请更改图标菜单ActionMode,而不是为颜色菜单启动一个全新的菜单。保存对参数的引用并设置某种标志;我正在使用布尔值。MenuonCreateActionMode

private class CustomActionModeCallback implements ActionMode.Callback {

    private boolean highlighterClicked = false;
    private Menu mMenu;

    // Called when the action mode is created; startActionMode() was called
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mMenu = menu;
        // Inflate a menu resource providing context menu items
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.first_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) {
        // This method is called when the handlebars are moved.
        MenuInflater inflater = mode.getMenuInflater();
        if (highlighterClicked) {
            menu.clear(); // Remove the four icons
            inflater.inflate(R.menu.highlight_colors, menu); // Show the colors
            return true; // This time we did stuff, so return true
        }
        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) {

        highlighterClicked = false;
        switch (item.getItemId()) {
        case R.id.copy:
            // Do stuff
            break;
        case R.id.bookmark:
            // Do stuff
            break;

        case R.id.highlight:
            highlighterClicked = true;
            onPrepareActionMode(mode, mMenu);
            return true;

        case R.id.note:
            // Do stuff
            break;
        default:
            // Any of the colors were picked
            return true;
        }

        mode.finish(); // Action picked, so close the CAB
        return true;
    }

    // Called when the user exits the action mode
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        clearFocus();
    }
}

选择突出显示和手柄保持活动和功能,并且颜色选项按预期工作。

删除第二ActionModeCallback类是安全的;这是毫无价值的。再次,多虑了。:P

于 2014-04-16T19:59:04.587 回答