So this question has been asked few times already in here in the past years and non of the solutions worked for me.
The problem is that when I use AdjustPan
to move the softkeyboard it hides part of the EditText
as follows:
The solutions I tried are:
Solution 1 (2011)
Solution 2 (2014)
Solution 3 (2013)
Most of the answers include using AdjustPan/AdjustResize
so I will just say that none of them give the desired solution (Showing the whole EditText
when keyboard is opened).
I was thinking maybe in 2019 there is a working solution for this problem.
The xml for this layout is:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_height="match_parent"
android:background="@color/colorWhite"
tools:context=".ChatActivity">
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/actionbar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/colorGrayBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.appcompat.widget.ActionMenuView>
<TextView
android:id="@+id/tv_This"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:fontFamily="@font/open_sans"
android:text="@string/ActivityChat_This"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/actionbar" />
<View
android:id="@+id/v_Line"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginRight="24dp"
android:background="@color/colorLightGray"
app:layout_constraintTop_toBottomOf="@+id/tv_This" />
<androidx.cardview.widget.CardView
android:id="@+id/imagecard"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="16dp"
app:cardCornerRadius="20dp"
app:layout_constraintBottom_toBottomOf="@+id/actionbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/ivPersonPic"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:fontFamily="@font/assistant_bold"
android:textColor="@color/colorLightPurple"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/actionbar"
app:layout_constraintStart_toEndOf="@+id/imagecard"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_Messages"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/constraint2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_Line"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintHeight_percent="0.1">
<EditText
android:id="@+id/et_Message"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/et_rounded"
android:fontFamily="@font/assistant"
android:gravity="center_vertical"
android:hint="@string/ActivityChat_Type"
android:inputType="textMultiLine|textPersonName"
android:paddingEnd="32dp"
android:paddingStart="32dp"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.85" />
<ImageButton
android:id="@+id/ib_Send"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_chats_send"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.1" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="0dp"
android:layout_height="0dp"
app:itemBackground="@color/colorWhite"
app:itemIconTint="@drawable/btm_nav"
app:itemTextColor="@drawable/btm_nav"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/menu_btm_nav" />
</androidx.constraintlayout.widget.ConstraintLayout>
I had a lot of problems with the keyboard myself, but I prefer using android:windowSoftInputMode="adjustResize"
so you can handle the changes yourself. You should add a windowInsetsListener to your root view and if you don't have a transparent navigation bar the systemWindowInsetBottom
should only be the keyboard. So you can just add padding to the container you're interested in. This is an example I use:
rootContainer.setOnApplyWindowInsetsListener { view, windowInsets ->
var containerPadding = 0
if (windowInsets.systemWindowInsetBottom > 0) {
val bottomBarHeight = bottomBar.bottom - bottomBar.top
containerPadding = windowInsets.systemWindowInsetBottom - bottomBarHeight
}
if (containerPadding < 0) {
containerPadding = 0
}
contentView.bottomPadding = containerPadding
return@setOnApplyWindowInsetsListener windowInsets.replaceSystemWindowInsets(windowInsets.systemWindowInsetLeft, windowInsets.systemWindowInsetTop, windowInsets.systemWindowInsetRight, 0)
}
This way you can move the container above the bottomBar up (which has your EditText
in it).
For me this was the best option I've found so far. Most options rely on GlobalLayoutListeners and see how much it changes, but this is far more reliable.
Try this, add this code in your AndroidManifest.xml
activity
android:windowSoftInputMode="adjustPan"
Add the following into your root Layout at the xml
file
android:fitsSystemWindows="true"
Wrap your base layout in a ScrollView set hight to match_parent and fillViewport to true:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
and in manifest:
<activity
android:name=".YourActivity"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
Use this as a second solution, here I check if the layout is not showing completely after the keyboard appears and in that case scroll the sview for 200 pixels. The code has some comments too.
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ScrollView;
public class MainActivity extends AppCompatActivity {
private ScrollView sView;
private int heightDiff;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sView = findViewById(R.id.scrollView);
//Here we get the height of soft keyboard by observing changes of the scrollView's height.
sView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
heightDiff = sView.getRootView().getHeight() - sView.getHeight();
}
});
final EditText editText = findViewById(R.id.et_Message);
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!isVisibleWhileSoftKeyboardShowing(editText) && hasFocus) {
sView.postDelayed(new Runnable() {
@Override
public void run() {
sView.smoothScrollBy(0, 200);
}
}, 500);
}
}
});
}
/**
* check if a view is currently visible in the screen or not
*
* @param view
* @return
*/
public boolean isVisibleWhileSoftKeyboardShowing(final View view) {
if (view == null) {
return false;
}
if (!view.isShown()) {
return false;
}
final Rect actualPosition = new Rect();
view.getGlobalVisibleRect(actualPosition);
final Rect screen = new Rect(0, 0, getScreenWidth(), getScreenHeight() - heightDiff);
return actualPosition.intersect(screen);
}
/**
* to get screen width
*
* @return
*/
public static int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
/**
* to get screen height
*
* @return
*/
public static int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
}
First add ScrollView into your XML and add below lines into AndroidManiFest.xml in your activity tag where you use this search EditText.
android:windowSoftInputMode="stateAlwaysHidden|adjustResize|adjustPan|adjustResize
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