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);
}
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
}
...
}
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");
}
};
}
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
.
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)
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");
}
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);
}
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;
}
}
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);