web-dev-qa-db-fra.com

Affichage du clavier virtuel à chaque ouverture de l'objet AlertDialog.Builder

Mon code pour ouvrir une boîte de dialogue de saisie se lit comme suit:

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

Cela fonctionne bien sauf que je dois appuyer sur la ligne de saisie de texte avant que le clavier virtuel n'apparaisse.

Suite aux conseils donnés ici j'ai essayé d'insérer:

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

mais Eclipse objecte que "la méthode getWindow () n'est pas définie pour le type AlertDialog.Builder".

Il semble que le code setOnFocusChangeListener fonctionne pour un objet AlertDialog mais pas pour un AlertDialog.Builder. Comment modifier mon code pour faire apparaître automatiquement le clavier virtuel.

33
prepbgg

Avec les encouragements de Mur Votema (voir sa réponse ci-dessus), j'ai répondu à ma question en créant un dialogue personnalisé basé sur la classe Dialog. Contrairement à une alerte basée sur AlertDialog.Builder, une telle boîte de dialogue personnalisée accepte la commande getWindow (). SetSoftInputMode (...) et permet donc d'afficher automatiquement le clavier logiciel.

Pour obtenir des conseils sur la création d'une boîte de dialogue personnalisée, j'ai trouvé cette page Web et this particulièrement utiles.

6
prepbgg

Tant que vous devez toujours afficher le clavier immédiatement une fois que la boîte de dialogue s'ouvre plutôt qu'une fois qu'un widget de formulaire spécifique à l'intérieur obtient le focus (par exemple, si votre boîte de dialogue affiche juste un EditText et un bouton), vous pouvez faire le Suivant:

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

Plutôt que d'appeler immédiatement .show() sur votre générateur, vous pouvez à la place appeler .create() ce qui vous permet d'effectuer un traitement supplémentaire dessus avant de l'afficher à l'écran.

78
Defragged

C'est en réponse à miannelle.

La méthode suivante est appelée lorsqu'une option de menu est sélectionnée:

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

Le fichier textentryalertdialog.xml définit une mise en page linéaire contenant

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

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

Bouton Android: id = "@ + id/OKButton" ...

Bouton Android: id = "@ + id/CancelButton" ...

J'espère que ça aide.

15
prepbgg

Si vous voulez faire apparaître une boîte de dialogue avec un pavé de touches programmables, afin que l'utilisateur puisse ne pas appuyer sur modifier le texte dans la boîte de dialogue pour afficher le clavier, par exemple si vous allez prendre une valeur de la boîte de dialogue, utilisez ce code simple, cela résoudra votre problème.

        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();
                    }
2
Pir Fahim Shah

Avez-vous essayé de définir le focus sur votre EditText -> inputBox.requestFocus () ou quelque chose comme ça?

1
Tima

Je pense que vous l'avez presque fait fonctionner dans votre question initiale. Essayez de créer un final AlertDialog Pour appeler getWindow(), par exemple.

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

J'ai testé ce code et le clavier apparaît désormais automatiquement sur la plupart de mes appareils, notamment:

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

Quelques autres commentaires sur cette solution:

1) Vérifiez si vous avez déjà quelque chose dans votre XML pour demander le focus, car cela peut empêcher ce code de fonctionner (selon Ted dans la question vers laquelle vous créez un lien).

2) Ce code ne semble pas fonctionner sur mon HTC G2 sous OS 2.3.4. Je suppose que c'est parce qu'il a un clavier physique, et peut-être que l'option WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE Ne fonctionne pas avec?

J'ai également essayé SOFT_INPUT_STATE_VISIBLE (sans ALWAYS), mais cela a empêché le clavier d'apparaître automatiquement.

3) Vous pouvez également ajouter du code afin que l'utilisateur puisse appuyer sur le bouton Terminé du clavier pour soumettre les modifications, par ex.

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
Dan J

essayez d'utiliser inputBox

inputBox.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
1
Aaron Saunders

essayez d'utiliser la vue

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

Je crée un AlertDialog et j'utilise une vue personnalisée qui contient un EditText. Et je veux que le clavier virtuel soit affiché lorsque la boîte de dialogue est affichée et qu'il soit masqué que l'utilisateur clique sur le bouton OK ou quelque part en dehors de la boîte de dialogue.

Ce morceau de code provient de androidx.perference.PreferenceDialogFragmentCompat et je nettoie un peu.

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

Vous n'avez pas besoin de modifier le manifeste. Il se concentre automatiquement sur EditText et sera ignoré si vous cliquez sur les boutons d'action de la boîte de dialogue ou quelque part en dehors de la boîte de dialogue.

1
Dewey Reed

Je sais, cette question est vraiment ancienne, mais depuis que j'ai essayé environ 20 soi-disant "solutions" différentes, je posterai, ce qui n'a fonctionné que pour moi finalement.

Cette réponse est basée sur la réponse de Pir Fahim Shah, qui m'a pointé dans la bonne direction (Merci):

Assurez-vous de mettre ceci dans le onCreate de votre activité, de sorte que les claviers forcés soient masqués, lorsque la boîte de dialogue est fermée:

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

puis créez une boîte de dialogue comme celle-ci:

    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
sec_aw

Dans l'extrait de code suivant, je montre comment héberger un LinearLayout arbitraire dans un DialogFragment. Un utilisant AlertDialog (où le clavier logiciel ne fonctionne pas) et un autre moyen sans utiliser AlertDialog (où le clavier logiciel fonctionne!):

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");
}
0
Stephen Quan

Salut Prepbgg, il existe en fait une manière alternative à ce que vous avez fait. J'ai en fait dû utiliser le mien dans mon ArrayAdapter. Ce que j'ai fait, c'est passer le contexte de l'activité dans le arrayadapter puis l'appeler pour accéder à getWindow () quelque chose comme ceci:

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's onCreate()
thisObject = this;

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

. setView () affichera automatiquement le clavier dans une boîte de dialogue. Notez le "final" sur le EditText lui-même. IMPORTANT!

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

Je pense que beaucoup de gens en font vraiment trop avec toutes les fonctions ... C'est assez universel et fonctionne très bien. Et cela ne gonflera pas votre code.

0
Kevin Loring

J'ai trouvé que cela fonctionnait dans une boîte de dialogue d'alerte appelée de différents endroits

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

Remarquez que j'ai essayé beaucoup d'autres choses aussi. Semble délicat.

0
user462990