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:
- Create
interface
(i.e. namedMyContract
) containing a signature of method for passing the data, i.e.methodToPassMyData(... data);
. - Ensure your
DialogFragment
fullfils that contract (which usually means implementing the interface):class MyFragment extends Fragment implements MyContract {....}
- On creation of
DialogFragment
set your invokingFragment
as its target fragment by callingmyDialogFragment.setTargetFragment(this, 0);
. This is the object you will be talking to later. - In your
DialogFragment
, get that invoking fragment by callinggetTargetFragment();
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 expectmethodToPassData()
to be there. If not, then you will get regularClassCastException
. 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. - When time to send data back comes, call
methodToPassMyData()
on the object you obtained previously:((MyContract)getTargetFragment()).methodToPassMyData(data);
. If youronAttach()
already casts and assigns target fragment to a class variable (i.e.mHost
), then this code would be justmHost.methodToPassMyData(data);
. - 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.
Passing data from dialogfragment to fragment
And I AM a little blind!
While creating intents and thinking about the right context (getActivity(), getParentFragment().getActivity(), ...) or other possibilities to create callbacks to my fragment I DID NOT waste a second thinking about some other reasons for the error. So the EditText-Element I try to get the text from (mEditText) was not initialised :\
Some modification to make it work:
View v = inflater.inflate(R.layout.dialog_choose_title, null);
mEditText = (EditText) v.findViewById(R.id.id_edit_choose_title);
mEditText.setText(mTitle);
builder.setView(v);
Thanks for your time Gokhan!
Related Topics
Exporting and Running Unity3D Project to Android Studio
Check for Active Internet Connection Android
How to Implement a Fileobserver from an Android Service
Can't Get Location and Email Using Facebook API
Broadcast Receiver as Inner Class in Android
Jcenter Deprecation; Impact on Gradle and Android
How to Properly Use Backwards Compatible Vector Drawable with the Latest Android Support Library
Classnotfoundexception: Didn't Find Class "Com.Google.Android.Gms.Ads.Adview"
Android.Content.Res.Resources$Notfoundexception
Android Audiorecord Class - Process Live Mic Audio Quickly, Set Up Callback Function
Navigation Drawer Item Icon Not Showing Original Colour
How to Get Data from Each Dynamically Created Edittext in Android
Java.Net.Socketexception: Socket Failed: Eperm (Operation Not Permitted)
Android Studio Could Not Initialize Class Org.Codehaus.Groovy.Runtime.Invokerhelper