web-dev-qa-db-fra.com

Obtenir la date de datepicker à l'aide de dialogfragment

J'utilise l'exemple de Google pour insérer un datepicker dans mon application à l'aide d'un dialogfragment
http://developer.Android.com/guide/topics/ui/controls/pickers.html

Mais je ne suis pas sûr de savoir comment obtenir la date après celle-ci (pas un expert en Java). La boîte de dialogue et le sélecteur de date fonctionnent correctement et je peux noter que la date est correctement définie, mais comment puis-je exécuter un rappel sur une activité parent?

Ceci est mon fragment de dialogue

public class DatePickerFragment extends DialogFragment implements
        DatePickerDialog.OnDateSetListener {

    @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);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        **Log.w("DatePicker","Date = " + year);**
    }
}

... et j'appelle dialoguer depuis mon activité avec ...

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getSupportFragmentManager(), "datePicker");
}

Quelle est la bonne façon d'appeler une méthode de mon activité parent à la place de Log.w? Je suppose que cela a quelque chose à voir avec le passage d'un callback en tant que paramètre ou quelque chose mais la plupart des références que j'ai trouvées sur Internet concernent des versions précédentes sans dialogues

EDIT: ne sais pas si c'est important mais l'activité parent est déclarée comme:

public class EditSessionActivity extends FragmentActivity {

SOLUTION: grâce à l'utilisateur de Lecho, voici comment procéder

DatePickerFragmennt.class

public class DatePickerFragment extends DialogFragment{

    @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);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);
    }

}

... et l'activité parent EditSessionActivity.class ...

public class EditSessionActivity extends FragmentActivity implements OnDateSetListener {
...
    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        //do some stuff for example write on log and update TextField on activity
        Log.w("DatePicker","Date = " + year);
        ((EditText) findViewById(R.id.tf_date)).setText("Date = " + year);
    }
49
Gonzalo Cao

Le constructeur de DatePickerDialog prend DatePickerDialog.OnDateSetListener en deuxième paramètre. Vous devriez donc peut-être implémenter cette interface dans votre activité parent EditSessionActivity (pas dans DatePickerFragment) et modifier cette ligne:

return new DatePickerDialog(getActivity(), this, year, month, day);

dans ceci:

return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);

Et alors votre activité devrait ressembler à ceci:

public class EditSessionActivity extends FragmentActivity implements
        DatePickerDialog.OnDateSetListener{

    public void onDateSet(DatePicker view, int year, int month, int day) {
        //use date in your activity
    }
    ...
}
63
Leszek

Je remplace simplement onDateSet dans la création du sélecteur de date dans ma classe qui affiche un sélecteur de date .

  private OnClickListener onDateClicked() {
    return new OnClickListener() {
          @Override
          public void onClick(View v) {
             DialogFragment newFragment = new DatePickerFragment() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int day) {
                  salePaymentCustomView.setBtDateText("" + day + "/" + month+1 + "/" + year);
                }
             };
             newFragment.show(getActivity().getSupportFragmentManager(), "datePicker");
    }
  };
 } 
25
Vinicius Paldês

Le problème peut également être résolu sans déplacer la méthode onDateSet vers l'activité parent. Il vous suffit de dire à la DatePickerFragment où chercher la vue:

public class DatePickerFragment extends DialogFragment implements
    DatePickerDialog.OnDateSetListener {

    @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);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // do some stuff for example write on log and update TextField on activity
        Log.w("DatePicker","Date = " + year);
        ((TextView) getActivity().findViewById(R.id.tf_date)).setText("Date = " + year);
    }
}

J'ai également changé la cible de la distribution de EditText à TextView. De cette façon, vous pouvez réutiliser votre implémentation pour différents types de vues, pas seulement pour une EditText.

13
steps

j'ai une correction à la réponse ci-dessus ... au lieu de renvoyer le DatePickerDialog comme ceci 

renvoyer le nouveau DatePickerDialog (getActivity (), (EditSessionActivity) getActivity (), année, mois, jour);

vous devriez le retourner d'une manière plus générique 

renvoyer un nouveau DatePickerDialog (getActivity (), (OnDateSetListener) getActivity (), année, mois, jour);

assurez-vous simplement que votre activité implémente l'interface OnDateSetListener et remplacez la fonction onDateSet 

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) 
9
Benny Margalit
public void onDate(View view) {

        DialogFragment fragment = new SelectDateFragment();
        fragment.show(getFragmentManager(), "Date Picker");
    }

//  @SuppressLint("NewApi")
    class SelectDateFragment extends DialogFragment implements
            DatePickerDialog.OnDateSetListener {

        public Dialog onCreateDialog(Bundle savedInstanceState) {


            System.out.println("entrering on create dialog");;

            return new DatePickerDialog(getActivity(), this, mYear, mMonth,
                    mDay);//it will return dialog setting date with mYera,MMonth and MDay

        }

        @Override
        public void onDateSet(Android.widget.DatePicker view, int year,
                int monthOfYear, int dayOfMonth) {
            System.out.println("year=" + year + "day=" + dayOfMonth + "month="
                    + monthOfYear);
            mYear=year;
            mMonth=monthOfYear;
            mDay=dayOfMonth;

            onPopulateSet(year, monthOfYear + 1, dayOfMonth);

        }
// set the selected date in the edit text  
        private void onPopulateSet(int year, int i, int dayOfMonth) {
            EditText et_setDate;
            et_setDate = (EditText) findViewById(R.id.register_et_dob);//register_et_dob:-id name of the edit text 
            et_setDate.setText(dayOfMonth + "/" + i + "/" + year);
            System.out.println("enetring on populate Set");

        }
3
Harsh Parikh

La réponse de Leszek fonctionne, mais pas si le dialogue est lancé à partir d'un autre fragment. Dans ce cas, vous devez utiliser setTargetFragment() dans le code qui crée la boîte de dialogue et getTargetFragment() dans son code.

Dans le code qui crée le dialogue:

DialogFragment dialogFragment = new YourDialogFragment();
dialogFragment.setTargetFragment(YourParentFragment.this, 0);
dialogFragment.show(getFragmentManager(), "mydialog");

Dans le code DialogFragment:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener()
    {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
        {
            YourParentFragment parentFragment = (YourParentFragment) getTargetFragment();
            // Manipulate the parent fragment
            // ...
        }
    };
    // Get the initial date
    // ...
    return new DatePickerDialog(getActivity(), listener, year, month, day);
}
2
wvdz

J'avais un problème similaire à celui-ci, mais mon sélecteur de date était lancé à partir d'un fragment de boîte de dialogue contenu dans un autre fragment. Cela rendait très difficile de jouer avec les rappels, car ils voulaient revenir à l'activité principale et je voulais que les données reviennent au fragment de dialogue précédent.

Initialement, j'avais transmis les nouvelles valeurs de date à l'activité principale (à l'aide de OnDateSetListener) et je voulais les obtenir à l'aide de la boîte de dialogue qui a lancé le sélecteur de date, mais aucun événement de cycle de vie n'est déclenché à la fermeture du sélecteur de date.

Le résultat auquel je suis arrivé était dans onDismiss dans le sélecteur de date, instanciait un nouveau fragment de boîte de dialogue, appelait une méthode de résultats d'ensemble et le lançait ensuite. Bien sûr, pour cela, vous devez vous assurer que le fragment précédent est ignoré lors du lancement du sélecteur de date.

C'est le dialogFragment qui a appelé le sélecteur de date

public class NewTrialDialogFragment extends DialogFragment  {

public final String LOG_TAG = "NewTrialDialog Fragment";

Button startDateButton;
Integer newYear, newMonth, newDay;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.dialog_new_trial, container, false);
    getDialog().setTitle("Dialog New Trial");

    startDateButton = (Button) rootView.findViewById(R.id.button_start_date);
    startDateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showDatePickerDialog(v);
        }
    });

    //If you exit the datepicker without choosing anything, it returns zeros
    if (newYear != null && newMonth != null && newDay != null && newYear != 0) {
        startDateButton.setText(newYear + " " + newMonth + " " + newDay);
    }else{
        startDateButton.setText("Select Start Date");
    }

     return rootView;
}

public void showDatePickerDialog(View v) {
    TrialDatePickerDialog newDialog = new TrialDatePickerDialog();
    newDialog.show(getActivity().getSupportFragmentManager(), "datePicker");
    this.dismiss();
}

public void setDates(int year, int month, int day){
    newYear = year;
    newMonth = month;
    newDay = day;
}}

Et le sélecteur de date

public  class TrialDatePickerDialog extends DialogFragment implements DatePickerDialog.OnDateSetListener
     {

private final String LOG_TAG = "TrialDatePickerDialog";
int newYear, newMonth, newDay;


@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);

    // Create a new instance of TrialDatePickerDialog and return it
    return new DatePickerDialog(getActivity(), this , year, month, day);
}

         @Override
         public void onDismiss(DialogInterface dialog) {
             super.onDismiss(dialog);
             FragmentManager fm = getActivity().getSupportFragmentManager();
             NewTrialDialogFragment newTrialDialogFragment = new NewTrialDialogFragment();
             newTrialDialogFragment.setDates(newYear, newMonth, newDay);
             newTrialDialogFragment.show(fm, "new_trial_dialog");

         }

         @Override
         public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
             newYear = year;
             newMonth = monthOfYear;
             newDay = dayOfMonth;
         }
     }
0
Matt

Si vous devez renvoyer un résultat à un fragment, mais pas une activité, voici une solution complète:

public class DatePickerDialogFragment extends DialogFragment  {

    private static final String ARGUMENT_YEAR = "ARGUMENT_YEAR";
    private static final String ARGUMENT_MONTH = "ARGUMENT_MONTH";
    private static final String ARGUMENT_DAY = "ARGUMENT_DAY";
    private DatePickerDialog.OnDateSetListener listener;

    private int year;
    private int month;
    private int dayOfMonth;

    public static DatePickerDialogFragment newInstance(final int year, final int month, final int dayOfMonth) {
        final DatePickerDialogFragment df = new DatePickerDialogFragment();
        final Bundle args = new Bundle();
        args.putInt(ARGUMENT_YEAR, year);
        args.putInt(ARGUMENT_MONTH, month);
        args.putInt(ARGUMENT_DAY, dayOfMonth);
        df.setArguments(args);
        return df;
    }

    @Override
    public void onCreate(@Nullable final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        retrieveArguments();
    }

    private void retrieveArguments() {
        final Bundle args = getArguments();
        if (args != null) {
            year = args.getInt(ARGUMENT_YEAR);
            month = args.getInt(ARGUMENT_MONTH);
            dayOfMonth = args.getInt(ARGUMENT_DAY);
        }
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {
        return new DatePickerDialog(getContext(), this.listener, this.year, this.month, this.dayOfMonth);
    }

    public void setListener(final DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }
}

Ensuite, utilisez-le simplement dans un fragment ou une activité:

final Calendar c = Calendar.getInstance();
DatePickerDialogFragment datePicker = DatePickerDialogFragment.newInstance(
        c.get(Calendar.YEAR),
        c.get(Calendar.MONTH),
        c.get(Calendar.DAY_OF_MONTH));
datePicker.setListener(this);
datePicker.show(getChildFragmentManager(), null);
0
Leo Droidcoder