Вложенные контекстные панели действий

Я создаю пользовательские контекстные панели действий (CAB) в рамках пользовательского 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 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();
        }
    }

}


Как это можно исправить? Любая помощь приветствуется.

1 ответ

Решение

Теперь я решил эту проблему; Я думал над этим. Решение лежит не в ActionMode, но в меню.

Вместо того, чтобы начинать совершенно новый ActionMode для цветного меню измените значок меню, если выбран маркер. Сохранить ссылку на Menu параметр в 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 учебный класс; это ничего не стоит. Опять же, путь слишком продуман.:П

Другие вопросы по тегам