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>
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.
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: http://stackoverflow.com/a/9108219/325479
*/
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)
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.
Try to put your LinearLayout
on a ScrollView
, that worked for me once..
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.
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.
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.
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.
Ensure you set windowTranslucentStatus
to false
in your styles.
来源:https://stackoverflow.com/questions/8398102/androidwindowsoftinputmode-adjustresize-doesnt-make-any-difference