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