2

I would like to "instruct" android how to correctly adapt the screen layout when the user does something that pops up the keyboard.

Actually the when the keyboard is shown android simple draws it over the bottomest items of the screen. Although it is a simple and, sometimes, correct approach

in some circunstances it goes pretty bad. For example if the inputtext being typed is the bottomest item of the screen... the keyboard will simple cover it and the user will lost the information about what he is typing.

another scenario is when the keyboard covers only partially some item, then android runs into a crazy state where the screen gets unstable

enter image description here

the image doesn't show, but these two partially covered buttons are blinking like crazy when the keyboard pops up

So again the question is... how can i tell android which layout items it can shrink, or simple remove from screen, in order to create space to display the keyboard?

=================UPDATE==============

I think this whole keyboard layout situation has 2 possible "best scenarios":
1- the information i want to show user is on top of screen so i would like the keyboard cover the bottom
2- the information i want to show is ont bottom so i want the keyboard "push" the screen up so the user can see what is on bottom like the next photo

enter image description here

the ideal solution is not an "app wide" configuration since the behavior should be chose layout by layout

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Rafael Lima
  • 3,079
  • 3
  • 41
  • 105
  • Share your `layout.xml` files with question – AskNilesh Oct 03 '18 at 09:57
  • @NileshRathod, i would like a generic standard android way... something like "picking" views from my layout and manually setting it as `GONE` is really not what im loking for – Rafael Lima Oct 05 '18 at 10:39

5 Answers5

5

Use

android:windowSoftInputMode="adjustPan"

And at your screen you set the root to be a ScrollView with android:fitSystemView="true"

Also set your button that is below from edittext to focusable and focusableInTouchMode to true.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
2

you can add this line to your manifest (in your activity tag)

android:windowSoftInputMode="adjustPan|adjustResize"

this will scroll the views so this way soft keyboard wont covers the view,

but i dont know if you could specifically tell android which items to cover...

Mohamad Rostami
  • 420
  • 3
  • 17
1

I used a "special" (??) approach to hide/change some interface when the keyboard is shown: an hidden fullscreen View that when the keyboard became visible its Height changes and the difference is the amount of pixels occuped from the keyboard. It's easy to intercept that event using:

View.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //the resize event will be triggered here
        ...
    }
});
emandt
  • 2,547
  • 2
  • 16
  • 20
1

I usually made such with Rx (it allows to unsubscribe easy when view destroyed) Inside my BaseFragment:

protected fun setSoftwareKeyboardListener(root: View) {
    addDisposable(Flowable.create<Boolean>({ emitter ->
        root.viewTreeObserver.addOnGlobalLayoutListener {
            val parentHeight = root.rootView.height
            val heightDiff = parentHeight - root.height
            emitter.onNext(heightDiff > parentHeight / 4)
        }
    }, BUFFER)
        .subscribe { if (it) onKeyboardOpened() else onKeyboardClosed() })
}

protected open fun onKeyboardOpened() {}

protected open fun onKeyboardClosed() {}

And inside fragment, which extend BaseFragment:

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    view?.let { setSoftwareKeyboardListener(it) }
}
Andrii Turkovskyi
  • 27,554
  • 16
  • 95
  • 105
0

You can use the following approach to solve your problem.

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:orientation="vertical"
        android:padding="16dp">

        <ImageView
            android:id="@+id/image_logo"
            android:layout_width="240dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:adjustViewBounds="true"
            android:src="@drawable/demo"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/edit_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/image_logo" />

        <EditText
            android:id="@+id/edit_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_login" />

        <Button
            android:id="@+id/btn_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/login"
            android:textAllCaps="false"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_password" />

        <Button
            android:id="@+id/btn_password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:text="@string/login_with"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_password" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:text="@string/forgot_password_q"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_login"
            app:layout_constraintVertical_bias="0.0" />

    </android.support.constraint.ConstraintLayout>

</ScrollView>

In this case you can use default windowSoftInputMode.

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

As a result user can scroll the UI when the software keyboard appears.

before scrolling

after scrolling

software keyboard is gone

Alex
  • 888
  • 2
  • 7
  • 21