Embedding DatePicker inside fragment

I have below code to display the date picker inside Activity, but when I tried to convert my activity to Fragment, I get an error. I see no difference in comparing code with solutions in SO for implementing DialogFragment inside a fragment.

Could you indicate what I am missing?

MainFragment:

public class AddEntryFragment extends Fragment implements DatePickerFragment.TheListener{ EditText datpurchased; public AddEntryFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.activity_addentry, container, false); return rootView; } @Override public void onStart() { super.onStart(); datpurchased = (EditText) getView().findViewById(R.id.datepurchased); datpurchased.setOnClickListener(onClickListener); } private OnClickListener onClickListener = new OnClickListener() { @Override public void onClick(View v) { switch(v.getId()){ case R.id.datepurchased: showdate(v); break; default: break; } } }; public void showdate(View v) { DialogFragment newFragment = new DatePickerFragment(); Bundle bundle = new Bundle(); bundle.putString("dateAsText",datpurchased.getText().toString()); newFragment.setArguments(bundle); newFragment.show(getFragmentManager(), "datePicker"); } public void returnDate(String date) { datpurchased.setText(date); } } 

DatePickerFragment:

 public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { TheListener listener; public interface TheListener{ public void returnDate(String date); } @Override public Dialog onCreateDialog(Bundle savedInstanceState){ Bundle bundle = getArguments(); String date = bundle.getString("dateAsText"); int year, month, day; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd",Locale.US); df.setLenient(false); Date d = null; Calendar c=Calendar.getInstance(); try { d = df.parse(date); c.setTime(d); } catch (ParseException e) { //e.printStackTrace(); } year=c.get(Calendar.YEAR); month=c.get(Calendar.MONTH); day=c.get(Calendar.DAY_OF_MONTH); listener = (TheListener) getActivity(); return new DatePickerDialog(getActivity(), this, year, month, day); } public void onDateSet(DatePicker view, int year, int month, int day){ Calendar c = Calendar.getInstance(); c.set(year, month, day); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd",Locale.US); String formattedDate = sdf.format(c.getTime()); if (listener != null) { listener.returnDate(formattedDate); } } } 

LogCat:

 12-18 23:35:41.094: D/AndroidRuntime(1058): Shutting down VM 12-18 23:35:41.094: W/dalvikvm(1058): threadid=1: thread exiting with uncaught exception (group=0xb4a65b90) 12-18 23:35:41.124: E/AndroidRuntime(1058): FATAL EXCEPTION: main 12-18 23:35:41.124: E/AndroidRuntime(1058): Process: com.migrationdesk.mylibman, PID: 1058 12-18 23:35:41.124: E/AndroidRuntime(1058): java.lang.ClassCastException: com.migrationdesk.mylibman.NavContainer cannot be cast to com.migrationdesk.mylibman.DatePickerFragment$TheListener 12-18 23:35:41.124: E/AndroidRuntime(1058): at com.migrationdesk.mylibman.DatePickerFragment.onCreateDialog(DatePickerFragment.java:41) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.DialogFragment.getLayoutInflater(DialogFragment.java:398) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.BackStackRecord.run(BackStackRecord.java:684) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.os.Handler.handleCallback(Handler.java:733) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.os.Handler.dispatchMessage(Handler.java:95) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.os.Looper.loop(Looper.java:137) 12-18 23:35:41.124: E/AndroidRuntime(1058): at android.app.ActivityThread.main(ActivityThread.java:4998) 12-18 23:35:41.124: E/AndroidRuntime(1058): at java.lang.reflect.Method.invokeNative(Native Method) 12-18 23:35:41.124: E/AndroidRuntime(1058): at java.lang.reflect.Method.invoke(Method.java:515) 12-18 23:35:41.124: E/AndroidRuntime(1058): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) 12-18 23:35:41.124: E/AndroidRuntime(1058): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) 12-18 23:35:41.124: E/AndroidRuntime(1058): at dalvik.system.NativeStart.main(Native Method) 
+6
source share
4 answers

Try this sample code ....

 public class student extends Fragment { public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); } public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view= inflater.inflate(R.layout.layout_main, container, false); return view; } public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); edittext.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub showDatePicker(); } }); } private void showDatePicker() { DatePickerFragment date = new DatePickerFragment(); /** * Set Up Current Date Into dialog */ Calendar calender = Calendar.getInstance(); Bundle args = new Bundle(); args.putInt("year", calender.get(Calendar.YEAR)); args.putInt("month", calender.get(Calendar.MONTH)); args.putInt("day", calender.get(Calendar.DAY_OF_MONTH)); date.setArguments(args); /** * Set Call back to capture selected date */ date.setCallBack(ondate); date.show(getFragmentManager(), "Date Picker"); } OnDateSetListener ondate = new OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { edittext.setText(String.valueOf(dayOfMonth) + "-" + String.valueOf(monthOfYear+1) + "-" + String.valueOf(year)); } }; } 

Create another DatePickerFragment class.

 public class DatePickerFragment extends DialogFragment { OnDateSetListener ondateSet; private int year, month, day; public DatePickerFragment() {} public void setCallBack(OnDateSetListener ondate) { ondateSet = ondate; } @SuppressLint("NewApi") @Override public void setArguments(Bundle args) { super.setArguments(args); year = args.getInt("year"); month = args.getInt("month"); day = args.getInt("day"); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new DatePickerDialog(getActivity(), ondateSet, year, month, day); } } 
+19
source

I used the AppCompatActivity, which implements Listen Listers. Fragments arose as a necessity since I needed to encode a date range selector.

For container activity, this is a class declaration:

 public class AppCompatDateRange extends AppCompatActivity implements DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener 

And the interfaces for callbacks:

 @Override public void onDateIniSelected(String dataIni) { Log.i("data inicial:", dataIni); } @Override public void onDateFimSelected(String dataFim) { Log.i("data final:", dataFim); } 

Callbacks are strings, since dates are parameters in query selection.

Code for fragments (based on the original date fragment):

 public class DateIniRangeFragment extends Fragment { OnDateIniSelectedListener callbackIni; private DatePicker startDatePicker; public DateIniRangeFragment() { ///required empty constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } ///through this interface the fragment sends data to the container activity public interface OnDateIniSelectedListener { void onDateIniSelected(String dataIni); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ///layout for the fragment View v = inflater.inflate(R.layout.date_ini_fragment, container, false); ///initial date for the picker, in this case, current date startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat); Calendar c = Calendar.getInstance(); int ano = c.get(Calendar.YEAR); int mes = c.get(Calendar.MONTH); int dia = c.get(Calendar.DAY_OF_MONTH); startDatePicker.setSpinnersShown(false); startDatePicker.init(ano, mes, dia, dateSetListener); return v; } ///listener that receives the selected date private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (view.isShown()) { ///if the datepicker is on the screen String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth; callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format } } }; @Override public void onAttach(Activity activity) { super.onAttach(activity); /* * this function guarantees that the container activity implemented the callback interface * */ try { callbackIni = (OnDateIniSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener"); } } 

}

To compose container + fragments, I used ViewPager (AppCompat) with a custom class that extends FragmentPagerAdapter. No dialogs.

0
source
 import android.app.Activity; import android.app.FragmentManager; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.nepal.peace.ilovemydiet.R; import com.wdullaer.materialdatetimepicker.Utils; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; import java.util.Calendar; /** * A simple {@link Fragment} subclass. * Activities that contain this fragment must implement the * {@link UserPhysicalCharacter.OnFragmentInteractionListener} interface * to handle interaction events. * Use the {@link UserPhysicalCharacter#newInstance} factory method to * create an instance of this fragment. */ public class UserPhysicalCharacter extends Fragment { // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, eg ARG_ITEM_NUMBER private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; EditText f_name, l_name, u_height, u_weight, u_obj_weight; TextView u_birth; SharedPreferences sharedpreferences; public static final String MyPREFERENCES = "LoginData"; // TODO: Rename and change types of parameters private String mParam1; private String mParam2; private OnFragmentInteractionListener mListener; /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment UserPhysicalCharacter. */ // TODO: Rename and change types and number of parameters public static UserPhysicalCharacter newInstance(String param1, String param2) { UserPhysicalCharacter fragment = new UserPhysicalCharacter(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } public UserPhysicalCharacter() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_relpace, container, false); final UserPhysicalCharacter userPhysicalCharacter=new UserPhysicalCharacter(); Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar); u_birth = (TextView) rootView.findViewById(R.id.birthday); u_birth.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Calendar now = Calendar.getInstance(); DatePickerDialog dpd = DatePickerDialog.newInstance( new DateListener(), now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) ); dpd.setThemeDark(true); dpd.vibrate(true); dpd.dismissOnPause(true); dpd.setAccentColor(Color.parseColor("#9C27B0")); dpd.setTitle("DatePicker Title"); dpd.show(getActivity().getFragmentManager(),"Datepickerdialog"); } }); return rootView; } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed(Uri uri) { if (mListener != null) { mListener.onFragmentInteraction(uri); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnFragmentInteractionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p/> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } public class DateListener implements DatePickerDialog.OnDateSetListener { @Override public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { String date = dayOfMonth+"/"+(++monthOfYear)+"/"+year; Toast.makeText(getActivity(),date, Toast.LENGTH_SHORT).show(); u_birth.setText(date); } } } 
0
source

I got the same casting error, and, finding a solution, but not finding what worked, I decided to come up with one of mine.

My approach is to use a little trick. Instead of trying to get a class that extends DialogFragment to accept my fragment as DatePickerDialog.OnDateSetListener, I let the DialogFragment class implement the interface and receive a callback. When the callback is called, it passes it along with my fragment, which also implements the same interface. In essence, the DialogFragment class redirects the callback. Here is the DialogFragment class that you could see in many other stackoverflow posts, except that it has a public setListeningActivity () method. setListeningActivity () takes a fragment, action, or indeed any class that implements DatePickerDialog.OnDateSetListener. This is the class to which any callbacks will be redirected to the DialogFragment class.

 public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { private DatePickerDialog.OnDateSetListener m_listener = null; @Override 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(getActivity(), this, year, month, day); } public void setListeningActivity(DatePickerDialog.OnDateSetListener listener) { m_listener = listener; } @Override public void onDateSet(DatePicker view, int year, int month, int day) { if (m_listener != null) { m_listener.onDateSet(view, year, month, day); } } 

The following code is used that uses it:

 public class AppPatientInfoFragment extends Fragment implements DatePickerDialog.OnDateSetListener { ... private void setDate(final Calendar calendar) { final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); ((TextView) m_activity.findViewById(R.id.dob)).setText(dateFormat.format(calendar.getTime())); } public void onDateSet(DatePicker view, int year, int month, int day) { Calendar c = Calendar.getInstance(); c.set(year, month, day); setDate(c); } ... DatePickerFragment fragment = new DatePickerFragment(); fragment.setListeningActivity(AppPatientInfoFragment.this); fragment.show(m_activity.getFragmentManager(), "date"); 

Basically, what happens is that DatePickerFragment onDateSet () is called because it is the actual callback registered in DatePicker and then DatePickerFragment onDateSet () forwards it to AppPatientInfoFragment onDateSet ().

0
source

All Articles