Подтвердить что ты не робот

Отображение мягкой клавиатуры при открытии объекта AlertDialog.Builder

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

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. Как мне изменить свой код, чтобы автоматическая настройка мягкой клавиатуры.

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

Это ответ на 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" ...

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

Ответ 4

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

        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();
                    }

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

Я думаю, вы почти всегда работали над своим оригинальным вопросом. Попробуйте создать 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 (без ALWAYS), но это остановило клавиатуру, появляющуюся автоматически.

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;
  }
});

Ответ 9

Я знаю, этот вопрос действительно старый, но, поскольку я пробовал около 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();

Ответ 10

Привет, Prepbgg, на самом деле есть альтернативный способ того, что вы сделали. Я действительно должен был использовать мой в своем ArrayAdapter. То, что я сделал, это передать контекст активности в arrayadapter, а затем вызвать его для доступа к getWindow() примерно так:

NoteArrayAdapter(Activity _activity, int _layout, ArrayList<Note> _notes, Context _context) {
  callingNoteListObj = (NoteList) _context;
}

// withiin getView

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

// within parent activity onCreate()
thisObject = this;

//within my parent activity fillData() (NoteList)
adapter =  new NoteArrayAdapter(activity, R.layout.channel_note_list_item, noteList, thisObject);

Ответ 11

В следующем фрагменте кода я покажу, как разместить произвольный LinearLayout в DialogFragment. Один с использованием AlertDialog (где мягкая клавиатура не работает) и другим способом без использования AlertDialog (где работает мягкая клавиатура!):

public static LinearLayout createLinearLayout(Context context)
{
    LinearLayout linearLayout = new LinearLayout(context);
    linearLayout.setOrientation(LinearLayout.VERTICAL);
    linearLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    String html;
    html = "<form action=search method=get >\n";
    html += "Google Search: <input name=q value=\"Johnny Depp\" /><br/>\n";
    html += "<input type=submit name=output value=search /><br/>\n";
    html += "</form>\n";
    WebView webView = new WebView(context);
    webView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new WebViewClient());
    webView.loadDataWithBaseURL("http://www.google.com", html, "text/html", "UTF-8", null);
    linearLayout.addView(webView);
    return linearLayout;
}

public void showWithAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder
                .setTitle("With AlertDialog")
                .setView(createLinearLayout(getActivity()));
            return builder.create();
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}

public void showWithoutAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            getDialog().setTitle("Without AlertDialog");
            getDialog().setCanceledOnTouchOutside(false);
            return createLinearLayout(getActivity());
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}

Ответ 12

Я нашел, что это сработало в диалоговом окне Alert Dialog, вызываемом из разных мест.

        case R.id.birthyear:
        case R.id.ymax:
            input.setInputType(InputType.TYPE_CLASS_NUMBER);
            break;

Имейте в виду, я тоже много пробовал. Кажется нежным.

Ответ 13

.setView() автоматически выведет клавиатуру в диалог. Обратите внимание на "финал" на самом EditText. ВАЖНЫЙ!

AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Random Title...");
alert.setMessage("Type a name");

final EditText input = new EditText(this);

//Set input focus (which opens the android  soft keyboard)
alert.setView(input);   
input.setHint("My Name is...");
//Set keyboard type
input.setInputType(InputType.TYPE_CLASS_TEXT); 

//add button onclick handlers...

alert.show();

Я думаю, что многие люди действительно переусердствовали со всеми функциями... Это довольно универсально и прекрасно работает. И это не будет раздувать ваш код.

Ответ 14

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

Этот фрагмент кода androidx.perference.PreferenceDialogFragmentCompat из androidx.perference.PreferenceDialogFragmentCompat и я немного 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();

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