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
But when there are more items the screen look like this
Image 2
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
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>
CodePudding user response:
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.
CodePudding user response:
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>




