Итак, у меня есть то, что кажется общей проблемой, а именно то, что EditText в моем диалоговом окне не отображается, когда он получает фокус. Я видел несколько обходных путей, например, в этой ветке , в этом и в этом (и во многих других), но я никогда не видел удовлетворительного объяснения того, почему это вообще происходит.
Я бы предпочел, чтобы Android использовал свое собственное поведение по умолчанию для EditTexts, чем создавать мое собственное, но похоже, что все (в этих потоках) приняли, что поведение по умолчанию для EditTexts в диалогах - просто указывать курсор, а не клавиатуру. Почему это могло быть?
Для записи, ни один из этих обходных путей, похоже, у меня не работает - самое близкое, что я смог найти, - это заставить клавиатуру появляться под диалоговым окном (с помощью InputMethodManager.toggleSoftKeyboard (*)). Моя конкретная конфигурация - API15, EditText отображается в нижнем колонтитуле ListView в AlertDialog. EditText андроид: фокусируемый = «истинный» установлен, и onFocusChangeListener будет получать фокус события.
Редактировать:
По запросу, вот конкретный фрагмент кода, с которым я работаю. Я не буду беспокоиться обо всем макете, но в этом конкретном приложении EditText появляется в ответ на нажатие кнопки в диалоговом окне (аналогично представлению действий ). Он содержится в RelativeLayout, для которого по умолчанию видимость "пропала":
<RelativeLayout
android:id="@+id/relLay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:visibility="gone"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp">
<ImageButton
android:id="@+id/cancelBut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@color/transparent"
android:src="@drawable/cancelButton"
android:layout_margin="5dp"/>
<ImageButton
android:id="@+id/okBut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/cancelBut"
android:background="@color/transparent"
android:src="@drawable/okButton"
android:layout_margin="5dp" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:focusable="true"
android:layout_toLeftOf="@id/okBut"/>
</RelativeLayout>
Код, который создает это, устанавливает видимость relativeLayout на «Visible» (и скрывает другие элементы пользовательского интерфейса). Этого должно быть достаточно, чтобы поднять клавиатуру, когда EditText сфокусируется, исходя из моего опыта работы с EditText. Однако по некоторым причинам это не так. Я могу установить следующее onFocusChangeListener:
edit_text.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// For whatever reason we need to request a soft keyboard.
InputMethodManager imm = (InputMethodManager)dlg.getWindow().getContext().getSystemService(_Context.INPUT_METHOD_SERVICE);
if(hasFocus)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Log.v("DialogProblem", "Focus requested, " + (hasFocus?"has focus.":"doesn't have focus."));
}
}
});
Используя эту конфигурацию, когда я впервые вхожу в EditText, срабатывает onFocusChangedListener и генерирует журнал, который неизменно выглядит следующим образом:
Focus requested, has focus.
Focus requested, doesn't have focus.
Focus requested, has focus.
Клавиатура появляется, а затем исчезает, вероятно, потому, что я переключаю ее дважды, но даже когда я проверяю, что она остается включенной, она находится за диалоговым окном (в серой области), и нет способа добраться до нее, не закрывая диалоговое окно. .
Тем не менее, я хотел бы подчеркнуть, что, хотя я могу заставить этот обходной путь работать, меня в первую очередь интересует найти простую причину, по которой EditText вообще не запускается, и почему это кажется таким банальным!
Ответы:
Итак, после большого чтения я понял, почему это проблема, и мне не нужно использовать какие-либо обходные пути.
Проблема, по-видимому, в том (по крайней мере, в моем случае), что, поскольку место, где вы вводите текст, изначально скрыто (или вложено или что-то в этом роде), AlertDialog автоматически устанавливает флаг WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM (или некоторую комбинацию этого и WindowManager .LayoutParams.FLAG_NOT_FOCUSABLE), чтобы вещи не запускали мягкий ввод для отображения.
Я нашел способ исправить это, добавив следующую строку после создания диалога:
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Как только это будет сделано, EditText будет действовать как обычный EditText, без каких-либо кладов или обходных путей.
источник
clearFlags()
послеshow()
, спасибо @AlexanderFragotsisУ меня такая же проблема в моем приложении. Если вы разрабатываете для уровня API> = 8, вы можете использовать этот фрагмент:
dialog.setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialog) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT); } });
Я не нашел решения для более низких уровней API ...
Кстати: этот фрагмент не всегда работает на эмуляторе. Не знаю почему.
источник
AlertDialog dialog = builder.create();
до иdialog.show();
после вышеуказанного, если вы используете AlertDialog.BuilderЕсли вы прочитаете документацию AlertDialog, вы найдете там:
У меня была проблема, о которой вы упомянули, с EditText в ListView внутри диалога. Я исправил это, перезаписав пользовательский класс представления (в моем случае ListView) моим собственным FocusableListView, с перезаписью только одного метода:
public class FocusableListView extends ListView { public FocusableListView(Context context) { super(context); } public FocusableListView(Context context, AttributeSet attrs) { super(context, attrs); } public FocusableListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onCheckIsTextEditor() { // this is where the magic happens return true; } }
Затем я использую его в файле макета как:
<?xml version="1.0" encoding="UTF-8"?> <com.myexample.wiget.FocusableListView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:descendantFocusability="beforeDescendants" android:layout_height="wrap_content" />
Вы можете перезаписать RelativeLayout в вашем случае таким же образом, и он должен работать.
источник
Это то, что у меня сработало. Создайте AlertDialog.Builder, установите заголовок, positiveButton, negativeButton. После сделайте это:
AlertDialog dialog = builder.create(); dialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); dialog.show(); editText.requestFocus();
Вам не нужно использовать
builder.show();
.источник
Приведенный выше код очень полезен. Но вы должны вызвать метод «show» после метода «create» (я не знаю почему, но только это работает в моем диалоге с EditText в ListView). В методе onCreateDialog:
@Override protected Dialog onCreateDialog(int id) { switch (id) { case YOUR_DIALOG_ID: { //... AlertDialog a = new AlertDialog.Builder(this)./* ... set the properties here */ .create(); a.show(); //!!! this is very important to call the "show" method a.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); return a; } //... } return null; }
источник
Спасибо! У меня есть встроенный TextEdit в последней строке ListView, встроенный в фрагмент диалогового окна предупреждения. Я использовал ваше решение по очистке флагов как сообщение для запуска, и теперь оно отлично работает.
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle("My Title"); m_adapter = new MyAdapter(getContext()); builder.setAdapter(m_adapter, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); final AlertDialog dialog = builder.create(); final ListView listView = dialog.getListView(); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { } }); listView.post(new Runnable() { @Override public void run() { dialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); } }); return dialog; }
источник
Вот один из способов сделать это:
final Window dialogWindow = dialog.getWindow(); dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
источник
Я хотел бы добавить к ответу Пола и комментарию Александра .
У меня есть диалог, созданный в
onCreateDialog()
методе, который (кажется) требует возвратаdialog.show();
, поэтому вы не можете добавить параметры макета в диалог, в котором создается диалог. Чтобы обойти это, просто оставьте свойonCreateDialog()
метод таким же и добавьтеonResume()
метод следующим образом:@Override public void onResume() { super.onResume(); Dialog dialog = getDialog(); dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); }
Это должно помочь, к счастью, у меня это работает. Довольно долго занимались этим делом.
источник
полный код для отображения клавиатуры в диалоге:
public void onFocusChange(View v, boolean hasFocus) { Log.v("onFocusChange", hasFocus + " " + showkeyboard); if (hasFocus) { if (showkeyboard++ == 0) { alertDialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); alertDialog.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } else { showkeyboard = 1; } } }
источник
This worked for me ---- editText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); //dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); //dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); //dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); InputMethodManager mgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); mgr.showSoftInput(v, InputMethodManager.SHOW_FORCED); editText.setFocusable(true); } });
источник
просто добавьте ниже codeLine:
// для автоматического отображения клавиатуры, когда editText находится в диалоге dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
источник