Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recyclerview scrolls down when soft keyboard appears or disappears

The issue is that the recyclerview scrolls down almost a complete row when the soft keyboard appears or disappears.

Here is a visual example:

enter image description here

The layout for the activity uses a MessageInput and MessageList object from the ChatKit UI library and is as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="apps.cal.calchat.ChatActivity.ChatView">

    <TextView
        android:id="@+id/chatIsTypingTextView"
        android:layout_width="match_parent"
        android:layout_marginLeft="8dp"
        android:layout_height="wrap_content"
        android:layout_above="@+id/chatMessageInput"/>

    <com.stfalcon.chatkit.messages.MessageInput
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:id="@+id/chatMessageInput"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />

    <com.stfalcon.chatkit.messages.MessagesList
        android:id="@+id/chatMessagesList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_above="@+id/chatIsTypingTextView"
        />

</RelativeLayout>

The activity also has adjustPan set in the manifest:

    <activity
        android:name=".ChatActivity.ChatView"
        android:windowSoftInputMode="adjustPan|stateHidden"/>

The Recyclerviews linear layout manager is set as vertical, with a reverse layout and with the default item animator:

public <MESSAGE extends IMessage>
    void setAdapter(MessagesListAdapter<MESSAGE> adapter, boolean reverseLayout) {
        SimpleItemAnimator itemAnimator = new DefaultItemAnimator();
        itemAnimator.setSupportsChangeAnimations(false);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(),
                LinearLayoutManager.VERTICAL, reverseLayout);

        setItemAnimator(itemAnimator);
        setLayoutManager(layoutManager);
        adapter.setLayoutManager(layoutManager);
        adapter.setStyle(messagesListStyle);

        addOnScrollListener(new RecyclerScrollMoreListener(layoutManager, adapter));
        super.setAdapter(adapter);
    }

I ideally do not want to set up a keyboard listener and programatically scroll to the bottom every time the keyboard is shown/hidden. It seems that I must be doing something wrong somewhere. Any ideas?

like image 905
Calco Avatar asked Oct 25 '17 16:10

Calco


1 Answers

When implementing the android ui chat, I spent a long time looking for a solution to the problem with scrolling messages when the keyboard opens. Basically, the decisions were based on scrolling through the recycler to the height of the keyboard and it looked like a crutch.

As it turned out, you need only few things
1. Do not use layoutManager.stackFromEnd = true
2. Do not use ConstraintLayout with high 0dp as a recycler parent
2. Do not use RelativeLayout with wrap_content height as a recycler parent

Setting example:

        val adapter = MessagesAdapter ()
        val layoutManager = LinearLayoutManager (this, RecyclerView.VERTICAL, true)
        rvMessages.layoutManager = layoutManager
        rvMessages.adapter = adapter

For layout you can use LinearLayout, RelativeLayout or ConstraintLayout with match_parent height and padding from bottom to editText height.

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

    <androidx.recyclerview.widget.RecyclerView
        android: id = "@ + id / rvMessages"
        android: layout_width = "match_parent"
        android: layout_height = "0dp"
        android: layout_weight = "1" />

    <EditText
        android: id = "@ + id / etMessage"
        android: layout_width = "match_parent"
        android: layout_height = "wrap_content" />

</LinearLayout>
like image 75
Zakhar Rodionov Avatar answered Oct 20 '22 20:10

Zakhar Rodionov