I have a custom class called DatePicker who extends DialogFragment and implements DatePickerDialog.OnDateSetListener, but my problem is because y need to listen the onDateChangeMethod and the DialogFragment only have DialogInterface.OnCancelListener and DialogInterface.OnDismissListener.
How can I do that? I tried to implement OnDateChangedListener and override the onDateChange method but it did not work. Here is the code:
public class DatePicker extends DialogFragment implements
DatePickerDialog.OnDateSetListener, OnDateChangedListener {
private OnDateSetListener _onDateSetListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
_onDateSetListener = (OnDateSetListener) activity;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Date initialValue = null;
String[] buttons = getArguments().getStringArray("buttons");
Long initialValueLong = getArguments().getLong("initialValue");
if (initialValue == null) {
initialValue = new Date();
}
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTimeInMillis(initialValueLong);
DatePickerDialog dialog = new DatePickerDialog(getActivity(), this,
calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE));
return dialog;
}
#Override
public void onDateSet(android.widget.DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
_onDateSetListener.onDateSet(new GregorianCalendar(year, monthOfYear,
dayOfMonth).getTime(), getArguments().get("tag"));
}
#Override
public void onDateChanged(android.widget.DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
// THIS METHOD NEVER CALLED
}
}
It looks like you haven't declared an onDateSetListener in your class, and you're also casting the host activity to the wrong type. The Dialog class itself should be the OnDateSetListener, and the host activity should be cast to something else.
Try to structure the class like this:
public class DatePickerDialogFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener
{
public static interface DatePickedListener
{
public void onDatePicked(int selectedYear, int selectedMonth, int selectedDay);
}
private DatePickedListener listener;
#Override
public void onAttach(Activity activity)
{
// when the fragment is initially attached to the activity, cast the
// activity to the callback interface type
super.onAttach(activity);
try
{
listener = (DatePickedListener) activity;
}
catch (ClassCastException e)
{
throw new ClassCastException(activity.toString() + " must implement " + DatePickedListener.class.getName());
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
Bundle b = getArguments();
int year = b.getInt("set_year");
int month = b.getInt("set_month");
int day = b.getInt("set_day");
return new DatePickerDialog(getActivity(), this, year, month, day);
}
#Override
public void onDateSet(DatePicker view, int setYear, int setMonth, int setDay)
{
// when the date is selected, send it to the activity via its callback interface method
listener.onDatePicked(setYear, setMonth, setDay);
}
}
I found the solution, just only need to get de DatePicker and set DatePicker.init method
android.widget.DatePicker datePicker = dialog.getDatePicker();
datePicker.init(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE),
new OnDateChangedListener() {
public void onDateChanged(android.widget.DatePicker view,
int year, int month, int day) {
_onDateSetListener.dateChange(new GregorianCalendar(
year, month, day).getTime(), getArguments()
.get("tag"));
}
});
Related
I'm creating an app with two DatePicker to set a start and an end dates. As the DatePicker are called from DialogFragments, I set two tags to differentiate the results in the main activity:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sel_start_date:
DialogFragment startDatePicker = new DatePickerFragment();
startDatePicker.show(getSupportFragmentManager(), START_DATE_PICKER_TAG);
break;
case R.id.sel_end_date:
DialogFragment endDatePicker = new DatePickerFragment();
endDatePicker.show(getSupportFragmentManager(), END_DATE_PICKER_TAG);
break;
The DatePickerFragment class:
public class DatePickerFragment extends DialogFragment {
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(), year, month, day );
}
and this is how I get the result in the main activity
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
if (view.getTag().equals(START_DATE_PICKER_TAG)) {
calendarStartDate.set(Calendar.YEAR, year);
calendarStartDate.set(Calendar.MONTH, month);
calendarStartDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
start_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
} else {
calendarEndDate.set(Calendar.YEAR, year);
calendarEndDate.set(Calendar.MONTH, month);
calendarEndDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
end_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
}
}
However, I get a nullPointerException doing view.getTag(). How can I solve this, or how else can I diferentiate the results?
Aclaration: DatePickerDialog is a native class, not one which I created, so I can't edit their methods`
TimePickerFragment:
public class TimePickerFragment extends DialogFragment {
private static final String ARGS_TAG = "ARGS_TAG";
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
final String tag = getArguments().getString(ARGS_TAG);
return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(), hour, minute, android.text.format.DateFormat.is24HourFormat(getActivity())) {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
};
}
public static TimePickerFragment newInstance(String tag){
Bundle args = new Bundle();
args.putString(ARGS_TAG, tag);
TimePickerFragment fragment = new TimePickerFragment();
fragment.setArguments(args);
return fragment;
}
Solution: Define two interface to forward data from fragments to activity.
Step 1. Define OnDateSetListener interface to communicate between MainActivity and DatePickerFragment.
public interface OnDateSetListener {
void onDateSet(String tag, DatePicker view, int year, int month, int dayOfMonth);
}
Step 2. Define OnTimeSetListener interface to communicate between MainActivity and TimePickerFragment.
public interface OnTimeSetListener {
void onTimeSet(String tag, TimePicker view, int hourOfDay, int minute);
}
Step 3. Let MainActivity implements both of interfaces.
public class MainActivity extends AppCompatActivity implements OnDateSetListener, OnTimeSetListener {
// Your code her
...
#Override
public void onDateSet(String tag, DatePicker view, int year, int month, int dayOfMonth) {
// Process code with tag here
}
#Override
public void onTimeSet(String tag, TimePicker view, int hourOfDay, int minute) {
// Process code with tag here.
}
}
Step 4. Change code in DatePickerFragment
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
private static final String ARGUMENT_TAG = "ARGUMENT_TAG";
public static DatePickerFragment newInstance(String tag) {
Bundle args = new Bundle();
args.putString(ARGUMENT_TAG, tag);
DatePickerFragment fragment = new DatePickerFragment();
fragment.setArguments(args);
return fragment;
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(requireActivity(), this, year, month, day);
}
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
final String tag = getArguments().getString(ARGUMENT_TAG);
OnDateSetListener listener = (OnDateSetListener) requireActivity();
listener.onDateSet(tag, view, year, month, dayOfMonth);
}
}
Step 5. Change code in TimePickerFragment.
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
private static final String ARGS_TAG = "ARGS_TAG";
public static TimePickerFragment newInstance(String tag) {
Bundle args = new Bundle();
args.putString(ARGS_TAG, tag);
TimePickerFragment fragment = new TimePickerFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
return new TimePickerDialog(requireActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
final String tag = getArguments().getString(ARGS_TAG);
OnTimeSetListener listener = (OnTimeSetListener) requireActivity();
listener.onTimeSet(tag, view, hourOfDay, minute);
}
}
As I see, you've set the tag to the Fragment, but what you're trying to get is the tag of the View. They are not the same thing, as a view's tag is an object, while a fragment's tag is a string.
As you can see your view in onDateSet is a DatePicker, and you set your tag on the fragment containing the DatePicker, which is the DatePickerDialog.
So to get your tag you should try something like:
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
if (view.getParent() != null && view.getParent().getTag().equals(START_DATE_PICKER_TAG)) {
calendarStartDate.set(Calendar.YEAR, year);
calendarStartDate.set(Calendar.MONTH, month);
calendarStartDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
start_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
} else {
calendarEndDate.set(Calendar.YEAR, year);
calendarEndDate.set(Calendar.MONTH, month);
calendarEndDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
end_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
}
}
I have managed to make a date picker class but now I want the value from the date picker dialog to be returned to the main activity class. Below is the code for the date picker dialog.
public class DateChooser extends DialogFragment implements DatePickerDialog.OnDateSetListener{
public int y,m,d;
public Dialog onCreateDialog(Bundle savedInstanceState)
{
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);
return new DatePickerDialog(getContext(),this,year,month,day);
}
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
Toast.makeText(getContext(), "Toast!", Toast.LENGTH_SHORT).show();
setDay(dayOfMonth);
setMonth(month);
setYear(year);
}
I have called this class from the mainactivity.
public void dateSelect(View view)
{
DateChooser dateC = new DateChooser();
dateC.show(getSupportFragmentManager(),"tag");
}
Do this:
Add this to DateChooser Class:
private DateSelectedListener mListener;
#Override
public void onDateSet(DatePicker view, int year, int month, int day) {
// Do something with the date chosen by the user
mListener.onDateSelected(view, year, month, day);
}
public void display(FragmentManager manager, String tag, DateSelectedListener listener) {
super.show(manager, tag);
mListener = listener;
}
public interface DateSelectedListener {
void onDateSelected(DatePicker view, int year, int month, int day);
}
in your Activity do this:
public class MyActivity extends AppCompatActivity implements DateChooser.DateSelectedListener {
//onCreate or whatever other method:
dateChooser.display(
getActivity().getSupportFragmentManager(),
"datePicker", this);
}
Good luck!!!
DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker1);
int day = datePicker.getDayOfMonth();
int month = datePicker.getMonth() + 1;
int year = datePicker.getYear();
String dateInString=year+"-"+month+"-"+day;
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = formatter.parse(dateInString);
System.out.println(date);
You can create an interface e.g. like this
public interface DateListener {
void onDateSelected(int day, int month, int year);
}
and implement it in your activity
public class YourActivity extends Activity implements DateListener {...}
then you have to implement the method in your activity...
In your Fragment add the following field:
private DateListener dateListener;
and add this code to your Fragment's onAttach:
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (!(getActivity() instanceof DateListener)) {
throw new ClassCastException("The activity inflating this fragment must implement DateListener!");
}
dateListener = (DateListener) getActivity();
}
Now you have set your activity as DateListener and can use it in the result of the DatePicker
I have DatepickerFragment which extends from DialogFragment. In my main fragment there are two edittext.The first one is for starting date and the second is for finising date. These are for some user operations.User clicks first edittext choose date and the other one is same way But i confused about how to handle edittexts on DatepickerFragment.What is best way for it ?
etOverFlowingStaringDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getActivity().getFragmentManager();
DatePickerFragment datePickerFragment = new DatePickerFragment();
datePickerFragment.show(fragmentManager, "datepicker");
}
});
DatepickerFragment.java
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);
}
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
populateSetDate(year, monthOfYear+1, dayOfMonth);
}
private void populateSetDate(int year, int month, int dayOfMonth) {
String datetime = dayOfMonth + "/" + month + "/" + year ;
//EditText edtext = (EditText)getView().findViewById(R.id.overflow_starting_date);
// The edittext is changable it is not a good way to define in here
}
}
I usually create my custom DatePickerFragments in a separate class and then use the Listener model to implement what you are trying to achieve. Essentially:
In your DatePickerFragment, define an interface -
public interface OnDateChosenListener {
void onDateChosen(int year, int month, int day);
}
Then, define a private variable within your DatePickerFragment class for that interface -
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
private OnDateChosenListener mOnDateChosenListener = null;
...
Add a function to set an OnDateChosenListener -
public void setOnDateChosenListener(OnDateChosenListener listener) {
mOnDateChosenListener = listener;
}
Final thing for the DatePickerFragment class, pass along event and values to the listener if it exists -
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
if (mOnDateChosenListener != null) {
mOnDateChosenListener.onDateChosen(year, monthOfYear, dayOfMonth);
}
}
Lastly, MOST IMPORTANT. Remember to add a listener wherever you use the new DatePickerFragment, in your case, an Activity -
FragmentManager fragmentManager = getActivity().getFragmentManager();
DatePickerFragment datePickerFragment = new DatePickerFragment();
datePickerFragment.addOnDateChosenListener(new OnDateChosenListener() {
public void onDateChosen(int year, int month, int day) {
// use values to change EditText value
}
}
datePickerFragment.show(fragmentManager, "datepicker");
The Listener model is a good practice and is widely used in the Android framework.
I am not sure if I understand your question very well, but are you trying to get the date on the EditText once the user selects it? If that's the case...
Create an interface that will receive your date in your activity/fragment:
interface DateReceiver {
void update(int year, int month, int day);
}
Implement your activity/fragment, then implement the method:
#Override
public void update(int year, int month, int day) {
String date = //format your date here;
this.editText.setText(date);
}
If you add the onClickListener to your editText...:
etOverFlowingStaringDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatePickerFragment fragment = new DatePickerFragment();
fragment.setReceiver(MainActivity.this); //assuming your activity is called MainActivity.this. 'this' alone won't work.
fragment.show(this.getFragmentManager(), "datePicker"); //do getActivity().getFragmentManager in a Fragment
}
});
As you may have noticed, I wrote fragment.setReceiver(MainActivity.this). This method is created and defined below.
Then, you should coninue by implementing your DatePickerFragment as follows:
public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
private DateReceiver receiver;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int year = TransactionUtils.getFragment().mYearChosen;
int month = TransactionUtils.getFragment().mMonthChosen;
int day = TransactionUtils.getFragment().mDayChosen;
//If you want the minimum date to be today...
DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, year, month, day);
datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
return datePickerDialog;
}
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
updateDate(year, monthOfYear, dayOfMonth);
}
public void setReceiver(DateReceiver receiver) {
this.receiver = receiver;
}
private void updateDate(int year, int monthOfYear, int dayOfMonth) {
if (receiver != null) //avoiding NullPointerExceptions :D
receiver.update(year, monthOfYear, dayOfMonth);
}
}
Calling update in private void updateDate(int,int,int) will change the date of your editText.
I am simply trying to get the date from a datepicker dialog I created from one of the many android datepicker tutorials I found online. I seem to be going wrong somewhere in the actual retrieving of the text date once it is selected. I have a DatePickerFragment class, which is called from a CreateEvent fragment which is nested inside my MainActivity activity class. This is the DatePicker:
public class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
private EditText txtDate;
#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) {
txtDate = (EditText)view.findViewById(R.id.txtDate);
txtDate.setText(day + " " + (month + 1) + " " + year);
}
}
I get Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence) on a null object reference when I actually try and set the date, which I understand means it can't actually find the edittext element in my create event fragment xml file.
How should I go about setting the text of this edittext element from onDateSet or do I have to change my approach?
I tried it this way but to no avail.
You need to use an interface to get the data from the datepicker to the caller fragment:
public interface DateListener {
void passDate(String date);
}
Create a member variable called mListener:
private DateListener mListener;
Override the onAttach & onDetach fragment methods:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (DateListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement DateListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
Next, implement this interface in the caller fragment and override the passDate method:
#Override
public void passDate(String date) {
// Do something with 'date', yourEditText.setText(date) for the example
}
And you should be good to go.
I have done this by below lines of code:
public class DatePickerDialogMy extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
DateSetting dateSetting=new DateSetting(getActivity());
Calendar calendar= Calendar.getInstance();
int year= calendar.get(calendar.YEAR);
int month=calendar.get(calendar.MONTH);
int day=calendar.get(calendar.DAY_OF_MONTH);
DatePickerDialog dialog;
dialog=new DatePickerDialog(getActivity(),dateSetting,year,month,day);
return dialog;
}
}
Second Class:
public class DateSetting implements android.app.DatePickerDialog.OnDateSetListener {
Context context;
public DateSetting(Context context){
this.context=context;
}
#Override
public void onDateSet(DatePicker view, int year, int dateSetting, int dayOfMonth) {
Toast.makeText(context, "selected date:" + dateSetting + "/" + dayOfMonth + "/" + year, Toast.LENGTH_LONG).show();
// MainActivity.test.setText(String.valueOf(dateSetting));
MyActivity.dobEditText.setText(dateSetting+"/"+dayOfMonth+ "/" + year);
}
}
How to call:
DatePickerDialogMy datePickerDialog = new DatePickerDialogMy();
datePickerDialog.show(getSupportFragmentManager(), "date_picker");
I am trying to make the date picker appear in a dialog fragment upon clicking the date field to write/set the date I selected with the use of the DatePicker. Unfortunately, each time I click, the DatePicker doesn't show up.
Below is the the code of the class:
public class UpdateGrade extends DialogFragment{
private EditText dateField;
static final int DATE_DIALOG_ID = 0;
protected Dialog onCreateDialog(int id) {
Calendar c = Calendar.getInstance();
int cyear = c.get(Calendar.YEAR);
int cmonth = c.get(Calendar.MONTH);
int cday = c.get(Calendar.DAY_OF_MONTH);
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(getActivity(), mDateSetListener, cyear, cmonth, cday);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
String date_selected =String.valueOf(monthOfYear+1)+"-"+String.valueOf(dayOfMonth)+"-"+String.valueOf(year);
dateField.setText(date_selected);
}
};
#SuppressLint("SimpleDateFormat")
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.update_grade_layout, container);
getDialog().getWindow().requestFeature(STYLE_NO_TITLE);
dateField = (EditText) view.findViewById(R.id.dateField);
dateField.setOnTouchListener(new OnTouchListener(){
#SuppressWarnings("deprecation")
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(v == dateField)
getActivity().showDialog(DATE_DIALOG_ID);
return false;
}
});
return view;
}
Thank you!
You have to define the onCreateDialog() method to return an instance of DatePickerDialog:
public static 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 something with the date chosen by the user
}
}
More information here.