Comment afficher une vue de liste dans une boîte de dialogue d'alerte Android?


291

Dans une application Android, je souhaite afficher une vue de liste personnalisée dans un AlertDialog.

Comment puis-je faire ceci?


Prenez simplement List of strings, puis créez une séquence de CharSequence [], puis utilisez AlertDialog.Builder pour afficher les éléments. Voici l'exemple le plus simple avec un instantané feelzdroid.com/2014/12/…
Naruto

Réponses:


498

Code ci-dessous utilisé pour afficher la liste personnalisée dans AlertDialog

AlertDialog.Builder builderSingle = new AlertDialog.Builder(DialogActivity.this);
builderSingle.setIcon(R.drawable.ic_launcher);
builderSingle.setTitle("Select One Name:-");

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(DialogActivity.this, android.R.layout.select_dialog_singlechoice);
arrayAdapter.add("Hardik");
arrayAdapter.add("Archit");
arrayAdapter.add("Jignesh");
arrayAdapter.add("Umang");
arrayAdapter.add("Gatti");

builderSingle.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

builderSingle.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String strName = arrayAdapter.getItem(which);
                AlertDialog.Builder builderInner = new AlertDialog.Builder(DialogActivity.this);
                builderInner.setMessage(strName);
                builderInner.setTitle("Your Selected Item is");
                builderInner.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog,int which) {
                                dialog.dismiss();
                            }
                        });
                builderInner.show();
            }
        });
builderSingle.show();

existe-t-il une possibilité de détecter de longs clics sur ces éléments? je cherche des heures pour une solution de menu contextuel qui fonctionne sur tous les niveaux de l'api
wutzebaer

7
@Shvet soi-disant, show () crée et affiche la boîte de dialogue, tandis que create () ne fait que la créer.
htafoya

Comment puis-je utiliser cette configuration, mais au lieu de coder en dur ma liste, j'ai besoin d'obtenir des données d'analyse que l'utilisateur possède déjà.?
stanley santoso

@stanleysantoso créez votre propre adaptateur, remplissez-le de données, puis définissez-le comme adaptateur pour le alertdialog: dialogBuilder.setAdapter (MyCustomAdapter); Cela devrait fonctionner
CantThinkOfAnything

1
Quelle est la mise en page select_dialog_single_choice?
ForceFieldsForDoors

254

Selon la documentation , il existe trois types de listes pouvant être utilisées avec AlertDialog:

  1. Liste traditionnelle à choix unique
  2. Liste à choix unique persistante (boutons radio)
  3. Liste à choix multiples persistante (cases à cocher)

Je vais donner un exemple de chacun ci-dessous.

Liste traditionnelle à choix unique

La façon de faire une liste traditionnelle à choix unique est d'utiliser setItems.

entrez la description de l'image ici

Version Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose an animal");

// add a list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
builder.setItems(animals, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case 0: // horse
            case 1: // cow
            case 2: // camel
            case 3: // sheep
            case 4: // goat
        }
    }
});

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

Il n'y a pas besoin d'un bouton OK car dès que l'utilisateur clique sur un élément de liste, le contrôle est renvoyé au OnClickListener .

Version Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose an animal")

// add a list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
builder.setItems(animals) { dialog, which ->
    when (which) {
        0 -> { /* horse */ }
        1 -> { /* cow   */ }
        2 -> { /* camel */ }
        3 -> { /* sheep */ }
        4 -> { /* goat  */ }
    }
}

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Liste des boutons radio

entrez la description de l'image ici

L'avantage de la liste des boutons radio par rapport à la liste traditionnelle est que l'utilisateur peut voir quel est le paramètre actuel. La façon de faire une liste de boutons radio est d'utiliser setSingleChoiceItems.

Version Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose an animal");

// add a radio button list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
int checkedItem = 1; // cow
builder.setSingleChoiceItems(animals, checkedItem, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user checked an item
    }
});

// add OK and Cancel buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user clicked OK
    }
});
builder.setNegativeButton("Cancel", null);

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

J'ai codé en dur l'élément choisi ici, mais vous pouvez le suivre avec une variable de membre de classe dans un projet réel.

Version Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose an animal")

// add a radio button list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
val checkedItem = 1 // cow
builder.setSingleChoiceItems(animals, checkedItem) { dialog, which ->
    // user checked an item
}


// add OK and Cancel buttons
builder.setPositiveButton("OK") { dialog, which ->
    // user clicked OK
}
builder.setNegativeButton("Cancel", null)

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Liste des cases à cocher

entrez la description de l'image ici

La façon de faire une liste de cases à cocher est d'utiliser setMultiChoiceItems.

Version Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose some animals");

// add a checkbox list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
boolean[] checkedItems = {true, false, false, true, false};
builder.setMultiChoiceItems(animals, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
        // user checked or unchecked a box
    }
});

// add OK and Cancel buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user clicked OK
    }
});
builder.setNegativeButton("Cancel", null);

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

Ici, j'ai codé en dur les éléments de la liste qui ont déjà été vérifiés. Il est plus probable que vous souhaitiez les suivre dans un fichier ArrayList<Integer>. Voir l' exemple de documentation pour plus de détails. Vous pouvez également définir les éléments cochés surnull si vous souhaitez toujours que tout commence sans contrôle.

Version Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose some animals")

// add a checkbox list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
val checkedItems = booleanArrayOf(true, false, false, true, false)
builder.setMultiChoiceItems(animals, checkedItems) { dialog, which, isChecked ->
    // user checked or unchecked a box
}

// add OK and Cancel buttons
builder.setPositiveButton("OK") { dialog, which ->
    // user clicked OK
}
builder.setNegativeButton("Cancel", null)

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Remarques

  • Pour le contextdans le code ci-dessus, n'utilisez pas getApplicationContext()ou vous obtiendrez un IllegalStateException(voir ici pourquoi). Au lieu de cela, obtenez une référence au contexte d'activité, comme avec this.
  • Vous pouvez également remplir les éléments de la liste à partir d'une base de données ou d'une autre source à l'aide de setAdapterou setCursorou en passant un Cursorou ListAdapterdans le setSingleChoiceItemsou setMultiChoiceItems.
  • Si la liste est plus longue que celle qui apparaît à l'écran, la boîte de dialogue la fait défiler automatiquement. Si vous avez une très longue liste, je suppose que vous devriez probablement créer une boîte de dialogue personnalisée avec RecyclerView .
  • Pour tester tous les exemples ci-dessus, je viens d'avoir un projet simple avec un seul bouton qui a montré la boîte de dialogue lorsque vous cliquez dessus:

    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            context = this;
        }
    
        public void showAlertDialogButtonClicked(View view) {
    
            // example code to create alert dialog lists goes here
        }
    }

en relation


2
C'est super, ajoutez maintenant des icônes;)
AaA

1
@AaA, je pense que vous auriez besoin de créer une boîte de dialogue d'alerte de mise en page personnalisée qui utilise un RecyclerViewdans la mise en page pour cela.
Suragch

que signifie le «qui» dans la méthode de dialogue onclick?
phishing passé le

@gonephishing, selon la documentation , c'est "le bouton qui a été cliqué (ex. BUTTON_POSITIVE) ou la position de l'élément cliqué".
Suragch

1
Si vous souhaitez implémenter une liste simple (1) avec un adaptateur personnalisé, utilisez Builder.setAdapter(ListAdapter, DialogInterface.OnClickListener): whichdans l'écouteur onClicksera égal à la position de l'élément cliqué. Builder.setOnItemSelectedListenern'aura aucun effet.
Miha_x64

122

Vous pouvez utiliser une boîte de dialogue personnalisée.

Disposition de dialogue personnalisée. list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ListView
        android:id="@+id/lv"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"/>
</LinearLayout>

Dans votre activité

Dialog dialog = new Dialog(Activity.this);
       dialog.setContentView(R.layout.list)

ListView lv = (ListView ) dialog.findViewById(R.id.lv);
dialog.setCancelable(true);
dialog.setTitle("ListView");
dialog.show();

Éditer:

Utilisation de alertdialog

String names[] ={"A","B","C","D"};
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.custom, null);
alertDialog.setView(convertView);
alertDialog.setTitle("List");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,names);
lv.setAdapter(adapter);
alertDialog.show();

custom.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

</ListView>

Casser

entrez la description de l'image ici


1
@Juan - devtopia.coop vous avez édité mon message après avoir voté juste pour downvote. Pourriez-vous commenter ce qui ne va pas
Raghunandan

Rien avec la version actuelle, la précédente manquait de tous les trucs d'adaptateur et ne montrait donc qu'un ListView vide, je retire volontiers mon vote négatif maintenant. J'ai voté sur une réponse incomplète, pas sur cette modification d'il y a 3 heures.
Juan Cortés

@Raghunandan, j'ai utilisé votre code mais j'ai eu une exception sur lv.setAdapter (adaptateur); ligne, pouvez-vous m'aider?
Ahmad Vatani

@Ahmad quelle est l'excpetion?
Raghunandan

1
@NeilGaliaskarov oui, il est défilable. Listview défilera
Raghunandan

44
final CharSequence[] items = {"A", "B", "C"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Make your selection");
builder.setItems(items, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int item) {
        // Do something with the selection
        mDoneButton.setText(items[item]);
    }
});
AlertDialog alert = builder.create();
alert.show();

1
Qu'est-ce que m.DoneButton?
ForceFieldsForDoors

2
@ArhatBaid Mais setItems ne fonctionne pas lorsque je mets un message dans setMessage. J'ai cherché dans google mais la réponse que j'ai trouvée était de définir le message dans setTitle. Mais le problème est que setTitle n'autorise que peu de caractères. Existe-t-il un moyen d'utiliser setMessage et setItems dans la boîte de dialogue d'alerte?
David

@David pour cela, vous devez opter pour une boîte de dialogue personnalisée.
Arhat Baid

1
Cette solution est très agréable car vous pouvez également y aller avec un ListAdapteravec setSingleChoiceItems(très similaire à l'appel ci-dessus)
snotyak

Parfait comme prévu ... gère des centaines d'articles avec un code minimal. :)
jeet.chanchawat

10

Utilisez l' import android.app.AlertDialog;importation " " et vous écrivez

    String[] items = {"...","...."};             
    AlertDialog.Builder build = new AlertDialog.Builder(context);
    build.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            //do stuff....
        }
    }).create().show();

vous aviez besoin de bc avec create vous construisez le AlertDialog puis vous le montrez. pas le constructeur. (c) Facebamm
Facebamm

@Facebamm ce n'est pas vrai. show()fait les deux. Calling this method is functionally identical to: AlertDialog dialog = builder.create(); dialog.show();qui provient directement de la show()documentation de la méthode
ᴛʜᴇᴘᴀᴛᴇʟ

c'est vrai mais parfois j'ai des erreurs d'interface utilisateur visiblement. (c) Facebamm
Facebamm

Non ce n'est pas vrai. show () est identique à create (). show (); / ** * Crée un {@link AlertDialog} avec les arguments fournis à ce * constructeur et affiche immédiatement la boîte de dialogue. * <p> * L'appel de cette méthode est fonctionnellement identique à: * <pre> * Dialogue AlertDialog = builder.create (); * dialog.show (); * </pre> * / public AlertDialog show () {final AlertDialog dialog = create (); dialog.show (); boîte de dialogue de retour; }
Emanuel S

ok, j'ai testé pendant un certain temps et je dis sry, c'est vrai. (c) Facebamm
Facebamm

4

C'est trop simple

final CharSequence[] items = {"Take Photo", "Choose from Library", "Cancel"};

AlertDialog.Builder builder = new AlertDialog.Builder(MyProfile.this);

builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int item) {
        if (items[item].equals("Take Photo")) {
            getCapturesProfilePicFromCamera();
        } else if (items[item].equals("Choose from Library")) {
            getProfilePicFromGallery();
        } else if (items[item].equals("Cancel")) {
            dialog.dismiss();
        }
    }
});
builder.show();

3

En tant que débutant, je vous suggère de passer par http://www.mkyong.com/android/android-custom-dialog-example/

Je vais résumer ce qu'il fait

  1. Crée un fichier XML pour la boîte de dialogue et l'activité principale
  2. Dans l'activité principale à l'endroit requis crée un objet de classe android Dialog
  3. Ajoute un style et du texte personnalisés basés sur le fichier XML
  4. Appelle la dialog.show()méthode.

1

À Kotlin:

fun showListDialog(context: Context){
    // setup alert builder
    val builder = AlertDialog.Builder(context)
    builder.setTitle("Choose an Item")

    // add list items
    val listItems = arrayOf("Item 0","Item 1","Item 2")
    builder.setItems(listItems) { dialog, which ->
        when (which) {
            0 ->{
                Toast.makeText(context,"You Clicked Item 0",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
            1->{
                Toast.makeText(context,"You Clicked Item 1",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
            2->{
                Toast.makeText(context,"You Clicked Item 2",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
        }
    }

    // create & show alert dialog
    val dialog = builder.create()
    dialog.show()
}

1
Ajoutez une description à votre réponse.
Mathews Sunny

1
Quelle sorte de description?
Varsha Prabhakar

1

Voici comment afficher la boîte de dialogue de mise en page personnalisée avec un élément de liste personnalisé, peut être personnalisé selon vos besoins.

entrez la description de l'image ici

ÉTAPE - 1 Créez la disposition de la boîte de dialogue, c'est-à-dire: -

R.layout.assignment_dialog_list_view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rectangle_round_corner_assignment_alert"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv_popup_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:singleLine="true"
        android:paddingStart="4dp"
        android:text="View as:"
        android:textColor="#4f4f4f" />

    <ListView
        android:id="@+id/lv_assignment_users"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

ÉTAPE - 2 Créez une disposition d'élément de liste personnalisée selon votre logique métier

R.layout.item_assignment_dialog_list_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:padding="4dp"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/iv_user_profile_image"
        android:visibility="visible"
        android:layout_width="42dp"
        android:layout_height="42dp" />
    <TextView
        android:id="@+id/tv_user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="8dp"
        android:layout_marginStart="8dp"
        android:paddingBottom="8dp"
        android:textColor="#666666"
        android:textSize="18sp"
        tools:text="ABCD XYZ" />
</LinearLayout>

ÉTAPE - 3 Créez une classe de modèle de données de votre choix

public class AssignmentUserModel {

private String userId;
private String userName;
private String userRole;
private Bitmap userProfileBitmap;

public AssignmentUserModel(String userId, String userName, String userRole, Bitmap userProfileBitmap) {
    this.userId = userId;
    this.userName = userName;
    this.userRole = userRole;
    this.userProfileBitmap = userProfileBitmap;
}


public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getUserRole() {
    return userRole;
}

public void setUserRole(String userRole) {
    this.userRole = userRole;
}

public Bitmap getUserProfileBitmap() {
    return userProfileBitmap;
}

public void setUserProfileBitmap(Bitmap userProfileBitmap) {
    this.userProfileBitmap = userProfileBitmap;
}

}

ÉTAPE - 4 Créez un adaptateur personnalisé

public class UserListAdapter extends ArrayAdapter<AssignmentUserModel> {
private final Context context;
private final List<AssignmentUserModel> userList;

public UserListAdapter(@NonNull Context context, int resource, @NonNull List<AssignmentUserModel> objects) {
    super(context, resource, objects);
    userList = objects;
    this.context = context;
 }

@SuppressLint("ViewHolder")
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.item_assignment_dialog_list_layout, parent, false);
    ImageView profilePic = rowView.findViewById(R.id.iv_user_profile_image);
    TextView userName = rowView.findViewById(R.id.tv_user_name);
    AssignmentUserModel user = userList.get(position);

    userName.setText(user.getUserName());

    Bitmap bitmap = user.getUserProfileBitmap();

    profilePic.setImageDrawable(bitmap);

    return rowView;
}

}

ÉTAPE - 5 Créez cette fonction et fournissez ArrayList du modèle de données ci-dessus dans cette méthode

// Pass list of your model as arraylist
private void showCustomAlertDialogBoxForUserList(ArrayList<AssignmentUserModel> allUsersList) {
        final Dialog dialog = new Dialog(mActivity);
        dialog.setContentView(R.layout.assignment_dialog_list_view);
        if (dialog.getWindow() != null) {
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // this is optional
        }
        ListView listView = dialog.findViewById(R.id.lv_assignment_users);
        TextView tv = dialog.findViewById(R.id.tv_popup_title);
        ArrayAdapter arrayAdapter = new UserListAdapter(context, R.layout.item_assignment_dialog_list_layout, allUsersList);
        listView.setAdapter(arrayAdapter);
        listView.setOnItemClickListener((adapterView, view, which, l) -> {
            Log.d(TAG, "showAssignmentsList: " + allUsersList.get(which).getUserId());
           // TODO : Listen to click callbacks at the position
        });
        dialog.show();
    }

Étape - 6 Donner l'arrière-plan du coin arrondi à la boîte de dialogue

@ drawable / rectangle_round_corner_assignment_alert

    <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffffff" />
    <corners android:radius="16dp" />
    <padding
        android:bottom="16dp"
        android:left="16dp"
        android:right="16dp"
        android:top="16dp" />
</shape>

0

N'est-il pas plus simple de faire une méthode à appeler après la création de l'unité EditText dans un AlertDialog, pour une utilisation générale?

public static void EditTextListPicker(final Activity activity, final EditText EditTextItem, final String SelectTitle, final String[] SelectList) {
    EditTextItem.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle(SelectTitle);
            builder.setItems(SelectList, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialogInterface, int item) {
                    EditTextItem.setText(SelectList[item]);
                }
            });
            builder.create().show();
            return false;
        }
    });
}

0
private void AlertDialogue(final List<Animals> animals) {
 final AlertDialog.Builder alertDialog = new AlertDialog.Builder(AdminActivity.this);
 alertDialog.setTitle("Filter by tag");

 final String[] animalsArray = new String[animals.size()];

 for (int i = 0; i < tags.size(); i++) {
  animalsArray[i] = tags.get(i).getanimal();

 }

 final int checkedItem = 0;
 alertDialog.setSingleChoiceItems(animalsArray, checkedItem, new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialog, int which) {

   Log.e(TAG, "onClick: " + animalsArray[which]);

  }
 });


 AlertDialog alert = alertDialog.create();
 alert.setCanceledOnTouchOutside(false);
 alert.show();

}

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.
Piotr Labunski
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.