windowSoftInputMode="adjustResize" not working with translucent action/navbar
Solution 1
You are missing the following property:
android:fitsSystemWindows="true"
in the root RelativeLayout
of the fragment .xml layout.
Update:
Last year there was an interesting talk by Chris Bane that explains in good detail how this works:
https://www.youtube.com/watch?v=_mGDMVRO3iE
Solution 2
There's a related bug report here. I've found a workaround that, from limited testing, seems to do the trick with no repercussions. Add a custom implementation of your root ViewGroup
(I almost always am using FrameLayout
, so this is what I've tested with) with the logic below. Then, use this custom layout in place of your root layout, and ensure you set android:fitsSystemWindows="true"
. You can then just call getInsets()
any time after layout (e.g. add an OnPreDrawListener
) to adjust the rest of your layout to account for the system insets, if desired.
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;
/**
* @author Kevin
* Date Created: 3/7/14
*
* https://code.google.com/p/android/issues/detail?id=63777
*
* When using a translucent status bar on API 19+, the window will not
* resize to make room for input methods (i.e.
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
* ignored).
*
* To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
* capture and override the system insets, and then call through to FrameLayout's
* implementation.
*
* For reasons yet unknown, modifying the bottom inset causes this workaround to
* fail. Modifying the top, left, and right insets works as expected.
*/
public final class CustomInsetsFrameLayout extends FrameLayout {
private int[] mInsets = new int[4];
public CustomInsetsFrameLayout(Context context) {
super(context);
}
public CustomInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public final int[] getInsets() {
return mInsets;
}
@Override
protected final boolean fitSystemWindows(@NotNull Rect insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Intentionally do not modify the bottom inset. For some reason,
// if the bottom inset is modified, window resizing stops working.
// TODO: Figure out why.
mInsets[0] = insets.left;
mInsets[1] = insets.top;
mInsets[2] = insets.right;
insets.left = 0;
insets.top = 0;
insets.right = 0;
}
return super.fitSystemWindows(insets);
}
}
Since fitSystemWindow
s was deprecated, please refer to the answer below to complete the workaround.
Solution 3
@kcoppock answer is really helpful, but fitSystemWindows was deprecated in API level 20
So since API 20 (KITKAT_WATCH) you should override onApplyWindowInsets
@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
insets.getSystemWindowInsetBottom()));
} else {
return insets;
}
}
Solution 4
If you want to customize the insets and you are targeting API level >=21 you can accomplish this without having to create a custom view group. By just setting fitsSystemWindows
padding will be applied to your container view by default, which you may not want.
The version checks are built into this method and only devices >= 21 will execute the code inside the lambda. Kotlin example:
ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
insets.replaceSystemWindowInsets(0, 0, 0, insets.systemWindowInsetBottom).apply {
ViewCompat.onApplyWindowInsets(view, this)
}
}
Make sure your layout still sets the fitsSystemWindows
flag otherwise the window insets listener will not be called.
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
/>
These sources are helpful:
https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec https://medium.com/@azizbekian/windowinsets-24e241d4afb9
Solution 5
This worked for me to have translucent status bar and adjustResize in fragment:
Make a custom RelativeLayout as @Victor91 and @kcoppock said.
Use CustomRelativeLayout as parent layout for your fragment.
Declare theme with android:windowTranslucentStatus = true
The container Activity must be declared in Manifest with android:windowSoftInputMode="adjustResize" and use the declared theme
-
Please Use fitsSystemWindows on fragment root layout!
public class CustomRelativeLayout extends RelativeLayout { private int[] mInsets = new int[4]; public CustomRelativeLayout(Context context) { super(context); } public CustomRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public final WindowInsets onApplyWindowInsets(WindowInsets insets) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { mInsets[0] = insets.getSystemWindowInsetLeft(); mInsets[1] = insets.getSystemWindowInsetTop(); mInsets[2] = insets.getSystemWindowInsetRight(); return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0, insets.getSystemWindowInsetBottom())); } else { return insets; } } }
Then in xml,
<com.blah.blah.CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
</com.blah.blah.CustomRelativeLayout>
Related videos on Youtube
fabianbru
Updated on July 08, 2022Comments
-
fabianbru almost 2 years
I have problems with the translucent actionbar/navbar in the new Android KitKat (4.4) and the
windowSoftInputMode="adjustResize"
.Normaly, changing the InputMode to
adjustResize
, the app should resize itself when keyboard is shown, but here it won't! If I delete the lines for the transparent effect, the resize is working.So if the keyboard is visible, my
ListView
is under it and I can't access the last few items (only by hiding the keyboard manually).AndroidManifest.xml
:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="XYZ" android:versionCode="23" android:versionName="0.1" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.XYZStyle" > <activity android:name="XYZ" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
values-v19/styles.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="Theme.XYZStyle" parent="@style/Theme.AppCompat.Light"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </style> </resources>
fragment.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/listView_contacts" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:divider="@null" android:dividerHeight="0dp" android:drawSelectorOnTop="true" android:fastScrollAlwaysVisible="true" android:fastScrollEnabled="true" android:paddingBottom="@dimen/navigationbar__height" > </ListView> </RelativeLayout>
Any ideas for fixing this?
-
mikepenz about 9 yearspossible duplicate of android:windowSoftInputMode="adjustResize" doesn't make any difference?
-
-
sealskej over 9 yearsActually SOFT_INPUT_ADJUST_PAN seems to be NOT ignored according to my experience - it will move whole screen up, including system bar and shift keyboard under focused view.
-
Simon almost 9 yearsThanks - you are correct about the SOFT_INPUT_ADJUST_PAN. I used this in my fragment: getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-
Lucas about 8 yearsThat was the only way I could achieve having adjustResize for activity (needed for the scrolling of the view upon showing keyboard), fitSystemWindows set as true so that the scroll actually happens on >= Lollipop and having translucent statusBar. Thanks a lot.
-
Paulina almost 6 yearsThis is the best answer so far, and I'm looking for solution some time now. It's working perfectly, but you have to add some extra padding to your toolbar, without it your toolbar will be overlapping statusbar
-
Bogdan Zurac about 5 yearsThis still remains the best approach, since you can apply this is your
BaseFragment
, along withview.fitsSystemWindows = true
and it just works without any changes to the actual XML layouts or View subclasses. -
Onik over 3 yearsWanted to note that the solution may not work for some view acting as
container
(in my case it wasConstraintLayout
). The fix was to wrap my layout withFrameLayout
that became a newcontainer
. Appreciate the solution! -
mikep over 3 yearsI do not see difference between your solution and @kcoppock answer. Tested both. When I use your method the same todo items 1 - 5 including fitSystemWindows of kcoppock answer must be used. When I omit fitSystemWindows status bar is translucent but windowSoftInputMode=“adjustResize” is not working (I do not see input in which im writing)
-
Andrey Kijonok over 2 yearsI almost got depression. I thought only I have issues with transparent status bar. And after 2 hours of searching. Finally got your answer. You saved my day. Thank you!
-
Admin almost 2 yearsThis code working when you are use full screen flag in your activity Thank you