Bence
Bence

Reputation: 109

How can a BottomSheetDialogFragment communicate with its host fragment?

I have a button in my fragment which opens a BottomSheetDialogFragment. I want to notify the host fragment if the user selected an item on the BottomSheetDialogFragment. In order to achieve this, I have made an interface in my BottomSheetDialogFragment. However, that interface only communicates with the host activity, not the fragment. How can I send the information from the dialog to the fragment?

This is my interface:

public interface BottomSheetListener {
        void onButtonClicked(int index);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        try {
            mListener = (BottomSheetListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
        }
    }

Upvotes: 1

Views: 3230

Answers (2)

Eray Agdoğan
Eray Agdoğan

Reputation: 138

When you use a lot of fragments, nested fragments or dialogfragments it becomes messy for communicate between them. I am suggesting to use ViewModel with LiveData for passing and updating data.

first add this to build gradle :

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

then create ViewModel class :

public class YourViewModel extends AndroidViewModel {

private MutableLiveData<Integer> yourMutableLiveData=new MutableLiveData<>();

public YourViewModel(@NonNull Application application) {
    super(application);
}

public MutableLiveData<Integer> getYourMutableLiveData() {
    return yourMutableLiveData;
}

}

This the fragment you want set value :

   public class FragmentA extends Fragment{

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

            YourViewModel yourViewModel =new ViewModelProvider(getActivity()).get(YourViewModel.class);

            yourViewModel.getYourMutableLiveData().setValue(0);
        }
    }

And this is the fragment you want to get value when updated :

 public class FragmentB extends Fragment{

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

            YourViewModel yourViewModel =new ViewModelProvider(getActivity()).get(YourViewModel.class);

            yourViewModel.getYourMutableLiveData().observe(getViewLifecycleOwner(), new Observer<Integer>() {
                @Override
                public void onChanged(Integer integer) {

                }
            });
        }
    }

It can work on dialog fragment as well as I tested.

Notes : -Do not pass context or any view into view model.

-Remember that onActivityCreated comes after onCreateView.

-Do not set this key to

 YourViewModel yourViewModel =new ViewModelProvider(this).get(YourViewModel.class);

in fragment if you want to pass data fragment to fragment but you can pass in activity.

-You can set more than one observer to the data.

Upvotes: 2

rahat
rahat

Reputation: 2056

getParentFragment will return the parent fragment, if the current fragment is attached to a fragment else it will return null if it is attached directly to an Activity

@Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        try {
            mListener = (BottomSheetListener) getParentFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
        }
    }

Upvotes: 4

Related Questions