Отображение программной клавиатуры при каждом открытии объекта AlertDialog.Builder - PullRequest
31 голосов
/ 29 октября 2010

Мой код для открытия диалогового окна ввода выглядит следующим образом:

final AlertDialog.Builder alert = new AlertDialog.Builder(this);  
alert.setTitle("Dialog Title");  
alert.setMessage("Request information");  
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.edittextautotextlayout, null);
final EditText inputBox = (EditText) textEntryView.findViewById(R.id.my_et_layout);
alert.setView(inputBox);

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

Последанный совет здесь Я попытался вставить:

inputBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            alert.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});

, но Eclipse возражает, что "метод getWindow () не определен для типа AlertDialog.Builder".

Кажется, что код setOnFocusChangeListener работает для объекта AlertDialog, но не для AlertDialog.Builder.Как мне изменить мой код, чтобы программная клавиатура отображалась автоматически.

Ответы [ 14 ]

78 голосов
/ 25 мая 2011

Если вам всегда нужно показывать клавиатуру сразу после открытия диалога, а не после того, как конкретный виджет внутри получает фокус (например, если в вашем диалоге просто отображается EditText и кнопка), вы можете сделатьследующее:

AlertDialog alertToShow = alert.create();
alertToShow.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
alertToShow.show();

Вместо немедленного вызова .show() на вашем сборщике, вы можете вместо этого вызвать .create(), что позволит вам выполнить некоторую дополнительную обработку, прежде чем отобразить его на экране.

15 голосов
/ 28 января 2011

Это в ответ на miannelle.

При выборе пункта меню вызывается следующий метод:

private void addNote() {
    final Dialog dialog = new Dialog(this);
    dialog.setContentView(R.layout.textentryalertdialog);
    dialog.setTitle("Add note");
    TextView msgText = (TextView) dialog.findViewById(R.id.messagetext);
    msgText.setText("Whatever prompt you want");
    final EditText inputLine = (EditText) dialog.findViewById(R.id.my_edittext);
    Button okButton = (Button) dialog.findViewById(R.id.OKButton);
    okButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
            // app specific code
        }           
    });
    Button cancelButton = (Button) dialog.findViewById(R.id.CancelButton);
    cancelButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
        }           
    });
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    dialog.show();
}

Файл textentryalertdialog.xml определяет линейный макет, содержащий

TextView android: id = "@ + id / messagetext" ...

EditText android: id = "@ + id / my_edittext" ...

Кнопка android: id = "@ + id / OKButton" ...

Кнопка android: id = "@ + id / CancelButton" ...

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

6 голосов
/ 07 ноября 2010

При поддержке Мура Вотема (см. Его ответ выше) я ответил на мой вопрос, построив собственный диалог на основе класса Диалог.В отличие от предупреждения, основанного на AlertDialog.Builder, такой настраиваемый диалог принимает команду getWindow (). SetSoftInputMode (...) и поэтому позволяет автоматически отображать программную клавиатуру.

Для получения инструкций по созданию настраиваемого диалогового окна.Я нашел эту веб-страницу и эту особенно полезной.

2 голосов
/ 09 декабря 2012

Если вы хотите открыть диалоговое окно вместе с программной клавиатурой, чтобы пользователь мог свободно нажимать на текст редактирования в диалоговом окне, чтобы отобразить клавиатуру, например, если вы хотите получить какое-либо значение из диалогового окна, используйте простой код, он решит вашу проблему.

        public void onClick(final View v) 
        {   
             AlertDialog.Builder alert = new AlertDialog.Builder(v.getContext());                 
              alert.setIcon(R.drawable.smsicon);
              alert.setTitle(" Secrete Code");  
              alert.setMessage("Enter a Key for secrete text !");
              final EditText shft_val = new EditText(v.getContext()); 
              shft_val.setInputType(InputType.TYPE_CLASS_NUMBER);//changing the keyBoard to No only,restrict the string etc
              alert.setView(shft_val);

     //pOp Up the key pad on Edit Text  focus event

             shft_val.setOnFocusChangeListener(new OnFocusChangeListener()
             {
                public void onFocusChange(View arg0, boolean arg1)
                {  InputMethodManager inputMgr = (InputMethodManager)v.getContext().
                                    getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
                        }
                    });

                 alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() 
                 {  
                 public void onClick(DialogInterface dialog, int whichButton) 
                 {
                    //Your specific code... 
                 }
                 });
                 alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                     public void onClick(DialogInterface dialog, int which) {                       
                         dialog.dismiss();
                         return;   
                     }
                 });
                       alert.show();
                    }
1 голос
/ 14 апреля 2019

Я создаю AlertDialog и использую пользовательское представление, которое содержит EditText.И я хочу, чтобы экранная клавиатура отображалась при отображении диалогового окна и была скрыта независимо от того, нажимает ли пользователь кнопку ОК или где-то за пределами диалогового окна.

Этот фрагмент кода взят из androidx.perference.PreferenceDialogFragmentCompat, и я очищаюнемного.

final AlertDialog.Builder builder = new AlertDialog.Builder(context)
        .setTitle(mDialogTitle)
        .setPositiveButton(mPositiveButtonText, null)
        .setNegativeButton(mNegativeButtonText, null);

View contentView = LayoutInflater.from(context).inflate(resId, null);

mEditText = contentView.findViewById(android.R.id.edit);

/**
 * From PreferenceDialogFragmentCompat.needInputMethod
 * <p>Note: If your application targets P or above, ensure your subclass manually requests
 * focus (ideally in {@link #onBindDialogView(View)}) for the input field in order to
 * correctly attach the input method to the field.
 */
mEditText.requestFocus();

builder.setView(contentView);

final Dialog dialog = builder.create();
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

// This is not from PreferenceDialogFragmentCompat and I add it.
// It seems the soft keyboard won't get dismissed on some old devices without this line.
dialog.setOnDismissListener {
    dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

dialog.show();

Вам не нужно изменять манифест.Он автоматически фокусируется на EditText и будет отклонен независимо от того, нажимаете ли вы кнопки действий диалога или где-то за пределами диалога.

1 голос
/ 11 декабря 2014

Я знаю, этот Вопрос действительно старый, но, поскольку я попробовал около 20 различных так называемых «решений», я опубликую, что на самом деле сработало только для меня.

Этот ответ основан наОтвет Пира Фахима Шаха, который указал мне правильное направление (Спасибо):

Убедитесь, что вы включили это в onCreate своей деятельности, чтобы принудительные клавиатуры были скрыты, когда диалог закрыт:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

, затем создайте диалог, подобный этому:

    AlertDialog.Builder builder = new Builder(this);
    builder.setTitle("title");
    final EditText input = new EditText(this);
    input.setText("text");
    input.setSelection(input.getText().length()); // set cursor to end
    builder.setView(input);
    input.setOnFocusChangeListener(new OnFocusChangeListener()  {
       public void onFocusChange(View v, boolean hasFocus) { 
           if(hasFocus) {
               InputMethodManager inputMgr = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
               inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
           }
       }
    });
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // do something here
            dialog.dismiss();
        }
    });
    builder.setNegativeButton("Cancel", null);
    builder.show();
1 голос
/ 23 октября 2011

Я думаю, что у вас почти все получилось в вашем первоначальном вопросе. Попробуйте создать final AlertDialog для вызова getWindow(), например,

// Create the dialog used to modify the mailbox alias
final AlertDialog dialog = alert.create();

inputBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            dialog.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});

Я протестировал этот код, и теперь клавиатура автоматически появляется на большинстве моих устройств, включая:

  • Samsung Galaxy Tab OS 2.2
  • Samsung Galaxy S OS 2.1
  • HTC Sensation OS 2.3.4

Некоторые другие комментарии к этому решению:

1) Проверьте, есть ли у вас что-то в вашем XML для запроса фокуса, поскольку это может остановить работу этого кода (согласно Теду в вопросе, на который вы ссылаетесь).

2) Этот код не работает на моем HTC G2 под управлением ОС 2.3.4. Я думаю, это потому, что у него есть физическая клавиатура, и, возможно, опция WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE не работает с ней?

Я также попробовал SOFT_INPUT_STATE_VISIBLE (без ВСЕГДА), но это остановило автоматическое появление клавиатуры.

3) Вы также можете добавить код, чтобы пользователь мог нажать кнопку «Готово» на клавиатуре, чтобы отправить изменения, например,

inputAlias.setOnKeyListener(new OnKeyListener()
{
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent event)
  {
    if (keyCode == KeyEvent.KEYCODE_ENTER &&
        inputAlias.isFocused() &&
        inputAlias.getText().length() != 0)
    {
      // Save the new information here

  // Dismiss the dialog
      dialog.dismiss();
      return true;
    }
    return false;
  }
});
1 голос
/ 30 октября 2010

Вы пытались установить фокус на свой EditText -> inputBox.requestFocus () или что-то подобное?

1 голос
/ 30 октября 2010

попробуйте использовать представление

v.getWindow().setSoftInputMode( 
           WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
1 голос
/ 29 октября 2010

попробуйте использовать inputBox

inputBox.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
...