web-dev-qa-db-fra.com

Comment implémenter une vue AlertDialog personnalisée

Dans le la documentation Android sur AlertDialog , vous trouverez les instructions et l'exemple suivants pour définir une vue personnalisée dans un AlertDialog:

Si vous souhaitez afficher une vue plus complexe, recherchez le "corps" FrameLayout et ajoutez-y votre vue:

FrameLayout fl = (FrameLayout) findViewById(R.id.body);
fl.add(myView, new LayoutParams(FILL_PARENT, WRAP_CONTENT));

Tout d'abord, il est assez évident que add() est une faute de frappe et est censé être addView().

Je suis confus par la première ligne en utilisant R.id.body. Il semble que c’est l’élément body de AlertDialog ... mais je ne peux pas simplement écrire que dans mon code car cela donne une erreur de compilation. Où est-ce que R.id.body est défini ou assigné ou quoi que ce soit?

Voici mon code. J'ai essayé d'utiliser setView(findViewById(R.layout.whatever) sur le constructeur mais cela n'a pas fonctionné. Je suppose parce que je ne l'ai pas gonflé manuellement?

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
    .setCancelable(false)
    .setPositiveButton("Go", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int id) {
        EditText textBox = (EditText) findViewById(R.id.textbox);
        doStuff();
    }
});

FrameLayout f1 = (FrameLayout)findViewById(R.id.body /*CURRENTLY an ERROR*/);
f1.addView(findViewById(R.layout.dialog_view));

AlertDialog alert = builder.create();
alert.show();
101
stormin986

Vous avez raison, c'est parce que vous ne l'avez pas gonflé manuellement. Il semble que vous essayiez d'extraire le "corps" id de la présentation de votre activité, et cela ne fonctionnera pas.

Vous voulez probablement quelque chose comme ça:

LayoutInflater inflater = getLayoutInflater();
FrameLayout f1 = (FrameLayout)alert.findViewById(Android.R.id.body);
f1.addView(inflater.inflate(R.layout.dialog_view, f1, false));
47
synic

Vous pouvez créer votre vue directement à partir de Layout Inflater. Vous devez uniquement utiliser le nom de votre fichier XML de présentation et l'ID de la présentation dans le fichier.

Votre fichier XML doit avoir un identifiant comme celui-ci:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
              Android:id="@+id/dialog_layout_root"
              Android:orientation="vertical"
              Android:layout_width="fill_parent"
              Android:layout_height="wrap_content"
              Android:padding="10dp"
              />

Et vous pouvez ensuite définir votre mise en page sur le générateur avec le code suivant:

LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_layout, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(dialoglayout);
builder.show();
156
Andrewx2

Android.R.id.custom renvoyait null pour moi. J'ai réussi à le faire fonctionner au cas où quelqu'un rencontrerait le même problème,

AlertDialog.Builder builder = new AlertDialog.Builder(context)
            .setTitle("My title")
            .setMessage("Enter password");
final FrameLayout frameView = new FrameLayout(context);
builder.setView(frameView);

final AlertDialog alertDialog = builder.create();
LayoutInflater inflater = alertDialog.getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.simple_password, frameView);
alertDialog.show();

Pour référence, R.layout.simple_password est:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
          Android:orientation="vertical"
          Android:layout_width="match_parent"
          Android:layout_height="match_parent">

<EditText
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/password_edit_view"
        Android:inputType="textPassword"/>
<CheckBox
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="@string/show_password"
        Android:id="@+id/show_password_checkbox"
        Android:layout_gravity="left|center_vertical"
        Android:checked="false"/>

</LinearLayout>
19
John Rellis

Les documents Android ont été édités pour corriger les erreurs.

La vue à l'intérieur de AlertDialog s'appelle Android.R.id.custom

http://developer.Android.com/reference/Android/app/AlertDialog.html

17
Dapp

Cela a fonctionné pour moi:

dialog.setView(dialog.getLayoutInflater().inflate(R.layout.custom_dialog_layout, null));
12
Sergio Viudes

Les lignes de code les plus simples qui fonctionnent pour moi sont les suivantes:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.layout_resource_id);
builder.show();

Quel que soit le type de présentation (LinearLayout, FrameLayout, RelativeLayout) fonctionnera par setView Et ne différera que par l'apparence et le comportement.

4
kenix

AlertDialog.setView (View View) ajoute la vue donnée au R.id. custom FrameLayout. Ce qui suit est un extrait du code source Android de AlertController.setupView () qui gère finalement cela (mView est la vue donnée à la méthode AlertDialog.setView).

...
FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.**custom**);
custom.addView(**mView**, new LayoutParams(FILL_PARENT, FILL_PARENT));
...
2
Jung Soo Kim

La façon la plus simple de procéder consiste à utiliser Android.support.v7.app.AlertDialog au lieu de Android.app.AlertDialog, où public AlertDialog.Builder setView (int layoutResId) peut être utilisé sous l'API 21.

new AlertDialog.Builder(getActivity())
    .setTitle(title)
    .setView(R.layout.dialog_basic)
    .setPositiveButton(Android.R.string.ok,
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                //Do something
            }
        }
    )
    .setNegativeButton(Android.R.string.cancel,
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                //Do something
            }
        }
    )
    .create();
2
flanaras

Après avoir modifié l'ID sur Android.R.id.custom, je devais ajouter ce qui suit pour que la vue s'affiche:

((View) f1.getParent()).setVisibility(View.VISIBLE);

Cependant, cela a entraîné le rendu de la nouvelle vue dans une grande vue parent sans arrière-plan, cassant la boîte de dialogue en deux parties (texte et boutons, avec la nouvelle vue entre les deux). J'ai finalement eu l'effet que je voulais en insérant ma vue à côté du message:

LinearLayout f1 = (LinearLayout)findViewById(Android.R.id.message).getParent().getParent();

J'ai trouvé cette solution en explorant l'arborescence de vues avec View.getParent () et View.getChildAt (int). Pas vraiment content non plus, cependant. Rien de tout cela ne se trouve dans la documentation Android et si jamais ils modifiaient la structure de AlertDialog, cela pourrait casser.

1
Black Mantha

AlerteDialog personnalisée

Cet exemple complet inclut la transmission de données à l'activité.

enter image description here

Créer une mise en page personnalisée

Une mise en page avec EditText est utilisée pour cet exemple simple, mais vous pouvez la remplacer par tout ce que vous voulez.

custom_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
              Android:orientation="vertical"
              Android:paddingLeft="20dp"
              Android:paddingRight="20dp"
              Android:layout_width="match_parent"
              Android:layout_height="match_parent">

    <EditText
        Android:id="@+id/editText"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"/>

</LinearLayout>

Utiliser le dialogue en code

Les parties clés sont

  • utiliser setView pour attribuer la disposition personnalisée au AlertDialog.Builder
  • renvoyer des données à l'activité lorsqu'un clic est effectué sur un bouton de la boîte de dialogue.

Voici le code complet de l'exemple de projet présenté dans l'image ci-dessus: 

MainActivity.Java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void showAlertDialogButtonClicked(View view) {

        // create an alert builder
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Name");

        // set the custom layout
        final View customLayout = getLayoutInflater().inflate(R.layout.custom_layout, null);
        builder.setView(customLayout);

        // add a button
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // send data from the AlertDialog to the Activity
                EditText editText = customLayout.findViewById(R.id.editText);
                sendDialogDataToActivity(editText.getText().toString());
            }
        });

        // create and show the alert dialog
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    // do something with the data coming from the AlertDialog
    private void sendDialogDataToActivity(String data) {
        Toast.makeText(this, data, Toast.LENGTH_SHORT).show();
    }
}

Remarques

  • Si vous utilisez ceci à plusieurs endroits, envisagez de créer une sous-classe DialogFragment comme décrit dans la documentation }.

Voir également

1
Suragch

Il serait plus logique de le faire de cette manière, en utilisant le moins de code possible.

new AlertDialog.Builder(this).builder(this)
        .setTitle("Title")
        .setView(R.id.dialog_view)   //notice this setView was added
        .setCancelable(false)
        .setPositiveButton("Go", new DialogInterface.OnClickListener() {
            @Override 
            public void onClick(DialogInterface dialog, int id) {
                EditText textBox = (EditText) findViewById(R.id.textbox);
                doStuff();
            }
        }).show();

Pour obtenir une liste étendue des éléments que vous pouvez définir, commencez à saisir .set dans Android Studio.

0
StackAttack