Over the month, we have been developing Buddy Chat for Android with custom features chatroom. Based on our experience, Qiscus SDK supports to develop sending payload messages. You can make your custom payload based on which of your data to include in your custom bubble chat room. For example, user interface of bubble survey in LINE Chat Application.
First, we have to analyze widgets requirement from the picture to implement in file item_message.xml. Furthermore, you can use ConstraintLayout to build responsive UI. However, other people say build with relative layout is better.
Table of Contents
1. Custom Bubble Item
This is example using relative layout:
<?xml version="1.0" encoding="utf-8"?>l <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginBottom="8dp" android:layout_marginTop="4dp" android:textColor="@color/qiscus_secondary_text" android:textSize="14sp" android:visibility="gone"/> <com.qiscus.sdk.ui.view.QiscusCircularImageView android:id="@+id/avatar" android:layout_width="38dp" android:layout_height="38dp" android:layout_alignTop="@+id/message" android:layout_marginLeft="8dp" android:layout_marginStart="8dp"/> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignEnd="@+id/message" android:layout_alignLeft="@+id/bubble" android:layout_alignRight="@+id/message" android:layout_alignStart="@+id/bubble" android:layout_below="@+id/date" android:layout_marginEnd="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginStart="4dp" android:layout_marginTop="4dp" android:ellipsize="end" android:maxLines="1" android:textColor="@color/qiscus_secondary_text" android:textSize="12sp" android:visibility="gone"/> <ImageView android:id="@+id/bubble" android:layout_width="42dp" android:layout_height="27dp" android:layout_alignTop="@+id/message" android:layout_marginLeft="42dp" android:layout_marginStart="42dp" android:src="@drawable/ic_qiscus_arrow_bubble_primary" android:tint="@color/qiscus_left_bubble"/> <LinearLayout android:id="@+id/message" android:layout_width="236dp" android:layout_height="wrap_content" android:layout_below="@+id/name" android:layout_marginBottom="4dp" android:layout_marginLeft="54dp" android:layout_marginRight="32dp" android:layout_marginStart="54dp" android:background="@drawable/qiscus_rounded_primary_chat_bg" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:layout_centerVertical="true" android:layout_margin="10dp" android:background="@drawable/qiscus_rounded_dark_white"> <ImageView android:id="@+id/ic_image" android:layout_width="48dp" android:layout_height="48dp" android:layout_centerInParent="true" android:layout_centerVertical="true" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:padding="8dp" android:tint="@color/qiscus_divider"/> </RelativeLayout> <TextView android:id="@+id/name_survey" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="13dp" android:layout_toRightOf="@+id/image" android:autoLink="web" android:linksClickable="true" android:text="LINE @ Selles Survey" android:textColor="@color/qiscus_primary_text" android:textColorLink="@color/qiscus_primary_text" android:textSize="16sp" android:textStyle="bold"/> <TextView android:id="@+id/date_survey" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/name_survey" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:layout_toRightOf="@+id/image" android:autoLink="web" android:linksClickable="true" android:text="2017-09-29" android:textColor="@color/qiscus_secondary_text" android:textColorLink="@color/qiscus_primary_text" android:textSize="14sp"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <View android:id="@+id/line" android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/qiscus_white"/> <TextView android:id="@+id/view_now" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/line" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:autoLink="web" android:linksClickable="true" android:paddingBottom="10dp" android:text="View Now" android:textColor="@color/qiscus_secondary_text" android:textColorLink="@color/qiscus_primary_text" android:textSize="14sp"/> </RelativeLayout> </LinearLayout> <TextView android:layout_marginTop="100dp" android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginStart="8dp" android:text="12.36 AM" android:layout_toRightOf="@+id/message" android:textColor="@color/qiscus_secondary_text" android:textSize="12sp"/> <!-- Add this view because Xiaomi need it --> <View android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@+id/message"/> </RelativeLayout>
https://gist.github.com/fauzisho/43178d6c6327d4139f6ce60b79d74693#file-item_messege_survey-xml
This is illustrated of this layout:

2. Chat Room Architecture Components
Second, we make Activity, Fragment, Adapter, and ViewHolder classes extend with class including in Qiscus SDK. After we extend Qiscus base to our custom classes, we can override methods in Qiscus Base.
For instance, in BubbleChatActivity.java we can override getResourceLayout() to implement custom main layout. You can add new toolbar with cool widgets like CircleImageView, Textview for name and new status, new feature include in Chatroom Activity.
@Override protected int getResourceLayout() { return R.layout.activity_sticker_chat; }
Next, in BubbleChatFragment.java we can custom bottom bar, not only edittext message, but also the size of list chat, new feature import image from the gallery until custom payload like sendSurvey() method.
private void sendSurvey() { String message = "Survey Qiscus"; JSONObject payload = new JSONObject(); try { payload.put("sticker_url", "https://res.cloudinary.com/qiscus/image/upload/fxwzBRPcdz/Bubble-Pup-Yup.gif"); payload.put("profile_url", "http://res.cloudinary.com/diufvqwbr/image/upload/v1507608923/logo_gb4lzy.png"); payload.put("title_survey", "Qiscus@ Selles Survey"); payload.put("date", "2017-10-29"); payload.put("link_url", "https://www.qiscus.com/"); } catch (JSONException e) { e.printStackTrace(); } QiscusComment comment = QiscusComment.generateCustomMessage(message, "survey", payload, qiscusChatRoom.getId(), qiscusChatRoom.getLastTopicId()); sendQiscusComment(comment); }
Next, we can analyze this method, we found a payload (JSONObject) initialization with dummy data object. Before sending to sendQiscusComment () method, we have to generate custom message with the parameter provided in QiscusComment.generateCustomMessage().
In adapter class, we have three methods to set an item bubble chat. We can set different layout form others with getIntemResourceLayout(), including set widgets item in QiscusBaseMessegeViewHolder().
@Override protected int getItemViewTypeCustomMessage(QiscusComment qiscusComment, int position) { try { JSONObject payload = new JSONObject(qiscusComment.getExtraPayload()); if (payload.optString("type").equals("survey")) { return qiscusComment.getSenderEmail().equals(qiscusAccount.getEmail()) ? TYPE_SURVEY : TYPE_SURVEY_OTHERS; } } catch (JSONException ignored) { } return super.getItemViewTypeCustomMessage(qiscusComment, position); } @Override protected int getItemResourceLayout(int viewType) { switch (viewType) { case TYPE_SURVEY: return R.layout.item_message_survey; case TYPE_SURVEY_OTHERS: return R.layout.item_message_survey; default: return super.getItemResourceLayout(viewType); } } @Override public QiscusBaseMessageViewHolder<QiscusComment> onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_SURVEY: case TYPE_SURVEY_OTHERS: return new BubbleMessageViewHolder(getView(parent, viewType), itemClickListener, longItemClickListener,context); default: return super.onCreateViewHolder(parent, viewType); } }
Look here:
https://gist.github.com/fauzisho/4fd7e7cbaa34fa7cfeb21289e2b63974#file-adapter_method-java
Also read: Qiscus Web SDK Version 2.6.0 is Now Live. Here’s What’s New!
Run, run, run!
Repository
Here you have the code that we developed in this part:
https://github.com/fauzisho/Bubble-Chat
Conclusion
As you can see, it’s really easy to custom UI bubble chat with Qiscus SDK.
If you find something to improve or any suggestion, don’t hesitate to contact us, we will try to do our best to answer any question or improve this tutorial.