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)!
This is what I wanted
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.
Set fitsSystemWindows = "false" and set android:windowSoftInputMode="adjustResize" in manifest file. Show activity on this post. I have used like this to show the soft keyboard programatically and this is worked for me to prevent the auto resize of the screen while launching the keyboard.
Setting android:isScrollContainer = "false" inside the ScrollView worked for me. According to the documentation, settings "isScrollContainer" to true means that the scroll view can be resized to shrink its overall window so that there is space for an input method.
After research I figured out that to work in some cases parent layout has to be set android:fitsSystemWindows="true" . Then native functionality of scrolling EditText above scrollbar working like a charm. Show activity on this post. Simply setting android:fitsSystemWindows="true" in the layout xml worked for me.
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
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()
}
}
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With