17

I want to know is there a way to create a datePicker in a fragment? I am creating one the regular activity may and it gives me syntax error. What is the correct way to do this?

yoshi24
  • 3,147
  • 8
  • 45
  • 62

5 Answers5

23

Expanding on Codejoy's answer:

Here is my DatePickerDialogFragment class:

public class DatePickerDialogFragment extends DialogFragment {
    private Fragment mFragment;

    public DatePickerDialogFragment(Fragment callback) {
        mFragment = callback;
    }

     public Dialog onCreateDialog(Bundle savedInstanceState) {
         return new DatePickerDialog(getActivity(), (OnDateSetListener) mFragment, 1980, 7, 16);
     }
}

(Notice that the constructor accepts the fragment that is using this dialog - and that we use this reference for the callback listener field for DatePickerDialog)

My fragment then just implements onDateSetListener:

public class SignupFragment extends Fragment implements OnDateSetListener {
...
public void onDateSet(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {
    // do stuff with the date the user selected
}
}

... and then I show the dialog from my Fragment like so:

FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = new DatePickerDialogFragment(this);
newFragment.show(ft, "dialog");

Not sure if this is the best way to do it, but seems to work fine.

NPike
  • 13,136
  • 12
  • 63
  • 80
  • I have an edittext which should have a date on it. I setted on the onClicklistener from this edittext to open this fragment the way you did, and it is working. The problem is that the keyboard also opens. How can I solve that? Thank you – Paulo Barros Nov 16 '11 at 09:01
  • @PauloBarros "prev" was to remove any previous fragments on the screen with this tag (such as another dialog), but was not used in this example. I have updated the code to not have it. – NPike Dec 30 '11 at 20:13
  • 4
    I believe this code will crash on a screen rotation because the DialogFragment does not have a default empty constructor. – emmby Apr 23 '12 at 03:47
  • @emmby thats correct, I neglected to add the default constructor in my example. – NPike Apr 26 '12 at 22:01
  • 1
    I don't think that just adding a default constructor will fix it though, since you no longer have access to the callback fragment after the dialog fragment has been recreated – emmby Apr 26 '12 at 22:15
  • I followed this approach before reading the comments about the need for an empty constructor. Indeed, rotating the device causes a fragment instantiation exception ("make sure class name exists, is public, and has an empty constructor that is public"). See also http://androidchef.wordpress.com/2011/06/03/fragments-constructors-arguments-and-callbacks. QUESTION: Any ideas how to modify this code to use fragment arguments so the code is more robust? – gcl1 Sep 06 '12 at 15:34
17

Though above answers might work, I believe I have a much easier solution:

DatePickerDialog dialog = new DatePickerDialog(getActivity(), datePickerListener, 
                             2000, 1,1);
dialog.show();

Where datePickerListerener is something like this:

private DatePickerDialog.OnDateSetListener datePickerListener 
            = new DatePickerDialog.OnDateSetListener() {

        // when dialog box is closed, below method will be called.
        public void onDateSet(DatePicker view, int selectedYear,
            int selectedMonth, int selectedDay) {
            //Do whatever you want
        }
};
Bart Burg
  • 4,786
  • 7
  • 52
  • 87
5

Previous anwsers are explaining good enough but here is how I changed the view onDateSet method of DialogFragment.

You can pass the view you want to change to the constructer of class extending DialogFragment. Then call setText method onDateSet method of the class. Here is the code:

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

public EditText activity_edittext;

public DatePickerFragment(EditText edit_text) {
    activity_edittext = edit_text;
}

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

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        activity_edittext.setText(String.valueOf(month + 1 ) + "/" + String.valueOf(day) + "/" + String.valueOf(year));
    }
}

Then you can show your fragment like this:

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

Set this method onClick method of EditText you want to change. Like this:

    <EditText
            android:id="@+id/editTextToShowDate"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:focusable="false"
            android:inputType="date"
            android:onClick="showDatePickerDialog" >
   </EditText>
4

You will most likely need to use a DialogFragment. I found some information here:

Show dialog from fragment?

and also a big help here:

https://github.com/commonsguy/cw-advandroid/blob/master/Honeycomb/FeedFragments/src/com/commonsware/android/feedfrags/AddFeedDialogFragment.java

This should help you get on your way, I am doing this very thing now. Though inside the example code I don't use a builder and instead just return:

return new DatePickerDialog(getActivity(), mDateSetListener, mYear, mMonth, mDay);

This seems to work... though I cannot figure out yet how to update the text on the fragment that calls this DialogFragment. I thought this would work and it doesn't:

 public void updateDisplay()
 {
     //update our button text from the calling fragment, this isn't quite working
     //doesn't crash just doesn't update...must be missing something.
     View v=getActivity()
        .getLayoutInflater()
        .inflate(R.layout.session_edits, null);
     Button sessionDate = (Button)v.findViewById(R.id.sessionPickDate);
            sessionDate.setText(new StringBuilder()
                            .append(mMonth+1).append("-").append(mDay).append("-").append(mYear).append(" "));

 }
Community
  • 1
  • 1
Codejoy
  • 3,722
  • 13
  • 59
  • 99
1

Here is a snippet in would like to use the datepicker in a fragment:

private Callbacks mCallbacks;
private String tag;

/**
 * A callback interface that all fragments/activities containing this fragment must
 * implement. This mechanism allows activities to be notified of item
 * selections.
 */
public interface Callbacks {
    /**
     * Callback for when an item has been selected.
     */
    public void onSelected(Date date, String tag);
}





  public static DatePickerFragment newInstance(Fragment fragment, 
                                               Date date, String tag)         {
    DatePickerFragment dateFragment = new DatePickerFragment();
    Calendar c = Calendar.getInstance();
    if (date != null) {
        c.setTime(date);
    }
    dateFragment.setYear(c.get(Calendar.YEAR));
    dateFragment.setMonth(c.get(Calendar.MONTH));
    dateFragment.setDay(c.get(Calendar.DAY_OF_MONTH));
    dateFragment.setmCallbacks((Callbacks) fragment);
    dateFragment.setTag(tag);
    return dateFragment;
}

public void onDateSet(DatePicker view, int year, int month, int day) {
    // Do something with the date chosen by the user
    Calendar cal = Calendar.getInstance();
    cal.set(year, month, day);
    date = new Date(cal.getTime().getTime());
    setType(1);
    mCallbacks.onSelected(date,tag);
}

and in your fragment:

   public class DetailFragment extends Fragment implements
    DatePickerFragment.Callbacks {

. . .

    private void startDatePicker(String tag) {

    DialogFragment newFragment = DatePickerFragment.newInstance(this,
            invoiceModell.getInvoice().getInvoiceDate(), tag);
    newFragment.show(getActivity().getSupportFragmentManager(),
            "datePicker");
}


    @Override
public void onSelected(Date date, String tag) {
    if (tag.equals(FIRSTDATE))
        invoiceModell.getInvoice().setInvoiceDate(date);
    else if (tag.equals(SECONDDATE))
        invoiceModell.getInvoice().setDueDate(date);
}
Skywalker
  • 1,717
  • 1
  • 22
  • 25