Android Studio kotlin chat screen layout - android

I am trying to build a chat layout. Everything is working fine. When users match each other, they can write messages and the messages appear in the chat screen. However, there is this giant gap in between my chat bubbles.
I read the official Android Chat Bubble documentation, went through YouTube videos and stack overflow. I don't really see where I am going wrong here. My bubbles appear in real time, I can read users chats when testing with two virtual android devices, however the chats have a giant gap in between them and are not on top of each other.
<?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"
tools:context=".activities.ChatActivity">
<LinearLayout
android:id="#+id/navigationLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/navigation_height"
android:layout_margin="#dimen/chat_margin"
android:background="#color/shadow"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/topPhotoIV"
android:layout_width="#dimen/navigation_height"
android:layout_height="#dimen/navigation_height"
android:layout_marginRight="#dimen/chat_margin"
android:scaleType="centerInside"/>
<TextView
android:id="#+id/topNameTV"
android:layout_width="match_parent"
android:layout_height="#dimen/navigation_height"
android:gravity="center_vertical"
android:textSize="20sp"
android:paddingLeft="#dimen/chat_margin"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/messagesRV"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/messageET"
app:layout_constraintTop_toBottomOf="#+id/navigationLayout" />
<Button
android:id="#+id/sendButton"
style="#style/sendButton"
android:layout_width="#dimen/send_width"
android:layout_height="#dimen/send_height"
android:layout_margin="#dimen/chat_margin"
android:onClick="onSend"
android:text="#string/send_button_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<EditText
android:id="#+id/messageET"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxHeight="#dimen/send_height_max"
android:layout_margin="#dimen/chat_margin"
android:padding="#dimen/chat_margin"
android:gravity="center_vertical"
android:background="#drawable/chat_box_bg_rounded"
android:hint="#string/hint_message"
android:minHeight="#dimen/send_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/sendButton"
app:layout_constraintStart_toStartOf="parent" />
chat screen
chatxml
currentUserMessage
otherUserMessage
I ended up changing the recycler view to wrap_content and it is still having a gap. I think I am missing somethinghere?
StillAGap
So I went into the item_current_user_message.xml and the item_other_user_message.xml and switched match_parent to wrap_content and voila, it works. :) Thank you!
FIXEDchatBubbles

This issue is because of the match_parent heigh to the layout of the chat adapter. Make sure the adapter's layout should have height as wrap_content. Setting height to wrap_content will resolve the issue.

Related

Android wrap_content not working on recyclerview

I have a very simple RecyclerView that loads data from a Firestore database. There are no issues with the code to get the data but the RecyclerView does not show anything when I set the view holder to wrap_content. However it does load the data when I set it to match_parent. I have tried using
firestoreRecycler.setHasFixedSize(true)
but it doesnt do anything, the data is just not shown at all when I use wrap_content and using match_parent makes it so that i have to scroll a lot to see a single item.
Here is the code for the RecyclerView row 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:padding="15dp">
<TextView
android:id="#+id/listOfficeName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/listOfficeAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/listOfficeName" />
</androidx.constraintlayout.widget.ConstraintLayout>
There is nothing relevant about the rest, there is functionality only for the RecyclerView that I got from a tutorial in which wrap_content actually worked.
Thanks in advance!
The distance of the recyclerview used in ConstraintLayout as a view is disabled because it does not fit the logic of ConstraintLayout. So edit the height value of recyclerview as follows:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp" />
height = 0dp

Images flowing out of a tablet layout inside a constraint layout

I'm facing troubles with a TableLayout here. My goal would be to make two columns with equal width, each one with one image that should adjust it's width so it fits inside the cell's available space, but it seems the images keep overflowing outside the available space in the cell/row. I have tested some properties without luck so far, so I could use some help here.
This is the current outcome in the design view:
I'd have expected the teddy bear to occupy only 50% of the row width at the left, and then the other image (which is an umbrella) to fit into the remaining 50% at the right of the bear. But you see that's not what's happening.
This is the layout code:
<?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:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.DebugFragment">
<TableLayout
android:id="#+id/tableImages"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:stretchColumns="*"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TableRow
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
app:srcCompat="#drawable/teddy_bear" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
tools:srcCompat="#drawable/umbrella" />
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
UPDATE: Following Jakob F advice of replacing stretchColumns with shrinkColumns solves the issue with the image overflowing the layout boundaries, but breaks the requirement of both columns being of same width. See image:
UPDATE: Keeping the stretchColumns="*" and setting the layout_width of each image to 0dp does the trick of keeping them inside the layout boundaries AND make both columns the same with. Now I just have to figure out how to keep them at the same height, but that's a different issue I think.
UPDATE: Adding android:scaleType="fitStart" to both images aligns both of them to the top as desired, but it keeps adding space under the images for no reason (I have changed the background color so the limits of the images are more obvious).
You need to use android:shrinkColumns="*" instead of android:strechColumns="*" to make all columns shrinkable, so that the width is automatically determined to fit the images on screen. Stretching them would only enable them to become larger.
OK, I managed to solve all the issues by myself. Can't help but complain on how difficult such an obvious task can become sometimes in Android. I had to go over a lot of trial and error with a number of different attributes which functionality seem anything but obvious in most cases. Anyway, this is the solution:
<?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:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99ffff"
tools:context=".view.DebugFragment">
<TableLayout
android:id="#+id/tableImages"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:stretchColumns="*"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="16dp"
app:srcCompat="#drawable/teddy_bear" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="16dp"
app:srcCompat="#drawable/umbrella" />
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
The result:

Android Activity Layout-Problem on only 1 of 15 test-devices (ImageView)

I'm testing a new activity in our Android app. On all but one devices, everything was fine - except for a Huawei P30 Pro.
The activity is quite simple: it shows an ImageView and a small menu-bar on the bottom. Before the image is set, a ProgressBar (spinning circle) gets shown.
On the Huawei P30 Pro, everything seems to work fine (the ProgressBar appears, the circle is spinning, the ProgressBar disappears), but no Image becomes visible. If you forward the image by pressing the Apply-button in the menuBar, the image gets correctly forwarded, so it actually is available, it just doesn't get shown within the activity.
We tested the same version of the app on several other devices (including Huawei P10, P20, several Samsung-phones and HTC) and everything was ok. But on both Huawei P30 Pro we had available, the same problem appeared.
The layout-code is pretty straightforward:
<LinearLayout 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="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_weight="10">
<LinearLayout
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="9"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:srcCompat="#tools:sample/avatars"
android:contentDescription="Image preview"/>
<ProgressBar
android:id="#+id/indeterminateBar"
android:indeterminate="true"
android:minWidth="100dp"
android:minHeight="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</LinearLayout
android:layout_height="0dp">
<LinearLayout
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="1">
<!-- bottom menu-bar-code is here as a TableLayout, which works fine on all devices -->
</LinearLayout>
</LinearLayout>
Maybe the ImageView has a height of 0 so it isn't visible?
I'm puzzled about what it could be, since it's only that particular device...
I checked if the ImageView-drawable does properly get set (imageView.getDrawable() != null) and it looks like it does (it is not null), as well as the visibility-state, which also seems to be fine.
So at this point, I think it is a pure layout-problem.
I highly recommend to switch from LinearLayout to ConstraintLayout. Even though your current layout works on 14 of 15 devices, the height of the bottom menu is always 10% and this will not look good on devices with small heights (have you ever tried your layout in landscape? You will see what I mean).
Once switched to ConstraintLayout, your layout issue on the 15th device should also disappear.
I transformed your layout to use ConstraintLayout to show how it could look like. It also has less layouts inside.
<?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">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:contentDescription="Image preview"
app:layout_constraintBottom_toTopOf="#id/bottomMenuBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<ProgressBar
android:id="#+id/indeterminateBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:minWidth="100dp"
android:minHeight="100dp"
app:layout_constraintBottom_toTopOf="#+id/bottomMenuBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/bottomMenuBar"
android:layout_width="fill_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<!-- bottom menu-bar-code is here as a TableLayout, which works fine on all devices -->
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Please be aware that for visibility reasons in the layout preview I have added a fixed height for the LinearLayout of the bottom menu. Once you have understood the ConstraintLayout you should also change it for the menu bar. I kept it as a LinearLayout for easier usage with your real layout code.

How can I make a recyclerView to take up to half the screen(max) in android constraint layout?

I have a screen that contains 2 views, a map(top) and a recycler(bottom)
The rules are simple .
the recycler view is allowed to extend up to the middle of the screen, if more space is needed then it should scroll instead, the map will occupy the rest of the space, Of course if the recycler has less elements then it should shrink leaving more space for the map ..
I am trying to achieve this using constraint layout, also I am trying to avoid solutions that involved calculations .
Check image below for more information on what I am trying to achieve :
Here is my code
<?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="#color/white"
tools:context="com.qmic.itraffic.ui.activities.crowdsourcing.CrowdSourceReportingDetailsActivity">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/halfScreenGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/categories"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#color/manatee"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/categories"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/halfScreenGuideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
My Question is can I achieve this behaviour using xml only (constraint layout )?or I would need to do calculation ?
Could you please try the following code in your recyclerview xml
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
Change the height to wrap content and add the second the line. This way the recyclerview should have the height same as its content but never exceeds the guideline/contraint.
The answer by Akhil Soman is correct but missing one thing
app:layout_constraintVertical_bias="1.0"
Without it the RecyclerView was floating above the bottom of the screen leaving an empty space .
for reference here is the complete answer
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/categories"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:clipToPadding="false"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/halfScreenGuideline"
app:layout_constraintVertical_bias="1.0" />
Also the suggestion by the Jaymin seems interesting and can fix this problem, but I haven't applied it because I already used Akil solution .

Layout content overlap in Oreo

I've two child layouts in ConstraintLayout (One above the other). It's showing second layout above first in all Android versions except Android 8.1 (Android O),where the second layout is hidden behind the first layout.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout android:id="#+id/subscriberViewContainer"
android:layout_marginBottom="50dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#color/colorAccent"/>
<RelativeLayout
android:id="#+id/publisherViewContainer"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="120dp"
android:layout_height="90dp"
android:elevation="20dp"
android:background="#color/colorPrimary"/>
</android.support.constraint.ConstraintLayout>
Are there any changes that need to be done in Android O to get the same response as the rest?
I found the last layout to which i'm adding view is coming on top, which is very odd. So i put a temporary fix , if the build version > 25 then add view to second layout again .It's very weird but at the end of the day , i had to fix it.

Categories

Resources