Reputation: 1839
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:
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>
Upvotes: 10
Views: 5382
Reputation: 729
Replace the EditText
view with a TextInputEditText
view and simply add padding to its bottom, like:
<com.google.android.material.textfield.TextInputLayout
...
<com.google.android.material.textfield.TextInputEditText
android:paddingBottom="30dp"
...
android:textSize="15sp"
android:hint="@string/txt_hint_add_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
Upvotes: 0
Reputation: 2990
There is one trick to do it:
1- put the EditText inside a CardView
2- style the CardView to looks like a TextEdit
3- add these properties to the EditText
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:background="@android:color/transparent"
Upvotes: -1
Reputation: 9814
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.
Upvotes: 0
Reputation: 520
i had exact same issue and solved this problem forever with a 'easy implementation' and 'tested' method..the idea is that when the edit text gains focus scroll view auto scrolls to bottom.let me show you how...
first you should use nested scroll view as parent of main layout
second add a library to find out when keyboard opens
implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.0.1'
third add this class to your project
public class KeyboardUtil {
private View decorView;
private View contentView;
//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);
}
}
}
};
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
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
/**
* 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);
}
}
public void enable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void disable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public static void adjustResize(Activity activity, final NestedScrollView scrollView) {
KeyboardVisibilityEvent.setEventListener(
activity,
new KeyboardVisibilityEventListener() {
@Override
public void onVisibilityChanged(boolean isOpen) {
// some code depending on keyboard visiblity status
if (isOpen) {
//Scroll view scrolls bottom without changing focus
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);
int bottom = lastChild.getBottom() + scrollView.getPaddingBottom();
int sy = scrollView.getScrollY();
int sh = scrollView.getHeight();
int delta = bottom - (sy + sh);
scrollView.smoothScrollBy(0, delta);
} else {
//Toast.makeText(context, "keyboard is close", Toast.LENGTH_SHORT).show();
}
}
});} }
then use it in your activity like
new KeyboardUtil(activity,nestedScrollView);
KeyboardUtil.adjustResize(activity,nestedScrollView);
and if you are in fragment you can pass below code as activity:
(AppCompatActivity)context
Upvotes: -1
Reputation: 1432
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
Upvotes: 2
Reputation: 89
In your Layout
file add the following line in the Constraint
tag.
android:isScrollContainer="true"
Upvotes: 0
Reputation: 4448
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"
Upvotes: 5
Reputation: 17037
First of all I think your layout should be improved, there is no need to use two ConstraintLayout
in a single xml file and the second one is a child of the first / main one. The idea behind this view is to flatten your whole layout, so as first step I think you should get rid off the second ConstraintLayout
.
I've create a simple layout which looks a little like yours in order to test if my implementation will work, so here is the layout file:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:layout_width="0dip"
android:layout_height="0dip"
app:layout_constraintBottom_toTopOf="@+id/edit_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edit_text"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/rounded"
android:gravity="center_vertical"
android:hint="Text"
android:importantForAutofill="no"
android:inputType="textMultiLine|textPersonName"
android:paddingStart="32dip"
android:paddingEnd="32dip"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
app:layout_constraintEnd_toStartOf="@+id/btn_send"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/btn_send"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="SEND"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="HardcodedText" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#c5c6c7"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The structure looks similar to yours, at least the part with the BottomNavigatioView
, EditText
and the Button
. Adding android:windowSoftInputMode="adjustPan"
to the Activity
which holds this layout will give this result (tested on a few devices) :
Upvotes: 0
Reputation: 554
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint2"
Add padding bottom in ConstraintLayout like android:paddingBottom="8dp"
Remove android:layout_marginBottom="8dp" from Edittext and Imageview i.e. android:id="@+id/et_Message" and android:id="@+id/ib_Send"
Then rerun again
Upvotes: -1