How to Get Data from Dialogfragment to a Fragment

Send Data from DialogFragment to Fragment

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;
}

How to send data from DialogFragment to a Fragment?

NOTE: aside from one or two Android Fragment specific calls, this is a generic recipe for implementation of data exchange between loosely coupled components. You can safely use this approach to exchange data between literally anything, be it Fragments, Activities, Dialogs or any other elements of your application.


Here's the recipe:

  1. Create interface (i.e. named MyContract) containing a signature of method for passing the data, i.e. methodToPassMyData(... data);.
  2. Ensure your DialogFragment fullfils that contract (which usually means implementing the interface): class MyFragment extends Fragment implements MyContract {....}
  3. On creation of DialogFragment set your invoking Fragment as its target fragment by calling myDialogFragment.setTargetFragment(this, 0);. This is the object you will be talking to later.
  4. In your DialogFragment, get that invoking fragment by calling getTargetFragment(); and cast returned object to the contract interface you created in step 1, by doing: MyContract mHost = (MyContract)getTargetFragment();. Casting lets us ensure the target object implements the contract needed and we can expect methodToPassData() to be there. If not, then you will get regular ClassCastException. This usually should not happen, unless you are doing too much copy-paste coding :) If your project uses external code, libraries or plugins etc and in such case you should rather catch the exception and tell the user i.e. plugin is not compatible instead of letting the app crash.
  5. When time to send data back comes, call methodToPassMyData() on the object you obtained previously: ((MyContract)getTargetFragment()).methodToPassMyData(data);. If your onAttach() already casts and assigns target fragment to a class variable (i.e. mHost), then this code would be just mHost.methodToPassMyData(data);.
  6. Voilà. You just successfully passed your data from dialog back to invoking fragment.

How to send data from DialogFragment to Fragment using viewmodel

in order to share ViewModel between fragments, you can use activityViewModels(). for instance,

class SharedViewModel : ViewModel() {
...
}

class MasterFragment : Fragment() {

// Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}

class DetailFragment : Fragment() {

// Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}

please read more in the android documentation here: https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

How to get data from DialogFragment to a Fragment?

The Fragment.onActivityResult() method is useful in this situation. It takes getTargetRequestCode(), which is a code you set up between fragments so they can be identified. In addition, it takes a request code, normally just 0 if the code worked well, and then an Intent, which you can attach a string too, like so

Intent intent = new Intent();
intent.putExtra("STRING_RESULT", str);

Also, the setTargetFragment(Fragment, requestCode) should be used in the fragment that the result is being sent from to identify it. Overall, you would have code in the requesting fragment that looks like this:

FragmentManager fm = getActivity().getSupportFragmentManager();
DialogFragment dialogFragment = new DialogFragment();
dialogFragment.setTargetFragment(this, REQUEST_CODE);
dialogFragment.show();

The class to send data (the DialogFragment) would use this Fragment we just defined to send the data:

private void sendResult(int REQUEST_CODE) {
Intent intent = new Intent();
intent.putStringExtra(EDIT_TEXT_BUNDLE_KEY, editTextString);
getTargetFragment().onActivityResult(
getTargetRequestCode(), REQUEST_CODE, intent);
}

To receive the data, we use this type of class in the Fragment which initially started the DialogFragment:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Make sure fragment codes match up
if (requestCode == DialogFragment.REQUEST_CODE) {
String editTextString = data.getStringExtra(
DialogFragment.EDIT_TEXT_BUNDLE_KEY);

At this point, you have the string from your EditText from the DialogFragment in the parent fragment. Just use the sendResult(int) method in your TextChangeListener() anonymous class so that the text is sent when you need it.

How can i get data back from this dialog fragment in this code?

Create a callback interface, implement it on your code (where you set up the listeners), then pass it as a parameter in the dialog.

Example:

public interface Callback {
void onResult(Object result);
}
private Callback callback;
public void setCallback(Callback callback) {
this.callback=callback;
}

// where you want to pass the result
if(callback!=null)
callback.onResult(YOUR_RESULT);

Where you create the dialog:

xTipo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ListTiop fragment=new ListTipo();
fragment.setCallback(result -> {
// run your code with the result
});
fragment.show(getSupportFragmentManager(),"ListTipo");
}
});

Callback to a Fragment from a DialogFragment

Activity involved is completely unaware of the DialogFragment.

Fragment class:

public class MyFragment extends Fragment {
int mStackLevel = 0;
public static final int DIALOG_FRAGMENT = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState != null) {
mStackLevel = savedInstanceState.getInt("level");
}
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("level", mStackLevel);
}

void showDialog(int type) {

mStackLevel++;

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
Fragment prev = getActivity().getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);

switch (type) {

case DIALOG_FRAGMENT:

DialogFragment dialogFrag = MyDialogFragment.newInstance(123);
dialogFrag.setTargetFragment(this, DIALOG_FRAGMENT);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");

break;
}
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case DIALOG_FRAGMENT:

if (resultCode == Activity.RESULT_OK) {
// After Ok code.
} else if (resultCode == Activity.RESULT_CANCELED){
// After Cancel code.
}

break;
}
}
}

}

DialogFragment class:

public class MyDialogFragment extends DialogFragment {

public static MyDialogFragment newInstance(int num){

MyDialogFragment dialogFragment = new MyDialogFragment();
Bundle bundle = new Bundle();
bundle.putInt("num", num);
dialogFragment.setArguments(bundle);

return dialogFragment;

}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

return new AlertDialog.Builder(getActivity())
.setTitle(R.string.ERROR)
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(R.string.ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, getActivity().getIntent());
}
}
)
.setNegativeButton(R.string.cancel_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, getActivity().getIntent());
}
})
.create();
}
}


Related Topics



Leave a reply



Submit