Reputation: 313
How to use the latest WindowInset API to adjust space betweeen my dialog and softkeyboard?
I have a BottomSheetDialog with some EditText. The default animation will show the soft keyboard right below my EditText which will cover my save button. After doing some research, I added this line into my BottomSheetDialog
fragment
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
And it worked (as the picture is shown down below)!
But apparently SOFT_INPUT_ADJUST_RESIZE
is deprecated.
* @deprecated Call {@link Window#setDecorFitsSystemWindows(boolean)} with {@code false} and
* install an {@link OnApplyWindowInsetsListener} on your root content view that fits insets
* of type {@link Type#ime()}.
And I couldn't figure out how to use the new OnApplyWindowInsetsListener
to achieve the same effect.
Here is my current BottomSheetDialog
fragment:
public class BottomSheetDialog extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Adding this line works, but it's deprecated in API 30
// getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
getDialog().getWindow().setDecorFitsSystemWindows(false);
view = inflater.inflate(R.layout.fragment_bottom_dialog_cash, container, false);
view.setOnApplyWindowInsetsListener((v, insets) -> {
Log.d("dialog", "onCreateView: ");
Insets imeInsets = insets.getInsets(WindowInsets.Type.ime());
v.setPadding(0,0,0,imeInsets.bottom);
return insets;
});
return view;
}
I use an onclicklistener in another fragment to show this dialog. Code in Another fragment
@Override
public void onItemClick(int position) {
BottomSheetDialog dialog = new BottomSheetDialog();
dialog.show(getParentFragmentManager(), "BottomSheetDialog");
}
In fact, the log indicates that the listener is never triggered when the soft keyboard pop up. FYI, I'm following this video and this blog.
Upvotes: 15
Views: 13169
Reputation: 1493
Compat Version
WindowCompat.setDecorFitsSystemWindows(window, false)
ViewCompat.setOnApplyWindowInsetsListener(rootView()) { _, insets ->
val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
rootView().setPadding(0, 0, 0, imeHeight)
insets
}
Or use Insetter library
WindowCompat.setDecorFitsSystemWindows(window, false)
rootView().applyInsetter {
type(ime = true) {
padding()
}
}
Upvotes: 11
Reputation: 305
The only thing that seemed to do the trick for me was setting the style of the BottomSheetDialog to use the following:
<style name="BottomSheetDialogTheme" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>
Upvotes: 5
Reputation: 313
After more research, I find out that if I use viewBinding
and replace view
with bind.getRoot()
, then everything works fine. I'm not sure why (maybe I should use in onViewCreated
instead of onCreateView
?) but the code should be helpful for people having the same issue.
// NOTE: you have to set this in the activity instead of fragment.
getWindow().setDecorFitsSystemWindows(false);
// Only work with API30 or above!
bind.getRoot().setOnApplyWindowInsetsListener((v, insets) -> {
imeHeight = insets.getInsets(WindowInsets.Type.ime()).bottom;
bind.getRoot().setPadding(0, 0, 0, imeHeight);
return insets;
});
One thing to be noticed is that setDecorFitsSystemWindows(false) means the app (you) are responsible for all the system windows includes the status bar and navigation bar.
I also find the tutorials linked down below are very useful, please check if you wanna know more about windowInsets and new animation callback.
New WindowInsets APIs for checking the keyboard (IME) visibility and size
Window Insets and Keyboard Animations Tutorial for Android 11
Upvotes: 14