AlexS
AlexS

Reputation: 972

Scrolling a layout when the keyboard appears

My screen resizing to top when keyboard appears and hiding toolbar (FrameLayout), i need just scroll chat items to top and hold my frame layout on the top. I try some examples from Google and SO, but nothing helps to me.

<activity
        android:name=".screen.workshiftscreen.WorkShiftActivity"
        android:launchMode="singleTop"
        android:windowSoftInputMode="adjustPan"
        android:screenOrientation="portrait" />

My fragment layout after some edits:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/bg_second"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginBottom="@dimen/space_large_s"
        android:background="?attr/bg_main"
        android:padding="@dimen/space_small_m">

        <TextView
            *params* />

        <ImageView
            *params* />
    </FrameLayout>

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_chat"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/edit_bar"
        android:layout_below="@+id/title">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/messages"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/space_medium_l"
                android:paddingRight="@dimen/space_medium_l"
                android:scrollbars="vertical" />
    </android.support.v4.widget.SwipeRefreshLayout>

    <LinearLayout
        android:id="@+id/edit_bar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

        <View
            *params* />

        <LinearLayout
            *params*>

            <EditText
                android:id="@+id/message_input"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:hint="@string/prompt_message"
                android:imeActionId="@+id/send"
                android:imeActionLabel="@string/action_send"
                android:imeOptions="actionSend"
                android:maxLines="6"
                tools:ignore="Autofill,InvalidImeActionId,TextFields" />

            <ImageButton
                android:id="@+id/send_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="@dimen/space_small_l"
                android:background="@android:color/transparent"
                android:contentDescription="@string/action_send"
                android:src="@android:drawable/ic_menu_send" />

            <ImageButton
                android:id="@+id/bottom_buttom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="@dimen/space_small_l"
                android:background="@android:color/transparent"
                android:contentDescription="@string/action_send"
                android:src="@drawable/down_active" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

Also some detailed pictures Screenshot:

screenshot How can i do it like that? enter image description here

Upvotes: 7

Views: 24638

Answers (4)

Islam Assem
Islam Assem

Reputation: 1512

First, you need to detect keyboard appearance

boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
    print("keyboard " + opened);
}

// ContentView is the root view of the layout of this activity/fragment    
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {

    Rect r = new Rect();
    contentView.getWindowVisibleDisplayFrame(r);
    int screenHeight = contentView.getRootView().getHeight();

    // r.bottom is the position above soft keypad or device button.
    // if keypad is shown, the r.bottom is smaller than that before.
    int keypadHeight = screenHeight - r.bottom;

    Log.d(TAG, "keypadHeight = " + keypadHeight);

    if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
        // keyboard is opened
        if (!isKeyboardShowing) {
            isKeyboardShowing = true
        binding.scrollView.fullScroll(ScrollView.FOCUS_UP)
        }
    }
    else {
        // keyboard is closed
        if (isKeyboardShowing) {
            isKeyboardShowing = false
        binding.scrollView.fullScroll(ScrollView.FOCUS_UP)
        }
    }
}

});

when keyboard appear change scroll to top

Upvotes: 1

Vikas Borkar
Vikas Borkar

Reputation: 496

use android:windowSoftInputMode="adjustResize" in manifest for the activity
and put the content you want to scroll in Scrollview/NestedScrollView
and make the views(the ones you want to stick at the bottom) below scroll as alignedToBottom and specify scroll to be above those views.

Check the sample below, you can create a similar layout according to your requirements.
Try to understand how it is working, you can use any container view instead of RelativeLayout.

Sample: (for Activity/Fragment layout)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/rlRoot"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

<!--Scrollable view: RecyclerView, NestedScrollView, Webview etc-->
<ScrollView
    android:id="@+id/nsScroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/btnNext">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        .
        .
        .
        <AutoCompleteTextView
            android:id="@+id/etDob"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:imeOptions="actionDone"
            android:inputType="date"
            android:maxLines="1" />
        .
        .
        .
    </LinearLayout>
</ScrollView>

<!--Sticks at the bottom-->
<Button
    android:id="@+id/btnNext"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:textColor="@android:color/white" />

Upvotes: 5

Deep Patel
Deep Patel

Reputation: 2644

"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.

Know more from this link and try different modes for your requirements

Upvotes: 0

Kajol Chaudhary
Kajol Chaudhary

Reputation: 267

In Manifest instead of adjustPan use adjustResize

<activity
    android:name=".screen.workshiftscreen.WorkShiftActivity"
    android:launchMode="singleTop"
    android:windowSoftInputMode="adjustResize"
    android:screenOrientation="portrait" />

Upvotes: 1

Related Questions