this is my first post and I am trying to create a very simple tasker app, however I am having issues with (what seems to be) the onDateChanged method. It seems that it does not implement the changes even though the dialog pops up normally. There are no errors in the log and i double checked various solutions with similar functionalities, but i could not find something relevant. (minSDK 16, Target 21)
Thanks a lot in advance and I am sorry if it is something obvious.
public class DatePickerFragment extends DialogFragment {
public static final String EXTRA_DATE = "thanoschatz.com.annastodolist.date";
private Date mDate;
public static DatePickerFragment newInstance(Date mDate) {
Bundle args = new Bundle();
args.putSerializable(EXTRA_DATE, mDate);
DatePickerFragment fragment = new DatePickerFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mDate = (Date) getArguments().getSerializable(EXTRA_DATE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(mDate);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
View v = getActivity().getLayoutInflater().inflate(R.layout.dialog_date, null);
DatePicker datePicker = (DatePicker) v.findViewById(R.id.dialog_date_datepicker);
datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mDate = new GregorianCalendar(year, monthOfYear, dayOfMonth).getTime();
getArguments().putSerializable(EXTRA_DATE, mDate);
}
});
return new AlertDialog.Builder(getActivity())
.setView(v) //
.setTitle(R.string.date_picker_title) //
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sendResult(Activity.RESULT_OK);
}
})
.create();
}
private void sendResult(int resultCode) {
if (getTargetFragment() == null) return;
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE, mDate);
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
}
}
public class ToDoFragment extends Fragment {
public static final String EXTRA_TODO_ID = "thanoschatz.com.annastodolist.todo_id";
private static final String DIALOG_DATE = "date";
private static final int REQUEST_DATE = 0;
private ToDo mToDo;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mDoneCheckBox;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
UUID toDoId = (UUID)getArguments().getSerializable(EXTRA_TODO_ID);
mToDo= ToDoLab.get(getActivity()).getToDo(toDoId);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_todo, container, false);
wireTitleField(view);
wireDateButton(view);
wireSolvedCheckBox(view);
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_DATE) {
Date mDate = (Date)intent.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
mToDo.setDate(mDate);
}
}
public ToDoFragment(){
}
public static ToDoFragment newInstance(UUID mId) {
Bundle args = new Bundle();
args.putSerializable(EXTRA_TODO_ID, mId);
ToDoFragment fragment = new ToDoFragment();
fragment.setArguments(args);
return fragment;
}
private void wireDateButton(View view) {
SimpleDateFormat dateFormatter = getSimpleDateFormat();
mDateButton = (Button)view.findViewById(R.id.toDo_date);
updateDate(dateFormatter);
mDateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
DatePickerFragment datePicker = DatePickerFragment.newInstance(mToDo.getDate());
datePicker.setTargetFragment(ToDoFragment.this, REQUEST_DATE);
datePicker.show(fragmentManager, DIALOG_DATE);
}
});
}
}
There is also another way to get it to work under 5.0 and keeping your DatePicker in Calendar mode. What you can do is set to listen to the click changes on the dialog, and update your date reference. If by any chance your closing dialog handler notices that the last button clicked was "cancel" then simply ignore the change...
private String dateString; //last date saved.
private String clickedDate; //last date clicked on DatePicker
private DatePicker datePicker;
@Override
protected void onDialogClosed(boolean shouldSave) {
if (shouldSave && this.clickedDate != null) {
updateDate(this.clickedDate);
this.clickedDate = null;
}
}
@Override
public void onDateChanged(DatePicker view, int year, int month, int day) {
Calendar selected = new GregorianCalendar(year, month, day);
this.clickedDate = formatter().format(selected.getTime());
}
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
datePicker.clearFocus();
onDateChanged(datePicker, datePicker.getYear(), datePicker.getMonth(),
datePicker.getDayOfMonth());
onDialogClosed(which == DialogInterface.BUTTON_NEGATIVE);
}
private void updateDate(String s) {
dateString = s;
}
This is where the idea came from https://github.com/bostonandroid/DatePreference/blob/master/DatePreference/src/org/bostonandroid/datepreference/DatePreference.java