2

I am creating a chat application. I used stackFromEnd = false and reverseLayout = true to show items from the bottom of screen. In which I used reyclerview and it's working fine, and I am adding the code below with a screenshot. How it looks likes

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccccc">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0" />

</androidx.constraintlayout.widget.ConstraintLayout>

The above code is working fine when there is a single item in recyclerView it opens a screen like this

Image 1

Example1

But when there are more items the screen look like this

Image 2

enter image description here

Note: This above image is my expected output. Also soft keyboard shift the layout.

Now the main story starts, I want to add editText at bottom of the screen.

<?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="#cccccc">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toTopOf="@+id/inputContainer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/inputContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:paddingStart="10dp"
        android:paddingTop="14dp"
        android:visibility="gone"
        android:paddingEnd="10dp"
        android:paddingBottom="14dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/conversationRecyclerView"
        app:layout_constraintVertical_bias="1.0">

        <EditText
            android:id="@+id/edittext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="textMultiLine|text|textNoSuggestions"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Problem 1

Image 1 is not getting the correct constraint and it looks like this

enter image description here

and image 2 is working fine and the soft keyboard shifts the layout.

problem 2

I tried some code to solve problem 1 and the soft keyboard is not shifting the layout

<?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="#cccccc">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@+id/inputContainer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/inputContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:paddingStart="10dp"
        android:paddingTop="14dp"
        android:paddingEnd="10dp"
        android:paddingBottom="14dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintVertical_bias="1.0">

        <EditText
            android:id="@+id/sendMessageEditText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

UPDATE

After @Cheticamp suggestion, I added this but not working. It has still a problem 1 issue. It's not resolving.

<?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="#cccccc">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@+id/inputContainer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/inputContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:paddingStart="10dp"
        android:paddingTop="14dp"
        android:paddingEnd="10dp"
        android:paddingBottom="14dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
      >

        <EditText
            android:id="@+id/sendMessageEditText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

UPDATE 1

After @Tenfour04 suggestions, I added some code please have a look. Am I am doing correctly?

<?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="#cccccc">

    <FrameLayout
        android:id="@+id/conversationRecyclerViewViewWrapper"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/inputContainer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/conversationRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingStart="10dp"
            android:paddingEnd="10dp"
            android:paddingBottom="10dp"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    </FrameLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/inputContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:paddingStart="10dp"
        android:paddingTop="14dp"
        android:paddingEnd="10dp"
        android:paddingBottom="14dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/conversationRecyclerView">

        <EditText
            android:id="@+id/sendMessageEditText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:inputType="textMultiLine|text|textNoSuggestions"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127

2 Answers2

1

For problem #1, make the height and the width of the RecyclerView 0dp and let the constraints size it to fill the screen. Also, remove the vertical bias - you don't need it.

btw, never use match_parent in a ConstraintLayout. Always use 0dp and the constraints.

That may solve all your issues with this layout.

Update: I should have scrolled down in your layout.

I take it that you want the RecyclerView to fill the screen except for the EditText on the bottom. In general, nesting layout within a ConstraintLayout is not needed and is considered by many poor design.

Make the changes I suggest above, remove the inner ConstraintLayout and place the two views into a vertical chain like this:

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccccc">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@+id/sendMessageEditText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/sendMessageEditText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="This is the EditText"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/conversationRecyclerView" />

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
1

The problem is your RecyclerView's height is wrap_content instead of 0dp (a.k.a. "match_constraints"), so it ignores the constraint that it should be above inputContainer.

So instead of making it wrap_content and using vertical bias to try to keep it at the top of the screen, try wrapping it in a FrameLayout and giving it layout gravity of "top". The FrameLayout should use 0dp for height so it can fill the entire space, but not overlap inputContainer. The RecyclerView can use wrap_content for height, and the layout gravity will bias it to the top of the FrameLayout's space. So replace your RecyclerView element with this:

<FrameLayout
    android:id="@+id/recyclerViewWrapper"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@+id/inputContainer"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/conversationRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:paddingBottom="10dp"
        app:layoutManager="LinearLayoutManager"
        app:reverseLayout="true"/>
</FrameLayout>

The app:layout_constraintVertical_bias is meaningless on inputContainer because it has no top constraint, so you can remove that.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • thanks once again for helping me. I am trying your code. One question do i need to give `app:layout_constraintTop_toBottomOf="@+id/conversationRecyclerView"`in `inputContainer` ? – Kotlin Learner Nov 10 '21 at 22:07
  • I am adding code in **UPDATE 1** please have a look. Thanks a million. – Kotlin Learner Nov 10 '21 at 22:20
  • It doesn't make sense and I don't think it's supported to constrain the `inputContainer` top to a View that isn't a direct child of the ConstraintLayout. If I understand correctly, you just want the `inputContainer` to be biased to the bottom of the screen, so you don't need to constrain its top. It's redundant anyway because the bottom of the FrameLayout is already constrained to the top of the `inputContainer`. – Tenfour04 Nov 10 '21 at 22:46
  • Thanks @Tenfour04 for you solution. – Kotlin Learner Nov 24 '21 at 11:53
  • can you please look on this [issue](https://stackoverflow.com/q/70095578/11560810) – Kotlin Learner Nov 24 '21 at 11:53