2

In my activity I have two TextView (startDatePicker & endDatePicker) and when they are clicked a datePicker dialog should show up. Until here everything works fine, but I need, after the user choose the date, to set the text of the corresponding clicked textView with the user's choice. I found another post like this and I took the cue from it : https://stackoverflow.com/a/24534147/10113273

This is my DatePickerDialogFragment Class:

public class DatePickerDialogFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

public static final int START_DATE = 0;
public static final int END_DATE = 1;

private int current = 0;
private int chosenDate;

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);

    Bundle bundle = this.getArguments();
    if (bundle != null) {
        chosenDate = bundle.getInt("DATE", 0);
    }
    switch (chosenDate) {
        case START_DATE:
            current = START_DATE;
            return new DatePickerDialog(getActivity(), this, year, month, dayOfMonth);

        case END_DATE:
            current = END_DATE;
            return new DatePickerDialog(getActivity(), this, year, month, dayOfMonth);
    }
    return null;
}

@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    if (current == START_DATE) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        String dateString = DateFormat.getDateInstance().format(calendar.getTime());

        //Set the startDate textView text with the dateString
    } else {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        String dateString = DateFormat.getDateInstance().format(calendar.getTime());

        //Set the endDate textView text with the dateString
    }
}

}

Inside the onDateSet how can I access the textView? I probably think that the answer is that it cannot be done. If I am right, what could I do to solve this?

Here where I set the onClickListener on the textview in the Activity:

startDatePicker.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle bundle = new Bundle();
            bundle.putInt("DATE",0);

            DialogFragment dialogFragment = new DatePickerDialogFragment();
            dialogFragment.setArguments(bundle);
            dialogFragment.show(getSupportFragmentManager(),"date picker");
        }
    });

    endDatePicker.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle bundle = new Bundle();
            bundle.putInt("DATE",1);

            DialogFragment dialogFragment = new DatePickerDialogFragment();
            dialogFragment.setArguments(bundle);
            dialogFragment.show(getSupportFragmentManager(),"date picker");
            //endDatePicker.setText(endDate);
        }
    });
  • Maybe [this](https://www.youtube.com/watch?v=czKLAx750N0&index=29&list=PLS1QulWo1RIbb1cYyzZpLFCKvdYV_yJ-E&t=180s) video may help you – JAMSHAID Jul 21 '18 at 01:12
  • Bah. I forgot how to format things on SO Maybe I don't understand the question properly, but it looks like the DialogFragments are instantiated within the scope of where the text view is. I haven't messed with android dev in a while, but can't you just add a constructor to your Fragment class that takes a TextView, so that you can reference it? `private TextView textView; public DatePickerDialogFragment(TextView view) { this.textView = view; } // do stuff in your other methods using the reference to the text view` – SaxyPandaBear Jul 21 '18 at 01:14
  • 1
    @SaxyPandaBear Fragments must have no-argument constructors unfortunately. The proposed design in the Android examples (https://developer.android.com/guide/topics/ui/controls/pickers#DatePicker) has the Fragment implement the listener as the OP does, which IMHO is a poor choice for this exact reason (it's hard to *do* anything with the date you get from that scope). Passing in a listener makes things a lot easier, and can work with screen rotation. – Tyler V Jul 21 '18 at 01:37

1 Answers1

0

You will probably be better off not having the DatePickerDialogFragment implement the listener (I know that's in the Android examples, but it's an inflexible design as you've noticed). If you add a setListener method to the DatePickerDialogFragment like this:

public class DatePickerDialogFragment extends DialogFragment {

    private DatePickerDialog.OnDateSetListener listener = null;

    void setListener(DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), listener, year, month, dayOfMonth);
    }
}

then it's easy to use with different date pickers, easy to reuse throughout your app, and straightforward to put the result into some other view in the Activity that launches the picker, like this (the example code below would go in your Activity onCreate method)

final DatePickerDialog.OnDateSetListener startListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear,
                          int dayOfMonth) {

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        String dateString = DateFormat.getDateInstance().format(calendar.getTime());

        // set the start date TextView
        startDatePicker.setText(dateString);
    }
};

final DatePickerDialog.OnDateSetListener endListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear,
                          int dayOfMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        String dateString = DateFormat.getDateInstance().format(calendar.getTime());

        // set the enddate TextView
        endDatePicker.setText(dateString);
    }
};

// NOTE: Use getSupportFragmentManager or getFragmentManager below
//       depending on which type of DialogFragment you extended

// Reset the listener if the screen was rotated
if (savedInstanceState != null) {
    DatePickerDialogFragment dpf;

    dpf = (DatePickerDialogFragment) getSupportFragmentManager().findFragmentByTag("myStartDatePicker");
    if (dpf != null) {
        dpf.setListener(startListener);
    }

    dpf = (DatePickerDialogFragment) getSupportFragmentManager().findFragmentByTag("myEndDatePicker");
    if (dpf != null) {
        dpf.setListener(endListener);
    }
}

startDatePicker.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        DatePickerDialogFragment dpf = new DatePickerDialogFragment();

        // set bundle args on dpf if still needed

        dpf.setListener(startListener);
        dpf.show(getSupportFragmentManager(), "myStartDatePicker");
    }
});

endDatePicker.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        DatePickerDialogFragment dpf = new DatePickerDialogFragment();

        // set bundle args on dpf if still needed

        dpf.setListener(endListener);
        dpf.show(getSupportFragmentManager(), "myEndDatePicker");
    }
});
Tyler V
  • 9,694
  • 3
  • 26
  • 52