android:windowSoftInputMode="adjustResize" doesn't make any difference?
Asked Answered
C

9

31

I have a faux dialog which uses this layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:id="@+id/containerPageConatiner">

    <FrameLayout    android:id="@+id/dialogHolder"
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:padding="15dp"
                    android:layout_gravity="center"
                    android:background="@drawable/panel_picture_frame_bg_focus_blue"/>    
</FrameLayout> 

I place a fragment inside the <FrameLayout> depending on the dialog which is opening - The activity controlling the Dialog looks like this:

<activity
    android:label="@string/app_name"
    android:name=".activity.DialogActivity"
    android:theme="@style/CustomTheme.Screen.Transparent" 
    android:windowSoftInputMode="adjustResize">

Unfortunately when you click on an edit text inside of the dialog, no resizing takes place. The windowSoftInputMode literally makes no difference as the functionality is the same as pan mode.

Documentation says "This of course only works for applications that have a resizeable area that can be reduced to make enough space" but doesn't tell you what it means by "a resizeable area" and makes me think that in some way I don't have a resizeable area?

If anyone knows what's up can they help me out?

EDIT

Surrounding the dialog like so doesn't change anything:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containerPageConatiner"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <FrameLayout    
        android:id="@+id/dialogHolder"
        android:layout_height="wrap_content"
    android:layout_width="wrap_content"
        android:padding="15dp"
        android:layout_gravity="center"
        android:background="@drawable/panel_picture_frame_bg_focus_blue"/>

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

EDIT2

Scrollview as parent doesn't help either:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containerPageConatiner"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
            android:id="@+id/dialogHolder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:padding="15dp" />

</ScrollView>
Complected answered 6/12, 2011 at 10:4 Comment(2)
use one EditText for checking. click inside the edittect to display the soft keyboard, now you can see the use of this android:windowSoftInputMode=“adjustResize”. is you use adjustNothing even keyboard shows your layout should not get any change.Obtain
Sorry, I don't understand you.Complected
C
52

I created a new project in order to try and get the basic features working for window resizing and the slowly moved it towards the target peice of my project. Doing this I tracked the problem down to this:

In my theme hierarchy I had this property:

<item name="android:windowFullscreen">true</item> 

which was burried at the level of Theme.Black.NoTitleBar.FullScreen - An ancestor of my custom theme.

The documentation suggests that this is a "Flag indicating whether this window should fill the entire screen". That sounds like a good thing to have if you have an app which takes up the whole screen... Except it still takes up the whole screen without the flag.

In fact, once you've taken this out, there is absolutely no change in the app at all... apart from adjustResize now works perfectly.

Complected answered 6/12, 2011 at 14:52 Comment(10)
Thanks for this post! But I want fullscreen and resizing. :(Edgerton
Have a re-read of the answer. No matter if windowFullscreen is set to true, false or isn't present, your Activity will still be fullscreen.Complected
ok. I think my problem was, that I had no own theme. It works like you write with an own theme. :)Edgerton
When I remove android:windowFullscreen from my custom theme, it stops being fullscreen unfortunantly (os 4.1). Can you post complete code of your theme please? Maybe there is something I'm missing in my implementation.Prevailing
I will add my observation. Graeme is right about android:windowFullscreen attribute. It hides the status bar (on top with clock and notifications and such). A consequence of this is that attribute android:windowSoftInputMode set at adjustResize does not function as expected. When the soft keyboard is shown the activity takes all available space and it is not aware that some is taken by soft keyboard. Therefore it is not possible to scroll to the bottom of activity.Julietajulietta
What is interesting though that this occurs on newer APIs. I tested it on API 19. On device with API 10 (2.3.5) adjustResize works. They activity is aware that keyboard takes place, and it is possible to scroll to the bottom with keyboard visible. A side not: It is demanded that if you hide status bar you should also hide action bar.Julietajulietta
I don't think this is a valid 'fix' as it brings back the notifications bar; something we are trying to achieve as well as adjustresizeDedrick
It's been a while, but I'm pretty sure windowFullscreen doesn't effect the title bar. Ensure you have on of the "NoTitleBar" themes as an ancestor.Complected
Wonderful, saved me.Tangled
Great, Worked for me. (no solution worked but this one worked for me)Nessus
D
50

A while back i also had the same issue in a library i've created. (MaterialDrawer)

As far as i can see all the provided answers don't solve the main issue, they just point to remove the fullscreen flag (android:windowFullscreen), which is no solution for many out there.

The above mentioned "issue" only appears in Android versions starting with API Level 19 (KITKAT), because they changed the behavior. To be correct it is no issue, it is working as intended. See the comment by a Android employee (Android-Issue).


So i started digging around the Android source and came to the following solution by using the ViewTreeObserver.OnGlobalLayoutListener and reacting if the Keyboard gets shown / or hidden. If the Keyboard gets shown i add the padding to the bottom of the container view which will then emulate the same as the adjustResize would do.


Solution

To simplify the usage i've wrapped the whole thing in a simple KeyboardUtil helper class.

/**
 * Created by mikepenz on 14.03.15.
 * This class implements a hack to change the layout padding on bottom if the keyboard is shown
 * to allow long lists with editTextViews
 * Basic idea for this solution found here: https://mcmap.net/q/36205/-how-to-check-visibility-of-software-keyboard-in-android
 */
public class KeyboardUtil {
    private View decorView;
    private View contentView;

    public KeyboardUtil(Activity act, View contentView) {
        this.decorView = act.getWindow().getDecorView();
        this.contentView = contentView;

        //only required on newer android versions. it was working on API level 19 (Build.VERSION_CODES.KITKAT)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void enable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void disable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }


    //a small helper to allow showing the editText focus
    ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            decorView.getWindowVisibleDisplayFrame(r);

            //get screen height and calculate the difference with the useable area from the r
            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int diff = height - r.bottom;

            //if it could be a keyboard add the padding to the view
            if (diff != 0) {
                // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                //check if the padding is 0 (if yes set the padding for the keyboard)
                if (contentView.getPaddingBottom() != diff) {
                    //set the padding of the contentView for the keyboard
                    contentView.setPadding(0, 0, 0, diff);
                }
            } else {
                //check if the padding is != 0 (if yes reset the padding)
                if (contentView.getPaddingBottom() != 0) {
                    //reset the padding of the contentView
                    contentView.setPadding(0, 0, 0, 0);
                }
            }
        }
    };


    /**
     * Helper to hide the keyboard
     *
     * @param act
     */
    public static void hideKeyboard(Activity act) {
        if (act != null && act.getCurrentFocus() != null) {
            InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

You can then use it in your activity or fragment by doing the following:

//initialize the KeyboardUtil (you can do this global)
KeyboardUtil keyboardUtil = new KeyboardUtil(activity, getContent().getChildAt(0));

//enable it
keyboardUtil.enable();

//disable it
keyboardUtil.disable();

The whole util class is used in the above mentioned library MaterialDrawer and can be found here KeyboardUtil. This will always contain the latest version. (if there are improvements)

Dup answered 3/5, 2015 at 20:40 Comment(15)
the 73 of the comment is just information that this was the dp on my device. you do not have to set this or anything. i only keep the initial height to prevent issues with the detectionDup
In an app that uses different themes, you may want to query if the current window has the WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or FLAG_TRANSLUCENT_NAVIGATION set before applying the fix. Fixed an issue I came across on my side.Hydrophilous
An interesting effect happens if the screen has a numeric field and an alpha field on it. Clicking first on the numeric field adjusts the screen correctly, then changing to the alpha field makes the keyboard get bigger (autocorrect solutions sit above the keyboard), and screen does not re-adjust.Hydrophilous
@RichardLeMesurier thanks a lot for all your testing. i know that this solution is not perfect. and is still only a partial work around for the main android issue. i still hope for someone to get a real solution for this. which will work in 100% of all use cases, without any strange edge cases as described by youDup
you have the only working solution I have found so far - nice work! If I manage to work around this edge case, I will be sure to let you know.Hydrophilous
Im using this solution and it works great. But one problem is that the snackbar and FAB is showing up somewhere over the appbar. Any idea how I can fix that ? Thank you for the solution btwGerund
Hi, first of all thanks for the util class! I suggest to not only check if the API level is greater than 19, but also check if the activity window is in fullscreen mode. In our app you can toggle fullscreen and so it's much more convenient to check the fullscreen flag inside the KeyboardUtil.Globular
great solution, and the only one working I've found. Thanks a lot man!Illegitimacy
Only issue I've found is that after the keyboard is hidden, the image in the navigation drawer header got a little smaller, the placeholder behind it can be seen below the statusbar. Anyone experiencing the same?Illegitimacy
It works for me! However, I don't know why "getContent" didn't work for me, but I replace it with: ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0)Zaffer
I tried various settings to get this to work. This is the only one that worked for me! Thank you!Hysterical
while using forms inside Coordinator layout only this solution works fine !!!! thanks @DupBounds
Thanks for your answer!!Culliton
@Dup I have tried this solution but it only works on some devices. It works on OnePlus 3 (7.1.1) and Blu X2 (5.1) but NOT on LG Lucid 2 (4.1.2) or Galaxy S3 4.4.4. Do you have any suggestions on what I should try for the older devices? Thank youLachish
@Lachish well I think on 4.x this util should not be necessary as, as far as I remember, on these devices the behaviour is different. Just debug into the source and see what's different and why it does not do what you expectDup
A
2

It seems that the problem is with FrameLayout, as it behaves that way, that each child occupying visible space of that frame, therefore no need to resize to fit children. Try to use RelativeLayout. It should work.

Anaanabaena answered 6/12, 2011 at 10:29 Comment(3)
Exact same problem with RelativeLayout in place of FrameLayout. As you can see from the edit LinearLayout doesn't help either.Complected
try to add android:fillViewport="true" to ScrollViewAnaanabaena
+1 frameLayout was not playing nice with android:windowSoftInputMode="adjustResize" for me, moving the view outside of my frameLayout fixed it. This was only not working on 4.0.4 howeverIz
B
1

Without using a ScrollView as my parent I just added android:fitsSystemWindows="true" to my parent view (which was a RelativeLayout) and adjustResize to the Manifest for the activity and it worked.

Blackmon answered 22/10, 2016 at 20:56 Comment(0)
M
0

Try to put your LinearLayout on a ScrollView, that worked for me once..

Maxiemaxilla answered 6/12, 2011 at 10:36 Comment(1)
Even using a ScrollView as the parent, clicking on an EditText inside the dialog doesn't resize any part of the screen.Complected
R
0

I've had to set

<item name="android:windowFullscreen">false</item> 

Despite, I've never set it to true and app actually wasn't full screen.

Roby answered 13/9, 2017 at 14:9 Comment(0)
P
-1

As original poster discovered when the Fullscreen Flag is assigned to an activity the android:windowFullscreen attribute will not work and so your window will not resize when the soft keyboard is visible and it won't be scrollable.

Simply removing the Fullscreen flag and not using a Fullscreen theme will allow scrolling when the soft keyboard is visible.

Primus answered 16/1, 2013 at 20:43 Comment(0)
A
-1

I don't know why, but if you have <item name="android:windowTranslucentNavigation">true</item> in your theme, change it to false. And it will start working. Really strange.

Airwaves answered 15/6, 2018 at 18:18 Comment(1)
@Bro, You make my day. I was just banging my head and working around this from last 2 days, and couldn't succeed. It worked liked a charm, Thank you !Drobman
M
-3

Ensure you set windowTranslucentStatus to false in your styles.

Mopes answered 25/2, 2016 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.