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();
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));
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();
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>
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
Cela a fonctionné pour moi:
dialog.setView(dialog.getLayoutInflater().inflate(R.layout.custom_dialog_layout, null));
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.
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));
...
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();
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.
Cet exemple complet inclut la transmission de données à l'activité.
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>
Les parties clés sont
setView
pour attribuer la disposition personnalisée au AlertDialog.Builder
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();
}
}
DialogFragment
comme décrit dans la documentation }.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.