web-dev-qa-db-fra.com

Dialogue de saisie de texte Android

Lorsqu'un utilisateur clique sur une Button dans mon application (qui est imprimée dans une SurfaceView), je souhaite qu'un texte Dialog apparaisse et j'aimerais stocker le résultat dans une String. J'aimerais que le texte Dialog se superpose à l'écran actuel. Comment puis-je faire ceci?

235
Luke Taylor

Cela semble être une bonne occasion d’utiliser un AlertDialog .

Aussi fondamental que cela puisse paraître, Android ne dispose pas de boîte de dialogue intégrée (pour autant que je sache). Heureusement, il ne s’agit que d’un peu de travail en plus de la création d’un AlertDialog standard. Vous devez simplement créer un EditText pour permettre à l'utilisateur de saisir des données et le définir comme vue de AlertDialog. Vous pouvez personnaliser le type d'entrée autorisé à l'aide de setInputType , si nécessaire.

Si vous pouvez utiliser une variable membre, vous pouvez simplement définir la variable sur la valeur de la propriété EditText. Cette variable persistera une fois que la boîte de dialogue aura été fermée. Si vous ne pouvez pas utiliser une variable membre, vous devrez peut-être utiliser un écouteur pour envoyer la valeur de chaîne au bon endroit. (Je peux éditer et élaborer plus si c'est ce dont vous avez besoin).

Dans votre classe:

private String m_Text = "";

Dans le OnClickListener de votre bouton (ou dans une fonction appelée à partir de là):

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");

// Set up the input
final EditText input = new EditText(this);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
builder.setView(input);

// Set up the buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
    @Override
    public void onClick(DialogInterface dialog, int which) {
        m_Text = input.getText().toString();
    }
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }
});

builder.show();
492
Aaron

Je mettrai à jour la mise à jour de @Aaron avec une approche qui vous donnera l'occasion de styler le dialogue de manière plus efficace. Voici l'exemple ajusté:

AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Title");
// I'm using fragment here so I'm using getView() to provide ViewGroup
// but you can provide here any other instance of ViewGroup from your Fragment / Activity
View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.text_inpu_password, (ViewGroup) getView(), false);
// Set up the input
final EditText input = (EditText) viewInflated.findViewById(R.id.input);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
builder.setView(viewInflated);

// Set up the buttons
builder.setPositiveButton(Android.R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        m_Text = input.getText().toString();
    }   
}); 
builder.setNegativeButton(Android.R.string.cancel, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }   
}); 

builder.show();

Voici l'exemple de mise en page utilisé pour créer la boîte de dialogue EditText:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:padding="@dimen/content_padding_normal">

    <Android.support.design.widget.TextInputLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <AutoCompleteTextView
            Android:id="@+id/input"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:hint="@string/hint_password"
            Android:imeOptions="actionDone"
            Android:inputType="textPassword" />

    </Android.support.design.widget.TextInputLayout>
</FrameLayout>

Ici vous pouvez trouver le résultat:

 EditText Dialog example

76
Michal

Qu'en est-il de cet exemple EXEMPLE ? Cela semble simple.

final EditText txtUrl = new EditText(this);

// Set the default text to a link of the Queen
txtUrl.setHint("http://www.librarising.com/astrology/celebs/images2/QR/queenelizabethii.jpg");

new AlertDialog.Builder(this)
  .setTitle("Moustachify Link")
  .setMessage("Paste in the link of an image to moustachify!")
  .setView(txtUrl)
  .setPositiveButton("Moustachify", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      String url = txtUrl.getText().toString();
      moustachify(null, url);
    }
  })
  .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
    }
  })
  .show(); 
59
bhekman

J'ai trouvé plus propre et plus réutilisable d'étendre AlertDialog.Builder pour créer une classe de dialogue personnalisée. Ceci est pour un dialogue qui demande à l'utilisateur d'entrer un numéro de téléphone. Un numéro de téléphone prédéfini peut également être fourni en appelant setNumber() avant d'appeler show().

InputSenderDialog.Java

public class InputSenderDialog extends AlertDialog.Builder {

    public interface InputSenderDialogListener{
        public abstract void onOK(String number);
        public abstract void onCancel(String number);
    }

    private EditText mNumberEdit;

    public InputSenderDialog(Activity activity, final InputSenderDialogListener listener) {
        super( new ContextThemeWrapper(activity, R.style.AppTheme) );

        @SuppressLint("InflateParams") // It's OK to use NULL in an AlertDialog it seems...
        View dialogLayout = LayoutInflater.from(activity).inflate(R.layout.dialog_input_sender_number, null);
        setView(dialogLayout);

        mNumberEdit = dialogLayout.findViewById(R.id.numberEdit);

        setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                if( listener != null )
                    listener.onOK(String.valueOf(mNumberEdit.getText()));

            }
        });

        setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                if( listener != null )
                    listener.onCancel(String.valueOf(mNumberEdit.getText()));
            }
        });
    }

    public InputSenderDialog setNumber(String number){
        mNumberEdit.setText( number );
        return this;
    }

    @Override
    public AlertDialog show() {
        AlertDialog dialog = super.show();
        Window window = dialog.getWindow();
        if( window != null )
            window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        return dialog;
    }
}

dialog_input_sender_number.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:padding="10dp">

    <TextView
        Android:id="@+id/title"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        Android:paddingBottom="20dp"
        Android:text="Input phone number"
        Android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        Android:id="@+id/numberLabel"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/title"
        app:layout_constraintLeft_toLeftOf="parent"
        Android:text="Phone number" />

    <EditText
        Android:id="@+id/numberEdit"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/numberLabel"
        app:layout_constraintLeft_toLeftOf="parent"
        Android:inputType="phone" >
        <requestFocus />
    </EditText>

</Android.support.constraint.ConstraintLayout>

Utilisation:

new InputSenderDialog(getActivity(), new InputSenderDialog.InputSenderDialogListener() {
    @Override
    public void onOK(final String number) {
        Log.d(TAG, "The user tapped OK, number is "+number);
    }

    @Override
    public void onCancel(String number) {
        Log.d(TAG, "The user tapped Cancel, number is "+number);
    }
}).setNumber(someNumberVariable).show();
2
Magnus W

@LukeTaylor: J'ai actuellement la même tâche (créer une fenêtre contextuelle/une boîte de dialogue contenant un texte d'édition).
Personnellement, je trouve la voie totalement dynamique un peu limitante en termes de créativité .

DISPOSITION DE DIALOGUE ENTIÈREMENT PERSONNALISÉE:

Plutôt que de compter entièrement sur Code pour créer le dialogue, vous pouvez le personnaliser comme suit:

1) - Créer un nouveau fichier Layout Resource .. Ceci agira comme votre dialogue, permettant une totale liberté de création!
REMARQUE: Reportez-vous aux directives relatives à la conception du matériel pour vous aider à garder les choses propres et précises.

2) - Donnez des identifiants à tous vos éléments View. Dans l'exemple de code ci-dessous, j'ai 1 EditText et 2 Buttons.

3) - Créer une Activity avec une Button, à des fins de test .. Nous allons le faire gonfler et lancer votre dialogue!

public void buttonClick_DialogTest(View view) {

    AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);

    //  Inflate the Layout Resource file you created in Step 1
    View mView = getLayoutInflater().inflate(R.layout.timer_dialog_layout, null);

    //  Get View elements from Layout file. Be sure to include inflated view name (mView)
    final EditText mTimerMinutes = (EditText) mView.findViewById(R.id.etTimerValue);
    Button mTimerOk = (Button) mView.findViewById(R.id.btnTimerOk);
    Button mTimerCancel = (Button) mView.findViewById(R.id.btnTimerCancel);

    //  Create the AlertDialog using everything we needed from above
    mBuilder.setView(mView);
    final AlertDialog timerDialog = mBuilder.create();

    //  Set Listener for the OK Button
    mTimerOk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick (View view) {
            if (!mTimerMinutes.getText().toString().isEmpty()) {
                Toast.makeText(MainActivity.this, "You entered a Value!,", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(MainActivity.this, "Please enter a Value!", Toast.LENGTH_LONG).show();
            }
        }
    });

    //  Set Listener for the CANCEL Button
    mTimerCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick (View view) {
            timerDialog.dismiss();
        }
    });

    //  Finally, SHOW your Dialog!
    timerDialog.show();


    //  END OF buttonClick_DialogTest
}


Part de gâteau! Pleine liberté de création! Assurez-vous simplement de suivre les directives importantes;)

J'espère que ça aidera quelqu'un! Dites-moi ce que vous en pensez!

1
Studio2bDesigns

Si vous voulez de l’espace dans les vues left et right de input, vous pouvez ajouter du rembourrage comme

private fun showAlertWithTextInputLayout(context: Context) {
    val textInputLayout = TextInputLayout(context)
    textInputLayout.setPadding(
        resources.getDimensionPixelOffset(R.dimen.dp_19), // if you look at Android alert_dialog.xml, you will see the message textview have margin 14dp and padding 5dp. This is the reason why I use 19 here
        0,
        resources.getDimensionPixelOffset(R.dimen.dp_19),
        0
    )
    val input = EditText(context)
    textInputLayout.hint = "Email"
    textInputLayout.addView(input)

    val alert = AlertDialog.Builder(context)
        .setTitle("Reset Password")
        .setView(textInputLayout)
        .setMessage("Please enter your email address")
        .setPositiveButton("Submit") { dialog, _ ->
            // do some thing with input.text
            dialog.cancel()
        }
        .setNegativeButton("Cancel") { dialog, _ ->
            dialog.cancel()
        }.create()

    alert.show()
}

dimens.xml

<dimen name="dp_19">19dp</dimen>

J'espère que ça aide

1
Linh