Исключение при фокусировке EditText в PopupWindow, запущенном на устройстве

Я разрабатываю окно PopUp для Android, и он работает, я добавил EditText и Button, когда при работе в ADV эта работа работает правильно, при запуске на устройстве, когда я фокусируюсь на EditText, это бросает странное исключение.

android.view.WindowManager$BadTokenException: Unable to add window - - token android.view.ViewRoot&48163b18 is not valid; is your active running? 

Я не знаю, имеет ли это значение, но я запускаю Galaxy Tab со входом Swype.

Теперь я прочитал спецификации Window.showAtLocation

 public void showAtLocation (View parent, int gravity, int x, int y) Display the content view in a popup window at the specified location. If the popup window cannot fit on screen, it will be clipped. [...] Parameters parent a parent view to get the getWindowToken() token from [...] 

Проблема заключается именно в этом токене, но как мне передать токен Activity?

Я также написал небольшой код, чтобы воспроизвести ошибку.

 PopupWindow window = new PopupWindow(activity); window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); window.setTouchable(true); window.setFocusable(true); EditText text = new EditText(activity); text.setText("Dont touch, this crash!"); window.setContentView(text); window.showAtLocation(arg0, Gravity.NO_GRAVITY, 10,10); 

Работа на AVD все работает нормально, а на устройстве этот сбой и выбросить ошибку, о которой я упоминал.

Я обнаруживаю что-то новое, когда я в ландшафтном режиме, эти ошибки не возникают.

Solutions Collecting From Web of "Исключение при фокусировке EditText в PopupWindow, запущенном на устройстве"

Спасибо, TheRedPill! У меня была та же проблема с EditText внутри PopupWindow, ведущей себя грубо. Он работал на Samsung Galaxy S3, HTC One X, но разбился на Huawei MediaPad FHD 10. Как только я начал редактировать приложение, он разбился.

Ваше решение:

 editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); 

Решил проблему для меня.

Трассировка стека:

 08-15 15:49:03.690: ERROR/AndroidRuntime(8692): FATAL EXCEPTION: main android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@417eefa8 is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:585) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224) at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149) at android.view.Window$LocalWindowManager.addView(Window.java:547) at android.widget.PopupWindow.invokePopup(PopupWindow.java:988) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:845) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:809) at android.widget.Editor$PinnedPopupWindow.updatePosition(Editor.java:2147) at android.widget.Editor$PinnedPopupWindow.show(Editor.java:2104) at android.widget.Editor$SuggestionsPopupWindow.show(Editor.java:2349) at android.widget.Editor.showSuggestions(Editor.java:1647) at android.widget.Editor$1.run(Editor.java:1546) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) 

Я попытался запустить ваш код, но все работает отлично для меня … Вот тестовый класс, который я написал:

 public class TestActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.testBtn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showPopup(); } }); } private void showPopup() { PopupWindow window = new PopupWindow(this); window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); window.setTouchable(true); window.setFocusable(true); EditText text = new EditText(this); text.setText("Touch it, it doesn't crash"); window.setContentView(text); window.showAtLocation(text, Gravity.NO_GRAVITY, 30, 30); } } 

Main.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/testBtn" android:text="Popup" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 

Возможно, вы попытались запустить всплывающий код в функции onCreate ()? Если я это сделаю, он выбрасывает то же Исключение, что и ваше, но это нормально, так как onCreate () называется активностью еще не полностью инициализированной.

(Я тоже пробовал на Galaxy Tab, но без ввода swype)

Причина:

Я отслеживаю причину ошибки вплоть до автоматического исправления правописания на некоторых телефонах (Moto Droid Razr и несколько других Moto Phones) и некоторых android Rom (как некоторые CM7 и CM7.1 ROMS). Если в тексте есть слово, которое неправильно написано, и текстовый курсор находится в тексте или рядом с ним, ОС Android попытается автоматически вызвать клавиатуру и попытаться предоставить предложения по правильной орфографии.

На большинстве устройств поле с правильной настройкой отображается только как однострочный сегмент над клавиатурой. Однако на некоторых пользовательских ROM (CM7, которые, как мне кажется, очень много) и некоторых устройствах (Droid Razr), появляется дополнительный раскрывающийся список:

образ

Я очень подозреваю, что раскрывающийся список с автоматическим исправлением также реализуется как всплывающее окно, и он пытается использовать текущее всплывающее окно (тот, который содержит EditText с неправильным словом) в качестве корневого представления, и пытается получить WindowToken из корневого представления.

Поскольку всплывающее окно не является традиционным, я предполагаю, что он не может дать правильное окноToken другим представлениям, которые их запрашивают, что приводит к ошибке.

Решения:

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) полагаются на автоматическую коррекцию, поэтому это, скорее всего, приведет пользователя от вашего приложения.

Надеюсь, это поможет другим, кто сталкивается с этой проблемой. Я ударился головой о клавиатуру в течение дня, прежде чем, наконец, решил попробовать подход «Диалог», который, к моему удивлению, довольно легко заменить. Удачи тебе

 EditText text = new EditText(activity); text.setText("Dont touch, this crash!"); 

Это на самом деле является причиной исключения.

Когда мы привязываем EditText к некоторому тексту, он выпадает при щелчке при появлении виртуальной клавиатуры.

Но тот же код отлично работает, когда мы не привязываем EditText

 EditText text = new EditText(activity); 

Хотя я столкнулся с такой же ошибкой и не смог разобраться до сих пор ….

Просто приложите усилия, чтобы сосредоточиться на линии создания проблем …

Может ли любой орган предложить, почему он ведет себя так и как решить эту проблему.

Thankx

отредактированный

Попробуйте сделать это, создайте новый класс, скажем, Popupcls

  public class PopUpFlag { private PopupWindow pw; public void initiatePopupWindow(Activity ctx) { LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.popupprofile, (ViewGroup) ctx.findViewById(R.id.popup_element)); EditText ettext = (EditText) layout.findViewById(R.id.edit); pw = new PopupWindow(layout, 300, 400, true); pw.showAtLocation(layout, Gravity.BOTTOM, 0, 0); } 

Теперь в вашей деятельности, если вам нужно всплывающее окно, когда кнопка всплывающего меню

 popupbtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { PopUpFlag puf=new PopUpFlag(); puf.initiatePopupWindow(YourActivityName.this); } }); 

надеюсь, это поможет

Я также получил ту же ошибку, когда edittext в моем popupwindow уже содержал текст, и текст не был словарным словом (например, название города). Когда я нажимаю между текстом и бумом! У меня есть исключение. Я решил это, сделав edittext не показывать автоматически правильные предложения:

 android:inputType="textNoSuggestions" 

Сбой происходит в EditText, помещенном в WindowManager, когда пользователь нажимает на слово, подчеркнутое красным. Такое подчеркнутое слово означает, что оно не существует в словаре. При нажатии OS пытается отобразить поп с ближайшими совпадающими словами из словаря и сбой, так как такое всплывающее окно не может быть прикреплено к окну из-за плохого исключения токена.

Только следующее решение, казалось, работало для меня программно

 //assume an EditText object with name myEditText myEditText.setInputType(myEditText.getInputType() | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); 

InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS работает не так, как ожидалось, на всех клавиатурах, тогда как InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD имеет недостаток, что он также отключает переключение языка на клавиатуре и жестов салфетки для добавления текста.