Adjust Layout When Soft Keyboard Is On

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>

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.

Android: Resize only parts of view with soft keyboard on screen

The full solution involves a few key points

  • Use RelativeLayout, so that Views can be setup to overlap one another
  • Align the EditText with the bottom of the Windows using android:layout_alignParentBottom="true"
  • Use android:windowSoftInputMode="adjustResize" in your manifest, so that the bottom of the Window changes when the keyboard pops up (as you mentioned)
  • Put the ImageView inside a ScrollView so that the ImageView can be larger than the Window, and disable scrolling on the ScrollView by using ScrollView#setEnabled(false)

Here is the layout file

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.so3.MainActivity">
<ScrollView
android:id="@+id/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/stickfigures"/>
</ScrollView>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/holo_blue_bright"
android:text="Please enter text"
android:textSize="40sp"
android:gravity="center_horizontal"/>
</RelativeLayout>

Here is my Activity

package com.so3;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ScrollView;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ScrollView sv = (ScrollView)findViewById(R.id.scroll);
sv.setEnabled(false);
}
}

My AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.so3" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.so3.MainActivity"
android:windowSoftInputMode="adjustResize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Screen shots of my solution

screenshot 1
screenshot 2

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.

Android: How do I prevent the soft keyboard from pushing my view up?

You can simply switch your Activity's windowSoftInputModeflag to adjustPan in your AndroidMainfest.xml file inside your activity tag.

Check the official documentation for more info.

<activity
...
android:windowSoftInputMode="adjustPan">
</activity>

If your container is not changing size, then you likely have the height set to "match parent". If possible, set the parent to "Wrap Content", or a constraint layout with constraingts to top and bottom of parent.

The parent container will shrink to fit the available space, so it is likely that your content should be inside of a scolling view to prevent (depending on the phone manufacturer and the layout choosen...)

  1. Content being smashed together
  2. Content hanging off the screen
  3. Content being inacccessable due to it being underneath the keyboard

even if the layout it is in is a relative or constraint layout, the content could exhibit problems 1-3.

How to move the layout up when the soft keyboard is shown android

I somehow achieved this by knowing the status of the soft keyboard on the device. i move the layout to y position when the keyboard is shown and moved back to its original position when not shown. this works fine, followed this guidelines.

Adjust the layout when the Android soft keyboard is shown or hidden

The best place to find out whether your layout changed due to the keyboard (dis)appearing and acting on the change is inside onMeasure() of the root layout.

In more detail, I made a custom LinearLayout, which is used as my root layout. I overrided the onMeasure and I calculate what is the current keyboard height. Depending on the keyboard's height and whether my attachment grid should be visible or not, I change the visibility of the attachment grid. I can even set the grid's height the same as the keyboard.

The results looks like the grid was always beneath the keyboard and the textview remains in the same vertical place.

The layout changes when the soft keyboard appears

in manifest for this activity put

android:windowSoftInputMode="adjustNothing"


Related Topics



Leave a reply



Submit