Пролить свет на вашу ситуацию: до сотовой связи, longPress в TextView даст всплывающее окно с опциями (например, «Выбрать слово», «Выбрать все» и «Добавить» в словарь »), в то время как NOT влияя на любой существующий ActionMode как при показе, так и при увольнении (путем нажатия). Так что это не проблема с предварительной сотой.
Больше света относительно HTC Sense: Sense НЕ ЧИТАЕТ TextView.setCustomSelectionActionModeCallback(), потому что Sense не использует ActionMode для функции выбора текста (и явно не волнует, делает ли остальная часть мира!). Таким образом, эта проблема имеет другой запах в этой ситуации (я не тестировал следующее решение под Sense, поэтому не уверен, как он будет себя вести).
Решение состоит в том, чтобы создать собственный пользовательский ActionMode.Callback для замены одного из них и применить его в setCustomSelectionActionModeCallback() любого текстового и/или EditText, которые вы хотите (хотя, только если устройство работает сотовым или большим). Передайте пользовательский интерфейс callTextSelectionCABDestroyed обратного вызова в свой пользовательский ActionMode.Callback, вызовите его в методе onDestroyActionMode.
Во-первых, создать интерфейс и реализовать его там, где вы хотите, чтобы справиться с воссоздание оригинального ActionMode (в качестве альтернативы вы можете использовать событие автобус с чем-то вроде Отто):
public interface YourCallbackInterface {
public void onTextSelectionCABDestroyed();
}
и создать новый класс :
public final class CustomTextSelectionActionModeCallback implements ActionMode.Callback {
WeakReference<YourCallbackinterface> mYourCallbackinterface;
public CustomTextSelectionActionModeCallback(YourCallbackinterface yourCallbackInterface) {
mYourCallbackinterface = new WeakReference<YourCallbackinterface>(yourCallbackInterface);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return true; //returning true will create the ActionMode
}
@Override
public void onDestroyActionMode(ActionMode mode) {
//this is the magic where we actually capture the destroy event for TextSelectionCAB and can subsequently do things like recreate the ActionMore that TextSelectionCAB greedily destroyed!
mYourCallbackinterface.get().onTextSelectionCABDestroyed();
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
}
И помните, чтобы избежать StackOverflowException когда воссоздания ActionMode от onDestroyActionMode года закона ionMode, postDelayed исполняемого в обработчике, как это я объясняю здесь: Reopen ActionMode (or CAB) after onDestroyActionMode is called
Наконец, если вы используете ActionBarSherlock, убедитесь, что ваш CustomTextSelectionActionModeCallback реализует android.view.ActionMode.Callback, а не com.actionbarsherlock.view.ActionMode .Перезвони.
Примечание: Я не играл с ActionBarCompat, поэтому не знаю, как это все действует. Если кто-то знает, пожалуйста, напишите как комментарий!
Спасибо за подробный ответ! Наконец, я решил изменить структуру приложения, чтобы избежать всей ситуации, потому что я не нашел надежного способа решить, был ли onDestroyActionMode вызван взаимодействием с пользователем или системой, чтобы открыть другой actionmode. Что-то простое, что было ужасно сложно, потому что у моего приложения сложная логика с десятками вложенных actionmodes ... Я все равно принимаю ваш ответ, потому что он показывает интересные функции actionmode. – rupps
Я думаю, что эти проблемы заставили многих избегать предательского каньона боли, который является ActionMode. Но решения есть сейчас. – straya