3

I have a fragment which contain an EditText when I click on that EditText a DatePicker Dialog appears to select date.
FragmentFile

public class FirstFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        EditText editText = (EditText) view.findViewById(R.id.visitDateFiled);

        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment picker = new DatePickerFragment();
                picker.show(getFragmentManager(), "Date Picker");
            }
        });
        return view;
    }

DialogFragment

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 month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, day);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());

    }
}

The problem I don't know how to pass data (Selected date) from the DialogFragment to Fragment?
I read some topic but It's not helping I got confused(Sorry for asking this question again).

Topic 1 Topic 2

Community
  • 1
  • 1
Chlebta
  • 3,090
  • 15
  • 50
  • 99

4 Answers4

5

Updated code


FragmentFile

public class FirstFragment extends Fragment implements DatePickerDialogFragmentEvents{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        EditText editText = (EditText) view.findViewById(R.id.visitDateFiled);

        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment picker = new DatePickerFragment();
                picker.setDatePickerDialogFragmentEvents(FirstFragment.this); //Changed
                picker.show(getFragmentManager(), "Date Picker");
            }
        });
        return view;
    }

    //This is where you will get selected date value
    @Override
    public void onDateSelected(String date) {
        String selectedDate = date;
    } 
 }

DialogFragment

public class DatePickerFragment extends DialogFragment
        implements DatePickerDialog.OnDateSetListener {

    //Interface created for communicating this dialog fragment events to called fragment
    public interface DatePickerDialogFragmentEvents{
       void onDateSelected(String date);
    }

    DatePickerDialogFragmentEvents dpdfe

    public void setDatePickerDialogFragmentEvents(DatePickerDialogFragmentEvents dpdfe){
         this.dpdfe = dpdfe;
    }

    @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 month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, day);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());
        dpdfe.onDateSelected(formattedDate); //Changed
    }
}

So i created an interface named DatePickerDialogFragmentEvents in your dialogfragment class and implemented that in caller fragment. From caller fragment when you create a instance of dialogfragment, set DatePickerDialogFragmentEvents instance of fragment by using setDatePickerDialogFragmentEvents method of dialog fragment class.

Rajen Raiyarela
  • 5,526
  • 4
  • 21
  • 41
  • The changed line `picker.setDatePickerDialogFragmentEvents(FirstFragment.this); //Changed` cannot be resolved. ?? – Chlebta Nov 04 '14 at 12:44
  • check for me this way works. there you have to pass the instance of the fragment 'this' ... as it is inside setOnClickListener i passed as FirstFragment.this as if i pass this then would take that clicklisterner and its wrong. – Rajen Raiyarela Nov 04 '14 at 13:58
  • I have sloved The problem using the seconde response of this topic : http://stackoverflow.com/questions/18579590/how-to-send-data-from-dialogfragment-to-a-fragment – Chlebta Nov 04 '14 at 15:45
  • It is working, just instead of defining `DialogFragment picker = new DatePickerFragment();` inside onClickListner inside FirstFragment. define it as `DatePickerFragment picker = new DatePickerFragment();` then `setDatePickerDialogFragmentEvents` cannot be resolved error will be gone. – Samrat Das Jul 20 '16 at 10:29
5

I have sloved the problem thank's to this topic, the seconde response of topic.
DatePickerFragment.java

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

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());
        // in this part I stored the selected date into the intent
        Intent i = new Intent();
        i.putExtra("selectedDate",formattedDate);
        getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i);
    }

Fragment File

public static final int DATEPICKER_FRAGMENT=1; // adding this line
@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_feeding, container, false);
    EditText editText = (EditText) view.findViewById(R.id.foodDeliveryDateFiled);

    editText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            DialogFragment picker = new DatePickerFragment();
            picker.setTargetFragment(FeedingFragment.this, DATEPICKER_FRAGMENT);
            picker.show(getFragmentManager().beginTransaction(), "Date Picker");
        }
    });
    return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
        case DATEPICKER_FRAGMENT:
            if (resultCode == Activity.RESULT_OK) {
                // here the part where I get my selected date from the saved variable in the intent and the displaying it.
                Bundle bundle=data.getExtras();
                String resultDate = bundle.getString("selectedDate","error");
                EditText editText = (EditText) getView().findViewById(R.id.foodDeliveryDateFiled);
                editText.setText(resultDate);
            }
            break;
    }
Community
  • 1
  • 1
Chlebta
  • 3,090
  • 15
  • 50
  • 99
1

Every Java programmer's first response would be to create an observable or callback and send it around. While this would be an acceptable practice in most places, when working with Fragments and DialogFragments the experience is not as pretty, due to state losses when recreating, rotating, pausing...you're bound to receive IllegalStateExceptions you're not expecting.

My advice, while a bit drastic, would be to move your communication patterns from a family of interface callbacks being passed around to a centralized event bus like Otto or GreenRobot's. It works just great both in foreground and background for any given state and helps decoupling usage.

MLProgrammer-CiM
  • 17,231
  • 5
  • 42
  • 75
-1

Using a ViewModel is the Best Solution

class ItemViewModel : ViewModel() {
        private val mutableSelectedItem = MutableLiveData<Item>()
        val selectedItem: LiveData<Item> get() = mutableSelectedItem

    fun selectItem(item: Item) {
        mutableSelectedItem.value = item
    }
}

class MainActivity : AppCompatActivity() {
    // Using the viewModels() Kotlin property delegate from the activity-ktx
    // artifact to retrieve the ViewModel in the activity scope
    private val viewModel: ItemViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel.selectedItem.observe(this, Observer { item ->
            // Perform an action with the latest item data
        })
    }
}

class ListFragment : Fragment() {
    // Using the activityViewModels() Kotlin property delegate from the
    // fragment-ktx artifact to retrieve the ViewModel in the activity scope
    private val viewModel: ItemViewModel by activityViewModels()

    // Called when the item is clicked
    fun onItemClicked(item: Item) {
        // Set a new item
        viewModel.selectItem(item)
    }
}

According to Android Documentation

mikail yusuf
  • 197
  • 3
  • 5