简体   繁体   中英

Non-default constructors in fragments with DatePicker Callback

There exist answers on how to avoid this problem by creating newInstance method, however as i am sending a listener as a parameter and that i cannot send that listener through Bundle how can i solve this issue?

Here i have an interface that listens to calendar change :

    public interface DateChangeListener {
    public void onDateChanged(Calendar calendar);
    }

Here i am opening DatePicker DialogFragment from Fragment :

(for clarity: There is a Fragment where i create a Custom AlertDialog on some button click, then inside that Dialog i open this DialogFragment(mDatePicker) which initializes DatePickerFragment )

DialogFragment mDatePicker = new DatePickerFragment(new DateChangeListener() {
@Override
public void onDateChanged(Calendar calendar) {
    year = calendar.get(Calendar.YEAR);
    month = calendar.get(Calendar.MONTH);
    day = calendar.get(Calendar.DAY_OF_MONTH);
    //Set date
    filtersInputEditText.setText(new StringBuilder().append(day).append("/").append(month + 1).append("/").append(year));
}

And here is DialogFragment created:

    public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

    private DateChangeListener mListener;

    public DatePickerFragment(DateChangeListener mListener){
        this.mListener = mListener;
    }

    @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(), android.R.style.Theme_Holo_Light_Dialog, this, year, month, day);
    }

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day);

        if(mListener != null)
            mListener.onDateChanged(calendar);
    }
}

The code runs well, but when i try to make a signed apk it warns me with non-default constructor message. How can i use newInstance strategy here, or should i change the way i am implementing this feature?

notice also that i am forcing app to keep orientation as landscape in Manifest , android:screenOrientation="landscape"

  1. Fragment should have Empty constructor If you don't want to have issues with configurations changed such as screen rotation or low memory case. When configurations changed, Android will re-create Fragment using empty constructor automatically.

  2. For your case. DateChangeListener should be implemented by

    • Host Activity - If you Open DatePickerFragment from Activity

    • TargetFragment (by setting setTargetFragment from Fragment) - If you open DatePickerFragment from Fragment (like parent fragment)

  3. From DatePickerFragment, you can access DateChangeListener by casting as below:

    • (DateChangeListener)this.getActivity() ----> If the host activity implement DateChangeListener

    • (DateChangeListener)this.getTargetFragment() ---> If the parent fragment (setTargetFragment) implement DateChangeListener

I would suggest you use a Bus (like Otto ). When using an interface, you are coupling the class that implements the interface with the one that uses said interface. Using a Bus avoids this since subscribers do not know where events are coming from.

The reason why you get the warning is because the framework may need to recreate your Fragment (eg when you rotate the screen). When it does so, the FragmentManager will call the Fragment 's default constructor, hence the non-default constructor will not be called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM