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();
}
}
Implementing a Callback for DialogFragment
An option would be to create an interface that is going to be implemented by the Adapter and passed to the dialogframe when creating it. The dialogframe could then invoke a certain method when positive is clicked and another one when negative is clicked :
public interface DialogCallback{
void clickedPositiveStart();
void clickedPositiveStop();
void clickedNegativeStart();
void clickedNegativeStop();
}
public class MyAdapter extends Adapter implements DialogCallback, View.OnClickListener{
@Override
protected void onClick(View view){
DialogFragment newFragment = null;
String action;
if(view.getId() == R.id.your_start_button){
action = "start";
}else if(view.getId() == R.id.your_stop_button){
action = "stop";
}else if(..){
....
}else{
return;
}
newFragment = ConfirmationDialog.newInstance(TITLE,CONTENT, this, action);
newFragment.show(((AppCompatActivity)contextView).getSupportFragmentManager(), TAG);
}
@Override
public void clickedPositiveStart(){
// do something when positive is clicked
}
@Override
public void clickedPositiveStop(){
// do something when positive is clicked
}
@Override
public void clickedNegativeStart(){
// do something when negative is clicked
}
@Override
public void clickedNegativeStop(){
// do something when negative is clicked
}
}
public ConfirmationDialog extends Dialogfragment{
private DialogCallback callback;
private String action;
public static ConfirmationDialog newInstance(String title, String description, DialogCallback callback, String action) {
this.callback = callback;
this.action = action;
...
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = getArguments().getString("title");
String description = getArguments().getString("description");
return new AlertDialog.Builder(getActivity())
//.setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setMessage(description)
.setPositiveButton("CONTINUE",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(action.equals("start"){
callback.clickedPositiveStart();
} else if(action.equals("stop"){
callback.clickedPositiveStop();
}
}
}
)
.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(action.equals("start"){
callback.clickedNegativeStart();
} else if(action.equals("stop"){
callback.clickedNegativeStop();
}
}
}
)
.create();
}
}
}
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 ListTipo(Callback callback) {
this.callback=callback;
}
// where you want to pass the result
callback.onResult(YOUR_RESULT);
Where you create the dialog:
xTipo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new ListTipo(result -> {
// run your code with result
}).show(getSupportFragmentManager(),"ListTipo");
}
});
How to callback different clicks from DialogFragment to Activity?
You can use interface to give callbacks, one for dialog frgament to activity and one from recyclerview to dialog fragment
1 Interface (for callback from dialog fragment to acitvity)
public interface OnDialogCountryChangeListener {
public void onDialogCountryChange(String country);
}
2 Activity.java (class starting the dialog fragment)
public class MyActivity extends AppCompactActivity implements OnDialogCountryChangeListener {
...
private void showDialog() {
FragmentManager fm = getSupportFragmentManager();
CountryDialogFragment countryDialog = new CountryDialogFragment();
countryDialog.setTargetFragment(this, 0); // set target fragment for callback listener
countryDialog.show(fm, "add_dialog");
}
@Override
public void onDialogCountryChange(String country) {
// Your callback from dialog fragment to activity
// Do your stuff
}
}
3 CountryDialogFragment.java
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
countryActivitycallback = (OnDialogCountryChangeListener) getTargetFragment(); // callback instance
} catch (ClassCastException e) {
throw new ClassCastException("Calling Fragment must implement OnDialogCountryChangeListener");
}
}
For callback from recyclerview to dialog fragment
1 Create interface (You could also use the same interface, but I think it's better to explain using new different one, as it might become confusing)
public interface OnItemClickListener {
void onItemClick(String countryItem);
}
2 Next modify your Adapter class , in your case RecycleView Adapter
i) Send listener as a parameter in your constructor
private final OnItemClickListener listener;
public RecycleViewCountryAdapter(OnItemClickListener listener) {
this.listener = listener;
}
ii) Set onCLick listener on some view in your ViewHolder class
public MyViewHolder(View itemView) {
super(itemView);
imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);
// change your listener on any other view if you want
imageOnCard..setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(worldDataModelArrayList.get(getAdapterPosition()));
}
});
}
3 Now modify your DialogFragment class to listen to your interface callback ,
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
RecycleViewCountryAdapter adapter = new RecycleViewCountryAdapter(new OnItemClickListener() {
@Override public void onItemClick(String countryItem) {
// implement click listener as per your requirement
// handle your work in dialog fragment and also give callback to activity
if(countryActivitycallback!=null) // callback for activity
{
countryActivitycallback.onDialogCountryChange(countryItem);
}
});
recyclerView.setAdapter(adapter);
Edit: setTargetFragment is deprecated now. As a Alternate way you can do the same with a shared ViewModel or with the new API FragmentResultListener.
DialogFragment callback to Target Fragment using interface
you have to call setTargetFragment
setTargetFragment(this, 0);
in order to get a reference FragmentXYXY
, in your DialogFragment
.
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.et_i:
DialogFragment newFragment = FragmentAlertDialog.newInstance(MainActivity.DIALOG_I, R.string.i_select, R.array.i_array);
newFragment.setTargetFragment(this, 0);
newFragment.show(getFragmentManager(), "dialog");
}
}
Call fragment method from dialogfragment
please try as follows
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
JobList jobList = new JobList();
jobList.testFunction(view);
}
});
public void testFunction(View view) {
sp = Objects.requireNonNull(view.getContext()).getSharedPreferences("app_data", 0);
Log.w("MY_tag", sp.getString("access_token", ""));
}
android callback to dialogfragment from fragment through viewpager
In case anyone else comes along and is wondering how to go about this. I solved this by passing the dialog fragment (FragmentNewTrips) class through the viewpager and then into the child fragment where I set it as the listener.
So, when I defined the adapter I passed the listener which was the dialog fragment
AdapterPagerTrips(childFragmentManager, tripIds, this)
Then within the adapter I passed the dialog fragment class to the corresponding fragment that needed it like so
class AdapterPagerTrips (fragmentManager: FragmentManager, val tripIds: ArrayList<String?>,
val listener: FragmentNewTrips):FragmentStatePagerAdapter(fragmentManager,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
// 2
override fun getItem(position: Int): Fragment {
if (position == 0) return FragmentNewTripsTypes.newInstance(listener)
return FragmentNewTripsResults.newInstance(tripIds, listener)
}
// 3
override fun getCount(): Int {
return 2
}
}
And each fragment had a companion object that would set the listener
companion object {
fun newInstance(tripIds: ArrayList<String?>, listener: FragmentNewTrips) = FragmentNewTripsResults().apply {
arguments = Bundle().apply { putStringArrayList(TRIPIDS, tripIds) }
this.listener = listener
}
}
Related Topics
Bad Class File Magic or Version
Android Facebook Sdk 4 in Eclipse
In Android, How to Set Margins in Dp Programmatically
How to Implement Recyclerview with Cardview Rows in a Fragment with Tablayout
How to Use Addr2Line in Android
Android Locationclient Class Is Deprecated But Used in Documentation
How to Change the Color of a Part of a Textview
Android Fragments. Retaining an Asynctask During Screen Rotation or Configuration Change
How to Convert Image File Data in a Byte Array to a Bitmap
Passing Arraylist of Objects Between Activities
How to Show Dependencies Tree in Android Studio
No Matching Client Found for Package Name (Google Analytics) - Multiple Productflavors & Buildtypes
Calling Activity Class Method from Service Class
Android Preventing Double Click on a Button
Could Not Find Com.Android.Tools.Build:Gradle:3.0.0-Alpha1 in Circle Ci
What Is the 'App' Android Xml Namespace
App Is Misconfigured for Facebook Login: Android Facebook Integration Issue