Reputation: 1024
I am using BottomSheetDialogFragment
in my android app. I am using Java. I show the bottomsheet
by:
ActionBottomDialogFragment dialogFragment = ActionBottomDialogFragment.newInstance();
showButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialogFragment.show(getActivity().getSupportFragmentManager(), ActionBottomDialogFragment.TAG);
}
});
What I see is it calls onCreateDialog
method and then calls onViewCreated
methods. For the first time this is okay.
Now I hide the bottom sheet using:
ImageButton close = view.findViewById(R.id.closeButton);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
Then when I press the show button again, it calls onCreateDialog
method again. I have a dynamic list of choice chips which I want the state to be just as I left it. If I left it on checking 'Choice A', it should show up selected the next time I open the bottom sheet. I need the state to be maintained.
What is happening is it rebuilds the choice chips from start, so the state is lost.
How can I just show / hide the bottom sheet without recreating?
Upvotes: 1
Views: 2569
Reputation: 40878
You can use show() & hide() of the dialog itself; this will keep the fragment alive.
So, in your case:
To show it:
ActionBottomDialogFragment dialogFragment;
showButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (dialogFragment == null) {
dialogFragment = ActionBottomDialogFragment.newInstance();
dialogFragment.show(getActivity().getSupportFragmentManager(), ActionBottomDialogFragment.TAG);
} else {
dialogFragment.getDialog().show();
}
}
});
And to hide it:
ImageButton close = view.findViewById(R.id.closeButton);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialogFragment.getDialog().hide();
}
});
But this requires to handle the side effects when dismissing the fragments using the back button and when touching outside.
Here's a custom DialogFragment that handles that:
public class BottomSheet extends BottomSheetDialogFragment {
public BottomSheet() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_layout, container, false);
return view;
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new BottomSheetDialog(requireContext(), getTheme()) {
@Override
public void onBackPressed() {
getDialog().hide();
}
};
]
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onStart() {
super.onStart();
setCancelable(false);
getDialog().setCanceledOnTouchOutside(false);
final View outsideView =
requireDialog().findViewById(com.google.android.material.R.id.touch_outside);
outsideView.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP)
getDialog().hide();
return false;
});
}
}
Upvotes: 0
Reputation: 516
UI will be always created again when you call show()
. It's better to use a sharedViewModel
in bottomSheetFragment
and the parent activity/fragment. You should save the fields being selected in the viewmodel and use it the bottomSheet. This way the state will be maintained.
Upvotes: 0