Multiple DatePickers dans la même activité

Je suis absolument nouveau sur la plate-forme Android et j'ai construit une application tout en apprenant le processus de développement.

Actuellement, je travaille sur une activité dans laquelle j'ai besoin de déployer 2 sélectionneurs de date. L'une est une "Date de début" et l'autre est une "Date de fin". J'ai suivi le tutoriel DatePicker sur la page des développeurs Android ici: http://developer.android.com/resources/tutorials/views/hello-datepicker.html

Pour un DatePicker, cela fonctionne très bien.

Maintenant, mon problème est que, lorsque je réplique l'ensemble du processus pour un deuxième sélecteur de date, il apparaît très bien sur l'émulateur ainsi que sur le combiné. Mais quand, quel que soit le bouton sur lequel j'appuie sur pour sélectionner les dates, seul le premier TextView est mis à jour et le deuxième TextView continue à afficher la date actuelle.

Voici le code:

package com.datepicker; import java.util.Calendar; import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.TextView; public class datepicker extends Activity { private TextView mDateDisplay; private TextView endDateDisplay; private Button mPickDate; private Button endPickDate; private int mYear; private int mMonth; private int mDay; static final int START_DATE_DIALOG_ID = 0; static final int END_DATE_DIALOG_ID = 0; /** Called when the activity is first created. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /* capture our View elements for the start date function */ mDateDisplay = (TextView) findViewById(R.id.startdateDisplay); mPickDate = (Button) findViewById(R.id.startpickDate); /* add a click listener to the button */ mPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(START_DATE_DIALOG_ID); } }); /* get the current date */ final Calendar c = Calendar.getInstance(); mYear = c.get(Calendar.YEAR); mMonth = c.get(Calendar.MONTH); mDay = c.get(Calendar.DAY_OF_MONTH); /* display the current date (this method is below) */ updateStartDisplay(); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.enddateDisplay); endPickDate = (Button) findViewById(R.id.endpickDate); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(END_DATE_DIALOG_ID); } }); /* get the current date */ final Calendar c1 = Calendar.getInstance(); mYear = c1.get(Calendar.YEAR); mMonth = c1.get(Calendar.MONTH); mDay = c1.get(Calendar.DAY_OF_MONTH); /* display the current date (this method is below) */ updateEndDisplay(); } private void updateEndDisplay() { endDateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-") .append(mDay).append("-") .append(mYear).append(" ")); } private void updateStartDisplay() { mDateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-") .append(mDay).append("-") .append(mYear).append(" ")); } 

/ * Le rappel reçu lorsque l'utilisateur "définit" la date dans la boîte de dialogue pour la fonction de date de début * /

  private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mYear = year; mMonth = monthOfYear; mDay = dayOfMonth; updateStartDisplay(); } }; @Override protected Dialog onCreateDialog(int id) { switch (id) { case START_DATE_DIALOG_ID: return new DatePickerDialog(this, mDateSetListener, mYear, mMonth, mDay); } return null; } /* the callback received when the user "sets" the date in the dialog for the end date function */ private DatePickerDialog.OnDateSetListener endDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mYear = year; mMonth = monthOfYear; mDay = dayOfMonth; updateStartDisplay(); } }; protected Dialog onCreateDialog1(int id) { switch (id) { case END_DATE_DIALOG_ID: return new DatePickerDialog(this, endDateSetListener, mYear, mMonth, mDay); } return null; } 

}

Veuillez indiquer les changements requis pour le code.

  • ImageButton dans le widget d'écran d'Android
  • Comment obtenez-vous la couleur de sélection dans Android?
  • Android: Personnalisation des onglets sur l'état: Comment puis-je rendre un sélecteur possible?
  • Sélecteur de fond de bouton Android
  • Android: comment obtenir l'effet de lueur lorsque vous appuyez longtemps sur un élément de liste?
  • Sélecteur de couleurs Google Calendar
  • Pourquoi android: listSelector change-t-il de manière incorrecte de l'activité à l'activité
  • Android comment appliquer la forme et le sélecteur simultanément pour le bouton
  • 7 Solutions collect form web for “Multiple DatePickers dans la même activité”

    Vous devez créer deux boîtes de dialogue DatePicker distinctes

    Faire 2 auditeurs

     int from_year, from_month, from_day,to_year, to_month, to_day; //initialize them to current date in onStart()/onCreate() DatePickerDialog.OnDateSetListener from_dateListener,to_dateListener; 

    Implémentez-les …

      from_dateListener = new OnDateSetListener(){ public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { ... } } }; to_dateListener = new OnDateSetListener(){ public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { ..... } }; 

    Créez des boîtes de dialogue séparées pour les deux

     int DATE_PICKER_TO = 0; int DATE_PICKER_FROM = 1; @Override protected Dialog onCreateDialog(int id) { switch(id){ case DATE_PICKER_FROM: return new DatePickerDialog(this, from_dateListener, from_year, from_month, from_day); case DATE_PICKER_TO: return new DatePickerDialog(this, to_dateListener, to_year, to_month, to_day); } return null; } 

    J'ai une solution qui permet un nombre illimité de champs de dates sans ajouter de nouveaux types de dialogue. Lorsque l'utilisateur clique sur l'un des boutons, j'inscrit lequel TextView et Calendar sont en cours de modification avant de lancer le DatePickerDialog. OnDateSetListener de la boîte de dialogue met ensuite à jour le TextView et le calendrier enregistrés.

     import java.util.Calendar; import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; import android.app.DatePickerDialog.OnDateSetListener; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.TextView; public class MultiDatePickerActivity extends Activity { private TextView startDateDisplay; private TextView endDateDisplay; private Button startPickDate; private Button endPickDate; private Calendar startDate; private Calendar endDate; static final int DATE_DIALOG_ID = 0; private TextView activeDateDisplay; private Calendar activeDate; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.multidatepicker); /* capture our View elements for the start date function */ startDateDisplay = (TextView) findViewById(R.id.startDateDisplay); startPickDate = (Button) findViewById(R.id.startPickDate); /* get the current date */ startDate = Calendar.getInstance(); /* add a click listener to the button */ startPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(startDateDisplay, startDate); } }); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.endDateDisplay); endPickDate = (Button) findViewById(R.id.endPickDate); /* get the current date */ endDate = Calendar.getInstance(); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(endDateDisplay, endDate); } }); /* display the current date (this method is below) */ updateDisplay(startDateDisplay, startDate); updateDisplay(endDateDisplay, endDate); } private void updateDisplay(TextView dateDisplay, Calendar date) { dateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(date.get(Calendar.MONTH) + 1).append("-") .append(date.get(Calendar.DAY_OF_MONTH)).append("-") .append(date.get(Calendar.YEAR)).append(" ")); } public void showDateDialog(TextView dateDisplay, Calendar date) { activeDateDisplay = dateDisplay; activeDate = date; showDialog(DATE_DIALOG_ID); } private OnDateSetListener dateSetListener = new OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { activeDate.set(Calendar.YEAR, year); activeDate.set(Calendar.MONTH, monthOfYear); activeDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); updateDisplay(activeDateDisplay, activeDate); unregisterDateDisplay(); } }; private void unregisterDateDisplay() { activeDateDisplay = null; activeDate = null; } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, dateSetListener, activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); } return null; } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DATE_DIALOG_ID: ((DatePickerDialog) dialog).updateDate(activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); break; } } } 

    Ce type de flexibilité est utile dans une application où vous ne savez pas combien de sélectionneur de date vous aurez besoin avant l'exécution.

    En élargissant l'option d'Adam dans une interprétation du poids légèrement plus légère et potentiellement plus utile, j'ai décidé de maintenir une référence int pour l'ID de l'élément qui a instancié la requête de dialogue, puis simplement référencé dans le gestionnaire d'événements final. Cela a l'avantage supplémentaire de bien s'intégrer dans une déclaration de commutation dans cette méthode au cas où vous avez plusieurs entrées de date, mais souhaitez un formatage spécifique pour chacun ou des groupes de chacun. Tous les extraits ci-dessous sont dans ma classe d'activité directement

    Variables d'instance

     private static final int DIALOG_DATE_PICKER = 100; private int datePickerInput; 

    Gestionnaire de boîte de dialogue

     @Override public Dialog onCreateDialog(int id) { switch(id) { case DIALOG_DATE_PICKER: final Calendar c = Calendar.getInstance(); DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); return dialog; } return null; } 

    Click Listener

     private OnClickListener datePickerListener = new OnClickListener() { @Override public void onClick(View v) { datePickerInput = v.getId(); showDialog(DIALOG_DATE_PICKER); } }; 

    Manipulateur de sélection de date

     private DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { switch( datePickerInput ) { case R.id.datePicker1: ((EditText) findViewById( datePickerInput )) .setText(...); ... break; case R.id.datePicker2: ... break; default: ... break; } } }; 

    Je pense que j'ai trouvé une solution plus propre. C'est un mélange entre ce qui est conseillé par Google et les commentaires que j'ai lu ici. Dans mon cas, il fonctionne même quand il est appelé à partir d'un fragment de Viewpager. Fondamentalement, je transmet un ensemble d'arguments au fragment de dialogue lors de l'appel de la boîte de dialogue de sélection de mon fragment, tel que défini ici: Android: Passez des données (extras) à un fragment Ensuite, je récupère la valeur du lot dans ma classe DialogFragment et allume Sa valeur.

    Voici les deux auditeurs de mes boutons startDate et endDate, à partir de mon code Fragment:

      mWylStartDate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putInt("DATE",1); DialogFragment newFragment = new DatePickerFragment(); newFragment.setArguments(bundle); newFragment.show(getFragmentManager(), "datePicker"); } }); mWylEndDate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putInt("DATE",2); DialogFragment newFragment = new DatePickerFragment(); newFragment.setArguments(bundle); newFragment.show(getFragmentManager(), "datePicker"); } }); 

    Voici ma classe DatePickerFragment

     public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { static final int START_DATE = 1; static final int END_DATE = 2; private int mChosenDate; int cur = 0; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current date as the default date in the picker final Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); Bundle bundle = this.getArguments(); if(bundle != null){ mChosenDate = bundle.getInt("DATE",1); } switch (mChosenDate) { case START_DATE: cur = START_DATE; return new DatePickerDialog(getActivity(), this, year, month, day); case END_DATE: cur = END_DATE; return new DatePickerDialog(getActivity(), this, year, month, day); } return null; } @Override public void onDateSet(DatePicker datePicker, int year, int month, int day) { if(cur == START_DATE){ // set selected date into textview Log.v("Date Début","Date1 : " + new StringBuilder().append(month + 1) .append("-").append(day).append("-").append(year) .append(" ")); } else{ Log.v("Date fin","Date2 : " + new StringBuilder().append(month + 1) .append("-").append(day).append("-").append(year) .append(" ")); } } 

    }

    Vous pouvez utiliser simplement ce type

     public class MainActivity extends Activity { private TextView startDateDisplay; private TextView endDateDisplay; private Button startPickDate; private Button endPickDate; private Calendar startDate; private Calendar endDate; static final int DATE_DIALOG_ID = 0; private TextView activeDateDisplay; private Calendar activeDate; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* capture our View elements for the start date function */ startDateDisplay = (TextView) findViewById(R.id.startDateDisplay); startPickDate = (Button) findViewById(R.id.startPickDate); /* get the current date */ startDate = Calendar.getInstance(); /* add a click listener to the button */ startPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(startDateDisplay, startDate); } }); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.endDateDisplay); endPickDate = (Button) findViewById(R.id.endPickDate); /* get the current date */ endDate = Calendar.getInstance(); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(endDateDisplay, endDate); } }); /* display the current date (this method is below) */ updateDisplay(startDateDisplay, startDate); updateDisplay(endDateDisplay, endDate); } private void updateDisplay(TextView dateDisplay, Calendar date) { dateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(date.get(Calendar.MONTH) + 1).append("-") .append(date.get(Calendar.DAY_OF_MONTH)).append("-") .append(date.get(Calendar.YEAR)).append(" ")); } public void showDateDialog(TextView dateDisplay, Calendar date) { activeDateDisplay = dateDisplay; activeDate = date; showDialog(DATE_DIALOG_ID); } private OnDateSetListener dateSetListener = new OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { activeDate.set(Calendar.YEAR, year); activeDate.set(Calendar.MONTH, monthOfYear); activeDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); updateDisplay(activeDateDisplay, activeDate); unregisterDateDisplay(); } }; private void unregisterDateDisplay() { activeDateDisplay = null; activeDate = null; } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, dateSetListener, activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); } return null; } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DATE_DIALOG_ID: ((DatePickerDialog) dialog).updateDate(activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); break; } } } 

    Vous pouvez simplement utiliser le code suivant

     @Override protected Dialog onCreateDialog(int id) { /* * final Dialog d = new Dialog(this); d.set */ switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, android.R.style.Theme_Holo_Light_Dialog_MinWidth, mDateSetListener, cmYear, cmMonth, cmDay); } return null; } private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { cmYear = year; cmMonth = monthOfYear; cmDay = dayOfMonth; updateDisplay(); } }; private void updateDisplay() { String date_check = "" + new StringBuilder() // Month is 0 based so add 1 .append(cmYear).append("-").append(cmMonth + 1) .append("-").append(cmDay).append(" "); } 

    Vous pouvez appeler Dialog sur n'importe quel onclick

     showDialog(DATE_DIALOG_ID); 

    Où DATE_DIALOG_ID est déclaré comme

     static final int DATE_DIALOG_ID = 0; 

    J'espère que cela est utile.

    Vous pouvez simplement utiliser une variable d'indicateur booléen pour déterminer la vue sur laquelle vous faites l'appel.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.