Android How to Adjust Layout in Full Screen Mode When Softkeyboard Is Visible

How to adjust layout when soft keyboard appears

Just add

android:windowSoftInputMode="adjustResize"

in your AndroidManifest.xml where you declare this particular activity and this will adjust the layout resize option.

Sample Image

some source code below for layout design

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

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="FaceBook"
android:textAppearance="?android:attr/textAppearanceLarge" />

<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="username" >

<requestFocus />
</EditText>

<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/editText1"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="password" />

<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="20dp"
android:text="Log In" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="17dp"
android:gravity="center"
android:text="Sign up for facebook"
android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

Phonegap - Android How to adjust layout in Full Screen Mode when softkeyboard is visible

After spending a day trying almost every possible solution in this website, nothing worked for me. At the end I was able to find a work around based on the following two proposed solutions:

https://stackoverflow.com/a/19494006/1435991

this link shows a workaround to fix the problem for an android app; however I don't have any experience working in android, so the question is: how to include this peace of code in a Phonepap project?.

https://stackoverflow.com/a/18610405

This link suggests specifically a solution for phonegap, which did not work for me, but more important gave an idea of how I could add custom android code on a phonegap project.

SOLUTION

1- Create the following class(as indicate in first link) in your phonegap project:



package com.test.android;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

public class AndroidBug5497Workaround {
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

public static void assistActivity (Activity activity) {
new AndroidBug5497Workaround(activity);
}

private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;

private AndroidBug5497Workaround(Activity activity) {
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}

private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard/4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}

private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}

}


This class can be placed in this location in your project: (I was not able to load an image in this forum, I need at lease 10 reputation). Find the image sample in this url:

check for more clarity

2- Any time you create a phonegap project you get a class called your_project_name.java. In my case it is test1.java. Edit the class and add the following sentence in method onCreate:



AndroidBug5497Workaround.assistActivity(this);


Your code should look like this:



public class test1 extends DroidGap
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set by in config.xml
super.loadUrl(Config.getStartUrl());
//super.loadUrl("file:///android_asset/www/index.html")
AndroidBug5497Workaround.assistActivity(this);
}
}


3- This fixed the problem in my app.

Android keyboard covers the view but only in fullscreen mode

  • adjustResize

The activity's main window is always resized to make room for the soft
keyboard on screen.

But it has limitations when your application is in fullscreen mode. Android official documentation says:

If the window's layout parameter flags include FLAG_FULLSCREEN, this
value for softInputMode will be ignored; the window will not resize,
but will stay fullscreen.

Check for more info:doc

  • getWindowVisibleDisplayFrame

Retrieve the overall visible display size in which the window this
view is attached to has been positioned in. This takes into account
screen decorations above the window, for both cases where the window
itself is being position inside of them or the window is being placed
under then and covered insets are used for the window to position its
content inside. In effect, this tells you the available area where
content can be placed and remain visible to users.

So,We need to detect when keyboard open and hide and calculate its size as per view.Below is example code.


Example code:

Manifest:

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">

<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/frame"
android:layout_height="match_parent"
tools:context=".MainActivity">

<WebView
android:id="@+id/MyWebView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

MainActivity.java

 public class MainActivity extends AppCompatActivity {
WebView webView;
RelativeLayout relativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
setContentView(R.layout.activity_main);
relativeLayout=findViewById(R.id.frame);
webView=findViewById(R.id.MyWebView1);
this.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int height = relativeLayout.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
if (diff != 0) {
if (relativeLayout.getPaddingBottom() != diff) {
relativeLayout.setPadding(0, 0, 0, diff);
}
} else {
if (relativeLayout.getPaddingBottom() != 0) {
relativeLayout.setPadding(0, 0, 0, 0);
}
}
}
});
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = "<html>\n" +
" <body style=\"padding: 0; margin: 0; box-sizing: border-box; border: 5px solid red; width: 100vw; height: 100vh;\">\n" +
" test\n" +
" <div style=\"width: 50vw; height: 70vh; border: 1px solid green;\">some div</div>\n" +
" <input placeholder=\"Type here and KB will cover this\">\n" +
" </body>\n" +
"</html>";
webView.loadDataWithBaseURL("", html, mimeType, encoding, "");
}

}

styles.xml:

<resources xmlns:tools="http://schemas.android.com/tools">

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

</resources>

Output screen:

Sample Image

Adjust layout when soft keyboard is on

Here's a solution that works like the Evernote login screen:

First, define a class that will be your special LinearLayout like this:

public class MyLayout extends LinearLayout {

public MyLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyLayout(Context context) {
super(context);
}

private OnSoftKeyboardListener onSoftKeyboardListener;

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
if (onSoftKeyboardListener != null) {
final int newSpec = MeasureSpec.getSize(heightMeasureSpec);
final int oldSpec = getMeasuredHeight();
if (oldSpec > newSpec){
onSoftKeyboardListener.onShown();
} else {
onSoftKeyboardListener.onHidden();
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public final void setOnSoftKeyboardListener(final OnSoftKeyboardListener listener) {
this.onSoftKeyboardListener = listener;
}

public interface OnSoftKeyboardListener {
public void onShown();
public void onHidden();
}

}

This layout listens to measure changes, and if new measurements are < than the old ones, that means part of the screen is eaten by soft keyboard.

Though, for it to work, in your manifest you need to set android:windowSoftInputMode="adjustResize" so the content will be resized and not just shifted.

And the whole system works as follows:
You have your layout:

<MyLayout id="layout">
<SomeImage id="image"/>
<SomeText>
<SomeInput>
</MyLayout>

It's like evernotes login screen.
Then, in your activity:

((MyLayout)findViewById(R.id.layout)).setOnSoftKeyboardListener(new OnSoftKeyboardListener() {
@Override
public void onShown() {
findViewById(R.id.image).setVisibility(View.GONE);
}
@Override
public void onHidden() {
findViewById(R.id.image).setVisibility(View.VISIBLE);
}
});

Then go to manifest.xml and set

android:windowSoftInputMode="adjustResize"

What will happen, is when soft keyboard is shown, it'll hide the image and will resize the rest of content. (You can actually see how text is resized in Evernote)

Image hide is, of course, one of the many things you can do. But you must be careful, since different layout changes will also call onMeasure.

Of course it's a dirty variant. You need to check for orientation changes, and the right time when actually take the measurements, and maybe some more logic when comparing the new specs with the old ones. But i think this is the only way to do it.

Move layouts up when soft keyboard is shown?

Yes, check out this article on the Android developers' site which describes how the framework handles the soft keyboard appearing.

The android:windowSoftInputMode attribute can be used to specify what happens on a per-activity basis: whether the layout is resized or whether it scrolls etc.

Cannot adjust layout when softkeyboard is up properly

Try this in the android manifest file corresponding to the activity.

<activity android:windowSoftInputMode="adjustPan|adjustResize”> </activity>

** Your given layout code’s root is LinearLayout. This layout don’t find enough space to adjust your view and keyboard. Please make ScrollView as root and other layout elements inside of Scrollview.



Related Topics



Leave a reply



Submit