I have two classes. First is activity, second is a fragment where I have some EditText
. In activity I have a subclass with async-task and in method doInBa
From Activity you send data with intent as:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
and in Fragment onCreateView method:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
Use following interface to communicate between activity and fragment
public interface BundleListener {
void update(Bundle bundle);
Bundle getBundle();
}
Or use following this generic listener for two way communication using interface
/**
* Created by Qamar4P on 10/11/2017.
*/
public interface GenericConnector<T,E> {
T getData();
void updateData(E data);
void connect(GenericConnector<T,E> connector);
}
fragment show method
public static void show(AppCompatActivity activity) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = (GenericConnector) activity;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
you can cast your context to GenericConnector
in onAttach(Context)
too
in your activity
CustomValueDialogFragment.show(this);
in your fragment
...
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
connector.connect(new GenericConnector() {
@Override
public Object getData() {
return null;
}
@Override
public void updateData(Object data) {
}
@Override
public void connect(GenericConnector connector) {
}
});
}
...
public static void show(AppCompatActivity activity, GenericConnector connector) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = connector;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
Note: Never use it like "".toString().toString().toString();
way.
This answer may be too late. but it will be useful for future readers.
I have some criteria. I have coded for pick the file from intent. and selected file to be passed to particular fragment for further process. i have many fragments having the functionality of File picking. at the time , every time checking the condition and get the fragment and pass the value is quite disgusting. so , i have decided to pass the value using interface.
Step 1: Create the interface on Main Activity.
public interface SelectedBundle {
void onBundleSelect(Bundle bundle);
}
Step 2: Create the SelectedBundle reference on the Same Activity
SelectedBundle selectedBundle;
Step 3: create the Method in the Same Activity
public void setOnBundleSelected(SelectedBundle selectedBundle) {
this.selectedBundle = selectedBundle;
}
Step 4: Need to initialise the SelectedBundle reference which are all fragment need filepicker functionality.You place this code on your fragment onCreateView(..)
method
((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
@Override
public void onBundleSelect(Bundle bundle) {
updateList(bundle);
}
});
Step 5: My case, i need to pass the image Uri from HomeActivity to fragment. So, i used this functionality on onActivityResult method.
onActivityResult from the MainActivity, pass the values to the fragments using interface.
Note: Your case may be different. you can call it from any where from your HomeActivity.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
selectedBundle.onBundleSelect(bundle);
}
Thats all. Implement every fragment you needed on the FragmentClass. You are great. you have done. WOW...
You can create public static method in fragment where you will get static reference of that fragment and then pass data to that function and set that data to argument in same method and get data via getArgument on oncreate method of fragment, and set that data to local variables.
I ran into a similar issue while using the latest Navigation architecture component. Tried out all the above-mentioned code with passing a bundle from my calling activity to Fragment.
The best solution, following the latest development trends in Android, is by using View Model (part of Android Jetpack).
Create and Initialize a ViewModel class in the parent Activity, Please note that this ViewModel has to be shared between the activity and fragment.
Now, Inside the onViewCreated() of the fragment, Initialize the Same ViewModel and setup Observers to listen to the ViewModel fields.
Here is a helpful, in-depth tutorial if you need.
https://medium.com/mindorks/how-to-communicate-between-fragments-and-activity-using-viewmodel-ca733233a51c
From Activity
you send data with Bundle as:
Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");
// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);
And in Fragment
onCreateView method get the data:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
String data = getArguments().getString("data");// data which sent from activity
return inflater.inflate(R.layout.myfragment, container, false);
}