Причина:
Я прослеживаю причину ошибки вплоть до автокоррекции правописания на некоторых телефонах (Moto Droid Razr и нескольких других Moto Phones) и некоторых Android Rom (например, CM7 и CM7.1 ROMS). Если в тексте содержится слово, написанное неправильно, и текстовый курсор находится в тексте или рядом с ним, ОС Android попытается автоматически вызвать клавиатуру и попытаться предложить правильное написание.
На большинстве устройств окно автокоррекции отображается только в виде одного отрезка над клавиатурой. Однако на некоторых пользовательских ПЗУ (с CM7, который, как мне кажется, часто случается) и на некоторых устройствах (Droid Razr) есть дополнительное раскрывающееся поле выбора:
Посмотрите на это изображение того, как выглядит автокоррекция всплывающего окна (извините, недостаточно репов для вставки изображения)
Я очень подозреваю, что выпадающий список автокоррекции также реализован в виде всплывающего окна, и он пытается использовать текущее всплывающее окно (то, которое содержит EditText со словом неправильного написания) в качестве корневого представления, и пытаясь получить windowToken из корневого представления.
Так как само всплывающее окно не является традиционным представлением, я предполагаю, что оно не может дать правильное окно, взятое другим представлениям, которые их запрашивают, что приводит к ошибке.
Решения:
1) Самый простой способ обойти эту проблему - использовать диалог вместо всплывающих окон. Их API действительно похожи, и в моих случаях довольно просто заменить PopupWindow с помощью Dialog.
Например:
Старый код:
LayoutInflater inflater = (LayoutInflater) parentActivity.getLayoutInflater();
View mainView = parentActivity.findViewById(R.id.main_calendar_fragment);
updateEventPopupWindow = new PopupWindow(inflater.inflate(
R.layout.add_event_fragment, null, false), metrics.widthPixels, metrics.heightPixels, true);
updateEventPopupWindow.setBackgroundDrawable(new BitmapDrawable());
updateEventPopupWindow.showAtLocation(mainView, Gravity.CENTER, 0, 0);
Новый код:
LayoutInflater inflater = (LayoutInflater) parentActivity.getLayoutInflater();
View mainView = parentActivity.findViewById(R.id.main_calendar_fragment);
updateEventDialog = new Dialog(parentActivity, android.R.style.Theme_NoTitleBar);
updateEventDialog.setContentView(inflater.inflate(R.layout.add_event_fragment, (ViewGroup) mainView, false));
updateEventDialog.show();
2) Второй подход сложнее, но может быть целесообразным, если замена PopupWindow на Dialog невозможна, это использование пользовательских фрагментов вместо PopupWindows. Есть много хороших фрагментов учебников , поэтому я не стану рассказывать, как это сделать, в этом посте.
3) В качестве последнего средства, как и несколько упомянутых выше плакатов, вы можете отключить автокоррекцию текста в полях EditText внутри PopupWindwow, чтобы обойти эту проблему. Однако это приводит к ужасному взаимодействию с пользователем, так как многие пользователи (и клавиатуры, такие как swype) полагаются на автокоррекцию, что, вероятно, приведет к удалению пользователя из вашего приложения.
Надеюсь, это поможет другим, кто сталкивается с этой проблемой. Я бился головой о клавиатуру более суток, прежде чем, наконец, решил попробовать подход «Диалог», который, к моему удивлению, было довольно легко заменить. Удачи тебе