Android 嵌套上下文操作栏

Android 嵌套上下文操作栏,android,webview,selection,contextual-action-bar,Android,Webview,Selection,Contextual Action Bar,我正在自定义WebView中创建自定义上下文操作栏(CAB) 我的要求是,从第一个驾驶室选择特定选项将打开第二个驾驶室。这是最终目标: 我已经做到了这一点,但选择不正确。我知道它看起来是正确的,但如果用户点击其他三个图标中的任何一个,则结果如下: 如果用户在按下四个初始图标中的任何一个后触摸所选内容,则应用程序会因空指针异常而崩溃 当用户在选择动作后触摸到延迟选择时,应用程序会尝试访问创建了带有图标的CAB的ActionMode(我们称之为firstActionMode)以使其无效/刷新

我正在自定义
WebView
中创建自定义上下文操作栏(CAB)

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

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

如果用户在按下四个初始图标中的任何一个后触摸所选内容,则应用程序会因空指针异常而崩溃

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


为了清除选择,我发现在
onDestroyActionMode(firstActionMode)
方法中调用
clearFocus()

private class CustomActionModeCallback extends ActionMode.Callback {
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        clearFocus();
    }
}
但是,在执行此操作时,当
secondActionMode
创建其CAB时,选择不会持续:

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


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

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

}


如何解决这个问题?非常感谢您的帮助。

我现在已经解决了这个问题;我想得太多了。解决方案不在
操作模式中,而是在菜单中

如果选择了荧光灯,则更改图标菜单,而不是为颜色菜单启动全新的
ActionMode
。保存对
onCreateActionMode
菜单
参数的引用,并设置某种类型的标志;我用的是布尔值

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