Question

I am going to explain my problem as short as possible.

I have a Fragment called FragmentA which displays a DialogFragment after clicking on a specific button.

public class FragmentA extends Fragment implements OnClickListener {

    ...

    @Override
    public void OnClick(View v) {
        if (v == dialogButton) {
            showDialog();
        }
    }

    public void showDialog() {
        String diagName = getResources().getString(R.string.dialog_title);
        MyDialog myDialog = MyDialog.newInstance(getFragmentAValue());
        myDialog.show(getFragmentManager(), diagName);
    }
}

public class MyDialog extends DialogFragment implements OnClickListener {
    ...
    @Override
    public void onClick(View view) {
        if (view == acceptButton) {
            ...
        }
        else if (view == cancelButton) {
            ...
        }
    }
}

The dialog is dispalyed without any problem. But my problem consists in after myDialog is dismissed onResume() method in FragmentA is never called and FragmentA is shown and you can interact with it without any problem.

public class FragmentA extends Fragment implements OnClickListener {

    ...

    @Override
    public void onResume() {
        super.onResume();
        resumeFragmentA();
    }
}

So, what I have done in order to fix this issue is copying an instance of FragmentA in the end of onActivityCreated() method and call the method resumeFragmentA() when user has closed the dialog.

public class FragmentA extends Fragment implements OnClickListener {

    FragmentA fragmentA = null;

    ...

    @Override
    public void onResume() {
        super.onResume();
        resumeFragmentA();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        ...

        fragmentA = this;
    }

    ...
}

public class MyDialog extends DialogFragment implements OnClickListener {
    ...
    @Override
    public void onClick(View view) {
        if (view == acceptButton) {
            storeData();
            dismissDialog();
        }
        else if (view == cancelButton) {
            dismissDialog();
        }
    }

    public void dismissDialog() {
        FragmentA.fragmentA.resumeFragmentA();
        dismiss();
    }

}

I know this solution is tricky but I do not know to solve in a more brilliant way. Do you know it? Any Idea? Thanks in advance!

For a better reading of my code, here you have my full code:

public class FragmentA extends Fragment implements OnClickListener {

    ...

    FragmentA fragmentA = null;

    ...

    @Override
    public void OnClick(View v) {
        if (v == dialogButton) {
            showDialog();
        }
    }

    public void showDialog() {
        String diagName = getResources().getString(R.string.dialog_title);
        MyDialog myDialog = MyDialog.newInstance(getFragmentAValue());
        myDialog.show(getFragmentManager(), diagName);
    }

    @Override
    public void onResume() {
        super.onResume();
        resumeFragmentA();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        ...

        fragmentA = this;
    }

    ...
}


public class MyDialog extends DialogFragment implements OnClickListener {

    ...

    static MyDialog newInstance(int value) {
        MyDialog fragment = new MyDialog ();
        Bundle args = new Bundle();
        args.putInt("value", value);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onClick(View view) {
        if (view == acceptButton) {
            storeData();
            dismissDialog();
        }
        else if (view == cancelButton) {
            dismissDialog();
        }
    }

    public void dismissDialog() {
        FragmentA.fragmentA.resumeFragmentA();
        dismiss();
    }

    ...

}
Was it helpful?

Solution 2

Now Google has released Android Architecture Components library, the best solution is to use a shared ViewModel between both Fragments with your Activity as the one that implements LifecycleRegistryOwner.

Doing this, we will avoid refreshing UI calling onResume and we don't need to code any tricky solution.

A solution could be the following one:

public MyActivity extends AppCompatActivity {

    ...

}

public class FragmentA extends Fragment implements OnClickListener {

    ...

    private SharedViewModel mSharedViewModel;

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

        mSharedViewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

        mSharedViewModel.getData().observe(this, value -> {
            updateUIValue(value);
        });

    }

    @Override
    public void OnClick(View v) {
        if (v == dialogButton) {
            showDialog();
        }
    }

    @Override
    public void OnClick(View v) {
        if (v == dialogButton) {
            showDialog();
        }
    }

    public void showDialog() {
        String diagName = getResources().getString(R.string.dialog_title);
        MyDialog myDialog = MyDialog.newInstance(getFragmentAValue());
        myDialog.show(getFragmentManager(), diagName);
    }
}

public class MyDialog extends DialogFragment implements OnClickListener {

    ...

    private SharedViewModel mSharedViewModel;

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

        mSharedViewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

        mSharedViewModel.getData().observe(this, value -> {
            updateUIValue(value);
        });

    }

    @Override
    public void onClick(View view) {
        if (view == acceptButton) {
            ...

            mSharedViewModel.setValue(newValue);
        }
        else if (view == cancelButton) {
            dismiss();
        }
    }
}


public class SharedViewModel extends ViewModel {

    final MutableLiveData<Resource<Value>> data = new MutableLiveData<>();

    public MutableLiveData<Value> getData() {
        return data;
    }

    public void setValue(Value newValue) {
        this.data.setValue(newValue)
    }
}

OTHER TIPS

If you just want to call onResume of FragmentA, make a call to startActivityForResult inside your DialogFragment, and start your FragmentActivity. This will call onResume.

public void dismissDialog() {
   getActivity().startActivityForResult(getActivity().getIntent(), 10);
   dismiss()
}

Another way is by implementing an interface. Create an interface and let the activity/fragment (which one you need) implements it, then pass itself as an interface object to your DialogFragment.

CustomDialogFragment df = new CustomDialogFragment();
Bundle b = new Bundle();
b.putSerializable(KEY, this); // current activity/fragment that implements the interface
df.setArguments(b);
df.show(getFragmentManager(), TAG);

Then in your DialogFragment get the listener, and call the listener's method when you need to (in this case after/before you called dismiss()).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top