39

I have an activity with an editText in the middle. When I click on the editText the keyboard appears, and the screen moves so that the editText is just above the keyboard, covering the other stuff that is below.

I don't want to resize or add padding to the layout. I need that the screen scrolls to the top the amount of space that I need to see also the other stuff below. In other words, I'd like to select the position of the editText when the keyboard appears. It would be enough also if the screen scrolls up completely, showing me the bottom of the layout.

I tried to put the layout in a scrollView adding this code on the editText

    editText.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            //make the view scroll down to the bottom
            scrollView.scrollTo(0, scrollView.getBottom());

        }
    });

but it doesn't work. Does anyone have an idea? Thank you in advance!

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
giangiska
  • 403
  • 1
  • 6
  • 9

10 Answers10

45

use android:windowSoftInputMode="adjustPan"

"adjustResize"

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

"adjustPan"

The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window.

For example inn your manifest file:-

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

Late answer.But surely it helps anyone.

Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159
26

I had a similar problem once, I resolved using:

    android:windowSoftInputMode="adjustResize"

in the AndroidManifest.xml.

If you use a RelativeLayout start with the bottom element that must be hooked to the parent bottom and then hook the other element above the previous.

If you use LinearLayout wrap it in a RelativeLayout and hook the LinearLayout to parentBottom.

In this way when the keyboard pops up you will see the bottom of your layout.

Hope this helps.

Darush
  • 11,403
  • 9
  • 62
  • 60
DrChivas
  • 1,025
  • 8
  • 14
  • 6
    What does "If you use a RelativeLayout start with the bottom element that must be hook to parent bottom and the hook the other element above the previous." Mean? I did not undersand what do you mean by hook, can you explain further please? – Josh Oct 13 '14 at 11:11
  • What if the part of the screen I want to show when the keyboard is visible must not be hooked to parent bottom but centered in the page? – Raphael Royer-Rivard Jul 26 '15 at 19:01
  • Not works in my "fragment" getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); –  Apr 12 '16 at 09:30
  • 1
    clarify your answer please – aya salama Nov 27 '16 at 11:46
  • 2
    I think what is meant (and works for me) is wrapping the LinearLayout in a RelativeLayout and set `android:layout_alignParentBottom="true"` in the former. – Matthias Jan 06 '17 at 14:34
  • what if parent is `ConstraintLayout` ? I tried using `android:windowSoftInputMode="adjustResize"` and parent is `ConstraintLayout` but still it doesn't move screen up – MMK Jun 27 '18 at 07:27
11

I had a this problem , I resolved by this code :

myEdittext.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    myscrollview.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            View lastChild = myscrollview.getChildAt(myscrollview.getChildCount() - 1);
                            int bottom = lastChild.getBottom() + myscrollview.getPaddingBottom();
                            int sy = myscrollview.getScrollY();
                            int sh = myscrollview.getHeight();
                            int delta = bottom - (sy + sh);
                            myscrollview.smoothScrollBy(0, delta);
                        }
                    }, 200);
                }
            });
user6581344
  • 111
  • 1
  • 5
  • 3
    Thanks! I also added `myEdittext.setOnFocusChangeListener { _, hasFocus -> if (hasFocus) scrollUpLayout() }` with your function. And added `android:windowSoftInputMode="adjustResize"` to AndroidManifest activity. – CoolMind Feb 04 '19 at 12:58
  • Thanks, it worked for me as well. android:windowSoftInputMode="adjustResize" and with setOnFocusChangeListener instead on setOnClickListener. – Krishna Upadhya Feb 20 '21 at 05:52
  • Thanks man, It is working nicely. But in my case with setOnClickListener it is not working for the first click and working fine for next clicks, and with setOnFocusChangeListener it is working on the first click. – Rahul Sharma Mar 10 '23 at 15:33
7

This works for me

android:windowSoftInputMode="stateVisible|adjustResize"

in androidmanifest for the activity

Vinayaka Dj
  • 105
  • 1
  • 4
5

This works: -

There is an issue with the scroll up when Keyboard opens up in Constraint Layout. Don't use that.

To achieve "Scroll the screen up when keyboard appears" Try this

Use Linear layout and ScrollView

and fill_parent in Scroll view. and any Text field in the scroll view.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   android:gravity="center">

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true">


</ScrollView>
</LinearLayout>
4

Add this library to your gradle dependencies:

dependencies {
    compile 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.1.0'
}

and use this code:

KeyboardVisibilityEvent.setEventListener(getActivity(), new KeyboardVisibilityEventListener() {
    @Override
    public void onVisibilityChanged(boolean isOpen) {

        if (isOpen && MY_EDIT_TEXT.hasFocus()) {

            //scroll to last view
            View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
            int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
            int sy = scrollLayout.getScrollY();
            int sh = scrollLayout.getHeight();
            int delta = bottom - (sy + sh);

            scrollLayout.smoothScrollBy(0, delta);
        }
    }
});
Homayoon Ahmadi
  • 1,181
  • 1
  • 12
  • 24
1

It only worked for me after I changed from Constraint Layout to Linear Layout and added

android:windowSoftInputMode="adjustResize".

and removed

<item name="android:windowFullscreen">true</item> from the Activity style

1

just add

android:screenReaderFocusable="true"

to your XML file, it will work like a charm

1

The simple way to do it in Kotlin (reused from user user6581344 's answer), and i used it to perform a manual scroll to EditText when focus is set and keyboard is shown, as need it with extra bottom padding between keypad and the EditText:

    binding.scrollView.postDelayed(object:Runnable {

        override fun run() {

            val extraBottomPadding = 100

            val manualScroll = txtFullName.y + extraBottomPadding

            scrollView.smoothScrollBy(0, manualScroll.toInt())
        }

    }, 200)
Osama Remlawi
  • 2,356
  • 20
  • 21
0

This code works for me, no need to add clickListener() or focusChanhgeListener() in your activity override onUserInteraction() function

@Override
public void onUserInteraction() {
    super.onUserInteraction();
    if (editText.hasFocus() ) { // to check if user is clicked on edit text 
        if (scroll.getVerticalScrollbarPosition() != scroll.getBottom())  // if scrollview is not already on the bottom 
            scroll.post(() -> scroll.scrollTo(0, scroll.getBottom()));
    }
}