I have a view with a Edittext field on top of an ImageView. When the keyboard comes up I want the window to resize so that EditText is no longer hidden by the keyboard. In the AndroidManifest file I declared android:windowSoftInputMode="adjustResize"
and the screen is resized but the issue is that I want the ImageView to not be re-sized. How can I make the ImageView unaffected?
Could I inflate an additional layout with just the ImageView or will the resize still affect it?
Android windowSoftInputMode – Resize the application for the soft-keyboard. Posted on October 25, 2010 by Lars Vogel. Android has the so-called Input Method Framework to support different input methods, e.g. keyboard, soft-keyboard, handwriting etc.
try this android:windowSoftInputMode="adjustResize" in your activity in manifest file.
The full solution involves a few key points
RelativeLayout
, so that Views
can be setup to overlap one anotherEditText
with the bottom of the Windows
using android:layout_alignParentBottom="true"
android:windowSoftInputMode="adjustResize"
in your manifest, so that the bottom of the Window
changes when the keyboard pops up (as you mentioned)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
Adding ScrollView
was making my image scrollable which I wanted to avoid so I used this samples-keyboardheight calculator and onKeyboardHeightChanged
recalculated position of the bottom Edittext
placed it above Keyboard and used this flag in Manifest.
android:windowSoftInputMode="adjustNothing|stateHidden"
Here is KeyboardHeightProvider
:
import android.app.Activity; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager.LayoutParams; import android.widget.PopupWindow; /** * The keyboard height provider, this class uses a PopupWindow * to calculate the window height when the floating keyboard is opened and closed. */ public class KeyboardHeightProvider extends PopupWindow { /** The tag for logging purposes */ private final static String TAG = "sample_KeyboardHeightProvider"; /** The keyboard height observer */ private KeyboardHeightObserver observer; /** The cached landscape height of the keyboard */ private int keyboardLandscapeHeight; /** The cached portrait height of the keyboard */ private int keyboardPortraitHeight; /** The view that is used to calculate the keyboard height */ private View popupView; /** The parent view */ private View parentView; /** The root activity that uses this KeyboardHeightProvider */ private Activity activity; /** * Construct a new KeyboardHeightProvider * * @param activity The parent activity */ public KeyboardHeightProvider(Activity activity) { super(activity); this.activity = activity; LayoutInflater inflator = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); this.popupView = inflator.inflate(R.layout.popupwindow, null, false); setContentView(popupView); setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_RESIZE | LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); parentView = activity.findViewById(android.R.id.content); setWidth(0); setHeight(LayoutParams.MATCH_PARENT); popupView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (popupView != null) { handleOnGlobalLayout(); } } }); } /** * Start the KeyboardHeightProvider, this must be called after the onResume of the Activity. * PopupWindows are not allowed to be registered before the onResume has finished * of the Activity. */ public void start() { if (!isShowing() && parentView.getWindowToken() != null) { setBackgroundDrawable(new ColorDrawable(0)); showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0); } } /** * Close the keyboard height provider, * this provider will not be used anymore. */ public void close() { this.observer = null; dismiss(); } /** * Set the keyboard height observer to this provider. The * observer will be notified when the keyboard height has changed. * For example when the keyboard is opened or closed. * * @param observer The observer to be added to this provider. */ public void setKeyboardHeightObserver(KeyboardHeightObserver observer) { this.observer = observer; } /** * Get the screen orientation * * @return the screen orientation */ private int getScreenOrientation() { return activity.getResources().getConfiguration().orientation; } /** * Popup window itself is as big as the window of the Activity. * The keyboard can then be calculated by extracting the popup view bottom * from the activity window height. */ private void handleOnGlobalLayout() { Point screenSize = new Point(); activity.getWindowManager().getDefaultDisplay().getSize(screenSize); Rect rect = new Rect(); popupView.getWindowVisibleDisplayFrame(rect); // REMIND, you may like to change this using the fullscreen size of the phone // and also using the status bar and navigation bar heights of the phone to calculate // the keyboard height. But this worked fine on a Nexus. int orientation = getScreenOrientation(); int keyboardHeight = screenSize.y - rect.bottom; if (keyboardHeight == 0) { notifyKeyboardHeightChanged(0, orientation); } else if (orientation == Configuration.ORIENTATION_PORTRAIT) { this.keyboardPortraitHeight = keyboardHeight; notifyKeyboardHeightChanged(keyboardPortraitHeight, orientation); } else { this.keyboardLandscapeHeight = keyboardHeight; notifyKeyboardHeightChanged(keyboardLandscapeHeight, orientation); } } /** * */ private void notifyKeyboardHeightChanged(int height, int orientation) { if (observer != null) { observer.onKeyboardHeightChanged(height, orientation); } } public interface KeyboardHeightObserver { void onKeyboardHeightChanged(int height, int orientation); } }
popupwindow.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/popuplayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:orientation="horizontal"/>
Here is MainActivity.java
:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; public class MainActivity extends AppCompatActivity implements KeyboardHeightProvider.KeyboardHeightObserver { private KeyboardHeightProvider keyboardHeightProvider; private ViewGroup relativeView; private float initialY; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); keyboardHeightProvider = new KeyboardHeightProvider(this); relativeView = findViewById(R.id.bottomEditor); relativeView.post(() -> initialY = relativeView.getY()); View view = findViewById(R.id.activitylayout); view.post(() -> keyboardHeightProvider.start()); } @Override public void onKeyboardHeightChanged(int height, int orientation) { if(height == 0){ relativeView.setY(initialY); relativeView.requestLayout(); }else { float newPosition = initialY - height; relativeView.setY(newPosition); relativeView.requestLayout(); } } @Override public void onPause() { super.onPause(); keyboardHeightProvider.setKeyboardHeightObserver(null); } @Override public void onResume() { super.onResume(); keyboardHeightProvider.setKeyboardHeightObserver(this); } @Override public void onDestroy() { super.onDestroy(); keyboardHeightProvider.close(); } }
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?> <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:id="@+id/activitylayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageView2" android:layout_width="match_parent" android:layout_height="match_parent" android:adjustViewBounds="true" android:scaleType="fitCenter" /> <RelativeLayout android:id="@+id/bottomEditor" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" > <EditText android:id="@+id/edit_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_toStartOf="@+id/btn_send" android:hint="Add caption" android:paddingBottom="12dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingStart="8dp" android:paddingTop="12dp" /> <ImageButton android:id="@+id/btn_send" android:layout_width="48dp" android:layout_height="48dp" android:layout_alignBottom="@+id/edit_message" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginEnd="4dp" android:layout_marginRight="4dp" app:srcCompat="@android:drawable/ic_menu_send" /> </RelativeLayout> </RelativeLayout>
P.S. : Keyboard height calculation code is copied from siebeprojects
Here is demo example app of implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With