AnthonyR
AnthonyR

Reputation: 3545

ChatKit library : incoming image wrong margins

I'm using ChatKit library (https://github.com/stfalcon-studio/ChatKit/) for a chat feature in my app. In the message list provided by the library, I also included images messages.

It works fine, but the bubble's layout of the images is ambiguous, as the following picture :

enter image description here

Bubble picture 1 and 3 should be aligned on the right side, but they are stick on the left in the available space for incoming messages.

Note that the default text messages bubbles are displayed correctly on the right.

I didn't find any attributes for the layout in the library to configure this behaviour.

This is my XML for the message list :

    <android.support.v4.widget.SwipeRefreshLayout

        android:id="@+id/swipe_refresh_comments"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.stfalcon.chatkit.messages.MessagesList
            android:id="@+id/messagesList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/input_comment"
            app:incomingDefaultBubbleColor="@color/lightGrayRetail"
            app:incomingTimeTextColor="@color/white"
            app:incomingDefaultBubblePressedColor="@color/lightGrayRetail"
            app:incomingDefaultImageOverlayPressedColor="@color/lightGrayRetail"
            app:outcomingDefaultBubblePressedColor="@color/pinkRetail"
            app:outcomingDefaultImageOverlayPressedColor="@color/pinkRetail"
            app:outcomingDefaultBubbleColor="@color/pinkRetail"
            app:outcomingTimeTextColor="@color/colorMaterialGray" />

    </android.support.v4.widget.SwipeRefreshLayout>

My incoming text message layout layout :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginTop="8dp">

    <TextView
        android:id="@+id/displayNameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/bubble"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="8dp"
        android:textColor="@color/colorMaterialGray"/>

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@id/messageUserAvatar"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginEnd="8dp"
        android:src="@drawable/woman" />

    <ImageView
        android:id="@+id/onlineIndicator"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_alignEnd="@id/messageUserAvatar"
        android:layout_alignTop="@id/messageUserAvatar"
        android:layout_marginEnd="5dp" />

    <LinearLayout
        android:id="@id/bubble"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="30dp"
        android:layout_below="@+id/displayNameTextView"
        android:layout_toEndOf="@id/messageUserAvatar"
        android:orientation="vertical">

        <TextView
            android:id="@id/messageText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="4dp"
            android:layout_marginStart="8dp"/>

    </LinearLayout>

    <TextView
        android:id="@+id/incomingTimeTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@id/bubble"
        android:layout_below="@id/bubble"
        android:layout_marginEnd="4dp"
        android:text="18:00"
        android:layout_marginTop="4dp"
        android:textColor="@color/colorMaterialGray" />

</RelativeLayout>

Outcoming layout :

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginTop="8dp">

    <LinearLayout
        android:id="@id/bubble"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="40dp"
        android:orientation="vertical">

        <TextView
            android:id="@id/messageText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <TextView
        android:id="@+id/outcomingTimeTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@id/bubble"
        android:layout_below="@id/bubble"
        android:textColor="@color/colorMaterialGray"
        android:layout_marginStart="16dp"/>

</RelativeLayout>

MessageHolder of outcoming :

public class CustomOutcomingMessageViewHolder extends MessageHolders.OutcomingTextMessageViewHolder<Comment> {

    private TextView mOutcomingTimeTextView;

    public CustomOutcomingMessageViewHolder(View itemView) {
        super(itemView);
        mOutcomingTimeTextView = itemView.findViewById(R.id.outcomingTimeTextView);
    }

    @Override
    public void onBind(Comment comment) {
        super.onBind(comment);
        if(comment.getmContent() != null){
            if(comment.getmContent().length() > 3){
                SimpleDateFormat timeOutput = new SimpleDateFormat("HH:mm", Locale.FRANCE);
                String commentPostedTime = timeOutput.format(comment.getmPostedDate());
                mOutcomingTimeTextView.setText(commentPostedTime);
            }
        }
    }
}

Any ideas ?

Upvotes: 2

Views: 947

Answers (4)

humazed
humazed

Reputation: 76902

Fixed it by setting a fixed width using ConstraintLayout

val holdersConfig = MessageHolders()
    .setIncomingTextConfig(
        CustomIncomingTextMessageViewHolder::class.java,
        R.layout.item_custom_incoming_text_message
    )

Here is my item_custom_outcoming_image_message

<?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/imageMessageContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="16dp"
    android:layout_marginTop="8dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    tools:context=".chatting.ChattingFragment">

    <com.stfalcon.chatkit.utils.RoundedImageView
        android:id="@id/image"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_chat_pick_image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".8"
        tools:srcCompat="@tools:sample/backgrounds/scenic" />

    <View
        android:id="@id/imageOverlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@id/image"
        app:layout_constraintEnd_toEndOf="@id/image"
        app:layout_constraintStart_toStartOf="@id/image"
        app:layout_constraintTop_toTopOf="@id/image"
        tools:visibility="gone" />

    <ImageView
        android:id="@+id/status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingStart="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/image"
        tools:src="@drawable/ic_message_status_processing" />

    <TextView
        android:id="@id/messageTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@id/status"
        app:layout_constraintEnd_toStartOf="@+id/status"
        app:layout_constraintTop_toTopOf="@id/status"
        tools:text="12:15" />

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 0

Mason Ashment
Mason Ashment

Reputation: 1

For anyone using the default MessagesListAdapter and ViewHolders, outgoing picture message ImageViews don't have their alignment set, but their parent view width is set to match_parent, which is why the image isn't aligned correctly.

item_outcoming_image_message.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginTop="8dp">

    <com.stfalcon.chatkit.utils.RoundedImageView
        android:id="@id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:layout_marginLeft="@dimen/message_outcoming_bubble_margin_left"
        android:layout_marginStart="@dimen/message_outcoming_bubble_margin_left" />

So, after looking through some of the library code, I found one solution is to simply override onBindViewHolder():

messagesAdapter = new MessagesListAdapter<Message>(senderId, imageLoader) {
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        if (holder.getItemViewType() == -132) { // -132 is an outgoing picture message
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.itemView.findViewById(com.stfalcon.chatkit.R.id.image).getLayoutParams();
            params.addRule(RelativeLayout.ALIGN_PARENT_END);
        }
    }
};

Upvotes: 0

TinaTT2
TinaTT2

Reputation: 489

Did you check the sender ids in your code to be different for sender and receiver side by the id which is gotten from getId of message model? According to the library you need to determine the senderId in the Adapter initialization:

MessagesListAdapter<Message> adapter = new MessagesListAdapter<>(senderId, 
imageLoader);
messagesList.setAdapter(adapter);

Library decides whether to align left or right according to senderIds comparison.

Upvotes: 0

Tincho825
Tincho825

Reputation: 929

This happened to me without using any MessageHolder, I could fix it by assigning the same width to all images:

int width = Math.round( (float) getScreenWidthHeight().x * 0.8f); // width = 80% of screen's max width
int height = Math.round((float) bitmap.getHeight() / ((float) bitmap.getWidth() / (float) width));
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap), width, height, true);

where getScreenWidthHeight() is:

private Point getScreenWidthHeight(Activity activity) {
    Display display = activity.getWindowManager(). getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    return size;
}

Upvotes: 1

Related Questions