mitter.io
Search…
Custom Payloads
Learn how to add actions & extra information to your messages and build a playful and engaging chat experience.
In the previous chapter, we learnt how to send messages to specific people in a group chat with ACLs.
In this chapter, we’ll see how to take the demo app one step further by adding some custom payloads to our outgoing messages.

Schedule meetings on chat

To demonstrate the power and use of custom payloads, we’ll be letting our users schedule meetings on our app. The basic workflow is as follows:
  • Pick a date while sending a message
  • Receivers confirm their availability with a Yes/No action

Add the DatePickerDialog

We’ll use the standard DatePickerDialog to render a calendar dialog on the screen and allow the user to pick a date from the displayed calendar.
Get started by adding a button to the chat screen. For this example, you can use this vector drawable as the calendar button. Just copy this code to your project under the drawable package:
Now, navigate to your activity_main.xml and modify the code to look similar to this:
activity_main.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:app="http://schemas.android.com/apk/res-auto"
4
xmlns:tools="http://schemas.android.com/tools"
5
android:layout_width="match_parent"
6
android:layout_height="match_parent"
7
android:background="@android:color/white"
8
tools:context=".MainActivity">
9
10
<android.support.v7.widget.RecyclerView
11
android:id="@+id/chatRecyclerView"
12
android:layout_width="0dp"
13
android:layout_height="0dp"
14
android:layout_marginBottom="10dp"
15
app:layout_constraintBottom_toBottomOf="parent"
16
app:layout_constraintBottom_toTopOf="@id/inputMessage"
17
app:layout_constraintEnd_toEndOf="parent"
18
app:layout_constraintStart_toStartOf="parent"
19
app:layout_constraintTop_toTopOf="parent" />
20
21
<View
22
android:id="@+id/divider"
23
android:layout_width="match_parent"
24
android:layout_height="1dp"
25
android:background="@color/colorGray"
26
app:layout_constraintTop_toBottomOf="@id/chatRecyclerView" />
27
28
<Button
29
android:id="@+id/sendButton"
30
style="@style/Base.Widget.AppCompat.Button.Borderless"
31
android:layout_width="wrap_content"
32
android:layout_height="wrap_content"
33
android:layout_marginBottom="5dp"
34
android:text="Send"
35
app:layout_constraintBottom_toBottomOf="parent"
36
app:layout_constraintEnd_toEndOf="parent" />
37
38
<ImageView
39
android:id="@+id/pickDateButton"
40
android:layout_width="wrap_content"
41
android:layout_height="wrap_content"
42
android:src="@drawable/ic_date_range_black_24dp"
43
app:layout_constraintBottom_toBottomOf="parent"
44
app:layout_constraintEnd_toStartOf="@id/sendButton"
45
app:layout_constraintTop_toBottomOf="@id/divider" />
46
47
<android.support.v7.widget.AppCompatEditText
48
android:id="@+id/inputMessage"
49
android:layout_width="0dp"
50
android:layout_height="40dp"
51
android:layout_marginBottom="10dp"
52
android:layout_marginEnd="10dp"
53
android:layout_marginStart="20dp"
54
android:background="@android:color/white"
55
android:hint="Type your message"
56
android:inputType="textCapSentences"
57
android:textSize="16sp"
58
app:layout_constraintBottom_toBottomOf="parent"
59
app:layout_constraintEnd_toStartOf="@id/pickDateButton"
60
app:layout_constraintStart_toStartOf="parent" />
61
62
</android.support.constraint.ConstraintLayout>
Copied!
If you compare this file to your previously created layout, you’ll see that we’ve just added an ImageView showing up the calendar icon that we added in the previous step and adjusted the surrounding views to accommodate this icon.
Lastly, go to your MainActivity and add the listener for this button to open up the DatePickerDialog and listen for inputs from the user.
Define an instance variable in your MainActivity to hold the picked date:
Kotlin
Java
MainActivity.kt
1
private var pickedDate: String = ""
Copied!
MainActivity.java
1
private String pickedDate = ""
Copied!
Then, add this block of code inside your onCreate() method:
Kotlin
Java
MainActivity.kt
1
pickDateButton?.setOnClickListener {
2
val calendar = Calendar.getInstance()
3
val year = calendar.get(Calendar.YEAR)
4
val month = calendar.get(Calendar.MONTH)
5
val day = calendar.get(Calendar.DAY_OF_MONTH)
6
7
val datePickerDialog = DatePickerDialog(
8
this,
9
{ _, year, month, day ->
10
pickedDate = "$day/${month + 1}/$year"
11
},
12
year,
13
month,
14
day
15
)
16
17
datePickerDialog.show()
18
}
Copied!
MainActivity.java
1
pickDateButton.setOnClickListener(new View.OnClickListener() {
2
@Override
3
public void onClick(View v) {
4
Calendar calendar = Calendar.getInstance();
5
final int year = calendar.get(Calendar.YEAR);
6
final int month = calendar.get(Calendar.MONTH);
7
final int day = calendar.get(Calendar.DAY_OF_MONTH);
8
9
DatePickerDialog datePickerDialog = new DatePickerDialog(
10
MainActivity.this,
11
new DatePickerDialog.OnDateSetListener() {
12
@Override
13
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
14
pickedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
15
}
16
},
17
year,
18
month,
19
day
20
);
21
22
datePickerDialog.show();
23
}
24
});
Copied!
Note: To use the DatePickerDialog you need to have your minSdkVersion set to 24 or above
Choosing a date for the meeting using the built-in date picker dialog

Send a message with the picked date

Now that we’ve added the functionality to capture a date from the user, we can send it along with our message to be used by our RecyclerView to render messages differently.
Get started by adding a new data class (or a POJO, if using Java) to hold the picked date:
Kotlin
Java
PickedDate.kt
1
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
2
data class PickedDate(
3
@JsonProperty("date") val date: String
4
)
Copied!
PickedDate.java
1
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
2
public class PickedDate {
3
@JsonProperty("date")
4
String date;
5
6
public PickedDate() {
7
}
8
9
public PickedDate(String date) {
10
this.date = date;
11
}
12
13
public String getDate() {
14
return date;
15
}
16
17
public void setDate(String date) {
18
this.date = date;
19
}
20
21
@Override
22
public String toString() {
23
return "PickedDate{" +
24
"date='" + date + '\'' +
25
'}';
26
}
27
}
Copied!
Now, go to MainActivity and inside the sendButton.setOnClickListener {} block (or inside the onClick() method, if using Java) , modify your code to this:
Kotlin
Java
MainActivity.kt
1
if (pickedDate.isEmpty()) {
2
messaging.sendTextMessage(
3
channelId = channelId,
4
message = typedInput,
5
appliedAcls = appliedAcls,
6
onValueUpdatedCallback = object : Mitter.OnValueUpdatedCallback {
7
override fun onError(apiError: ApiError) {}
8
9
override fun onSuccess() {
10
inputMessage?.text?.clear()
11
}
12
}
13
)
14
} else {
15
val objectMapper = ObjectMapper()
16
val sender = IdUtils.of<User>(mitter.getUserId())
17
18
val pickedDate = PickedDate(this.pickedDate)
19
20
val timelineEvent = TimelineEvent(
21
eventId = UUID.randomUUID().toString(),
22
type = StandardTimelineEventTypeNames.Messages.SentTime,
23
eventTimeMs = System.currentTimeMillis(),
24
subject = sender
25
)
26
27
val message = Message(
28
messageId = UUID.randomUUID().toString(),
29
senderId = sender,
30
textPayload = typedInput,
31
timelineEvents = listOf(timelineEvent),
32
appliedAcls = appliedAcls,
33
messageData = listOf(
34
MessageDatum(
35
"io.mitter.android.messages.DateMessage",
36
objectMapper.valueToTree(pickedDate)
37
)
38
)
39
)
40
41
messaging.sendMessage(
42
channelId = channelId,
43
message = message,
44
onValueUpdatedCallback = object : Mitter.OnValueUpdatedCallback {
45
override fun onError(apiError: ApiError) {
46
47
}
48
49
override fun onSuccess() {
50
inputMessage?.text?.clear()
51
this@MainActivity.pickedDate = ""
52
}
53
}
54
)
55
}
Copied!
MainActivity.java
1
if (pickedDate.isEmpty()) {
2
messaging.sendTextMessage(
3
channelId,
4
typedInput,
5
appliedAcls,
6
new Mitter.OnValueUpdatedCallback() {
7
@Override
8
public void onSuccess() {
9
inputMessage.getText().clear();
10
}
11
12
@Override
13
public void onError(ApiError apiError) {
14
}
15
}
16
);
17
} else {
18
ObjectMapper objectMapper = new ObjectMapper();
19
Identifiable<User> sender = IdUtils.of(mitter.getUserId(), User.class);
20
21
PickedDate date = new PickedDate(pickedDate);
22
23
TimelineEvent timelineEvent = new TimelineEvent(
24
UUID.randomUUID().toString(),
25
"",
26
StandardTimelineEventTypeNames.Messages.SentTime,
27
System.currentTimeMillis(),
28
sender,
29
null
30
);
31
32
List<TimelineEvent> timelineEvents = new ArrayList<>();
33
timelineEvents.add(timelineEvent);
34
35
MessageDatum messageDatum = new MessageDatum(
36
"io.mitter.android.messages.DateMessage",
37
objectMapper.valueToTree(date)
38
);
39
40
List<MessageDatum> messageData = new ArrayList<>();
41
messageData.add(messageDatum);
42
43
Message message = new Message(
44
UUID.randomUUID().toString(),
45
"",
46
StandardMessageType.Standard,
47
StandardPayloadTypeNames.TextMessage,
48
sender,
49
typedInput,
50
messageData,
51
timelineEvents,
52
appliedAcls,
53
new EntityMetadata(),
54
null
55
);
56
57
messaging.sendMessage(
58
channelId,
59
message,
60
new Mitter.OnValueUpdatedCallback() {
61
@Override
62
public void onSuccess() {
63
inputMessage.getText().clear();
64
pickedDate = "";
65
}
66
67
@Override
68
public void onError(ApiError apiError) {
69
70
}
71
}
72
);
73
}
Copied!
What we did here is:
  • Wrapped our previous sendTextMessage() method inside an if-else block
  • Wrapped the picked date string inside a PickedDate object ready to be serialised
  • Constructed a SentTime timeline event for our Message object
  • Constructed a Message object with all the previous params and a new MessageDatum list
A MessageDatum is a single unit of your custom payload. It has a unique ID to identify the type of payload you’re sending and also the payload in serialised form.
Now, if you type a message in the input field and tap on the calendar icon you’ll see a date picker pop-up. Select a date and then hit Send.
The app will send out a message with the selected date as its payload.
We’ll make use of this payload in the next section where we’ll show a different chat bubble with this date information.

Show the date message bubbles

To make use of the custom payload that we attached to our message, we need to add some custom layouts for our chat bubbles to accommodate the attached date.
Get started by adding these two layouts to your project:
item_message_date_self.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:app="http://schemas.android.com/apk/res-auto"
4
xmlns:tools="http://schemas.android.com/tools"
5
android:layout_width="match_parent"
6
android:layout_height="wrap_content">
7
8
<android.support.constraint.ConstraintLayout
9
android:id="@+id/messageContainer"
10
android:layout_width="wrap_content"
11
android:layout_height="wrap_content"
12
android:background="@drawable/back_blue_rounded"
13
app:layout_constraintEnd_toEndOf="parent">
14
15
<android.support.v7.widget.AppCompatTextView
16
android:id="@+id/selfDateMessageText"
17
android:layout_width="wrap_content"
18
android:layout_height="wrap_content"
19
android:layout_margin="5dp"
20
android:paddingBottom="5dp"
21
android:paddingEnd="20dp"
22
android:paddingStart="20dp"
23
android:paddingTop="10dp"
24
android:textColor="@android:color/white"
25
android:textSize="16sp"
26
app:layout_constraintStart_toStartOf="parent"
27
app:layout_constraintTop_toTopOf="parent"
28
tools:text="Can we have a meeting?" />
29
30
<android.support.v7.widget.AppCompatTextView
31
android:id="@+id/selfDate"
32
android:layout_width="wrap_content"
33
android:layout_height="wrap_content"
34
android:paddingBottom="15dp"
35
android:paddingEnd="20dp"
36
android:paddingStart="20dp"
37
android:textColor="#eee"
38
android:textSize="12sp"
39
android:textStyle="italic"
40
app:layout_constraintStart_toStartOf="@id/selfDateMessageText"
41
app:layout_constraintTop_toBottomOf="@id/selfDateMessageText"
42
tools:text="On: 26/09/2018" />
43
44
</android.support.constraint.ConstraintLayout>
45
46
</android.support.constraint.ConstraintLayout>
Copied!
item_message_date.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:app="http://schemas.android.com/apk/res-auto"
4
xmlns:tools="http://schemas.android.com/tools"
5
android:layout_width="match_parent"
6
android:layout_height="wrap_content">
7
8
<android.support.constraint.ConstraintLayout
9
android:id="@+id/messageContainer"
10
android:layout_width="wrap_content"
11
android:layout_height="wrap_content"
12
android:background="@drawable/back_gray_rounded">
13
14
<android.support.v7.widget.AppCompatTextView
15
android:id="@+id/dateMessageText"
16
android:layout_width="wrap_content"
17
android:layout_height="wrap_content"
18
android:layout_margin="5dp"
19
android:paddingBottom="5dp"
20
android:paddingEnd="20dp"
21
android:paddingStart="20dp"
22
android:paddingTop="10dp"
23
android:textColor="@android:color/black"
24
android:textSize="16sp"
25
app:layout_constraintStart_toStartOf="parent"
26
app:layout_constraintTop_toTopOf="parent"
27
tools:text="Can we have a meeting?" />
28
29
<android.support.v7.widget.AppCompatTextView
30
android:id="@+id/date"
31
android:layout_width="wrap_content"
32
android:layout_height="wrap_content"
33
android:paddingBottom="15dp"
34
android:paddingEnd="20dp"
35
android:paddingStart="20dp"
36
android:textSize="12sp"
37
android:textStyle="italic"
38
app:layout_constraintStart_toStartOf="@id/dateMessageText"
39
app:layout_constraintTop_toBottomOf="@id/dateMessageText"
40
tools:text="On: 26/09/2018" />
41
42
</android.support.constraint.ConstraintLayout>
43
44
<Button
45
android:id="@+id/yesButton"
46
style="@style/Base.Widget.AppCompat.Button.Borderless"
47
android:layout_width="wrap_content"
48
android:layout_height="wrap_content"
49
android:text="Yes"
50
app:layout_constraintTop_toBottomOf="@id/messageContainer" />
51
52
<Button
53
android:id="@+id/noButton"
54
style="@style/Base.Widget.AppCompat.Button.Borderless"
55
android:layout_width="wrap_content"
56
android:layout_height="wrap_content"
57
android:text="No"
58
app:layout_constraintStart_toEndOf="@id/yesButton"
59
app:layout_constraintTop_toBottomOf="@id/messageContainer" />
60
61
</android.support.constraint.ConstraintLayout>
Copied!
After you’ve added these, the next step is to modify your ChatRecyclerViewAdapter to something like this:
Kotlin
Java
ChatRecyclerViewAdapter.kt
1
class ChatRecyclerViewAdapter(
2
private val messageList: List<Message>,
3
private val currentUserId: String
4
) : RecyclerView.Adapter<ChatRecyclerViewAdapter.ViewHolder>() {
5
private val objectMapper = ObjectMapper()
6
7
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
8
val itemView = LayoutInflater.from(parent.context).inflate(getLayoutId(viewType), parent, false)
9
return ViewHolder(itemView)
10
}
11
12
override fun getItemCount(): Int = messageList.size
13
14
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
15
holder.bindMessage(messageList[position], holder.itemViewType)
16
}
17
18
override fun getItemViewType(position: Int): Int = when (messageList[position].senderId.domainId()) {
19
currentUserId -> {
20
val message = messageList[position]
21
22
if (message.messageData.isEmpty()) {
23
MessageTypes.SELF_PLAIN_MESSAGE
24
} else {
25
MessageTypes.SELF_DATE_MESSAGE
26
}
27
}
28
else -> {
29
val message = messageList[position]
30
31
if (message.messageData.isEmpty()) {
32
MessageTypes.OTHER_PLAIN_MESSAGE
33
} else {
34
MessageTypes.OTHER_DATE_MESSAGE
35
}
36
}
37
}
38
39
object MessageTypes {
40
const val SELF_PLAIN_MESSAGE = 0
41
const val OTHER_PLAIN_MESSAGE = 1
42
const val SELF_DATE_MESSAGE = 2
43
const val OTHER_DATE_MESSAGE = 3
44
}
45
46
private fun getLayoutId(viewType: Int): Int = when (viewType) {
47
MessageTypes.SELF_PLAIN_MESSAGE -> R.layout.item_message_self
48
MessageTypes.SELF_DATE_MESSAGE -> R.layout.item_message_date_self
49
MessageTypes.OTHER_DATE_MESSAGE -> R.layout.item_message_date
50
else -> R.layout.item_message_other
51
}
52
53
inner class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
54
fun bindMessage(message: Message, viewType: Int) {
55
with(message) {
56
when (viewType) {
57
MessageTypes.SELF_PLAIN_MESSAGE -> {
58
itemView?.selfMessageText?.text = textPayload
59
}
60
MessageTypes.OTHER_PLAIN_MESSAGE -> {
61
itemView?.otherMessageText?.text = textPayload
62
}
63
MessageTypes.SELF_DATE_MESSAGE -> {
64
val pickedDate = objectMapper.treeToValue(messageData[0].data, PickedDate::class.java)
65
itemView?.selfDateMessageText?.text = textPayload
66
itemView?.selfDate?.text = "On: ${pickedDate.date}"
67
}
68
MessageTypes.OTHER_DATE_MESSAGE -> {
69
val pickedDate = objectMapper.treeToValue(messageData[0].data, PickedDate::class.java)
70
itemView?.dateMessageText?.text = textPayload
71
itemView?.date?.text = "On: ${pickedDate.date}"
72
}
73
}
74
}
75
}
76
}
77
}
Copied!
ChatRecyclerViewAdapter.java
1
public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerViewAdapter.ViewHolder> {
2
private List<Message> messageList;
3
private String currentUserId;
4
5
private ObjectMapper objectMapper = new ObjectMapper();
6
7
public ChatRecyclerViewAdapter(
8
List<Message> messageList,
9
String currentUserId
10
) {
11
this.messageList = messageList;
12
this.currentUserId = currentUserId;
13
}
14
15
@NonNull
16
@Override
17
public ChatRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
18
View itemView = LayoutInflater.from(parent.getContext()).inflate(
19
getLayoutId(viewType),
20
parent,
21
false
22
);
23
return new ViewHolder(itemView, viewType);
24
}
25
26
@Override
27
public void onBindViewHolder(@NonNull ChatRecyclerViewAdapter.ViewHolder holder, int position) {
28
Message message = messageList.get(position);
29
PickedDate pickedDate = null;
30
31
if (!message.getMessageData().isEmpty() && message.getMessageData().get(0).getData() != null) {
32
try {
33
pickedDate = objectMapper.treeToValue(message.getMessageData().get(0).getData(), PickedDate.class);
34
} catch (JsonProcessingException jpe) {
35
}
36
}
37
38
switch (holder.getItemViewType()) {
39
case MessageTypes.SELF_PLAIN_MESSAGE:
40
holder.selfMessageText.setText(message.getTextPayload());
41
break;
42
case MessageTypes.OTHER_PLAIN_MESSAGE:
43
holder.otherMessageText.setText(message.getTextPayload());
44
break;
45
case MessageTypes.SELF_DATE_MESSAGE:
46
holder.selfDateMessageText.setText(message.getTextPayload());
47
holder.selfDate.setText("On: " + pickedDate != null ? pickedDate.getDate() : "");
48
break;
49
case MessageTypes.OTHER_DATE_MESSAGE:
50
holder.dateMessageText.setText(message.getTextPayload());
51
holder.date.setText("On: " + pickedDate != null ? pickedDate.getDate() : "");
52
break;
53
default:
54
break;
55
}
56
}
57
58
@Override
59
public int getItemCount() {
60
return messageList != null ? messageList.size() : 0;
61
}
62
63
@Override
64
public int getItemViewType(int position) {
65
if (messageList.get(position).getSenderId().domainId().equals(currentUserId)) {
66
Message message = messageList.get(position);
67
68
if (message.getMessageData().isEmpty()) {
69
return MessageTypes.SELF_PLAIN_MESSAGE;
70
} else {
71
return MessageTypes.SELF_DATE_MESSAGE;
72
}
73
} else {
74
Message message = messageList.get(position);
75
76
if (message.getMessageData().isEmpty()) {
77
return MessageTypes.OTHER_PLAIN_MESSAGE;
78
} else {
79
return MessageTypes.OTHER_DATE_MESSAGE;
80
}
81
}
82
}
83
84
class MessageTypes {
85
static final int SELF_PLAIN_MESSAGE = 0;
86
static final int OTHER_PLAIN_MESSAGE = 1;
87
static final int SELF_DATE_MESSAGE = 2;
88
static final int OTHER_DATE_MESSAGE = 3;
89
}
90
91
private int getLayoutId(int viewType) {
92
switch (viewType) {
93
case MessageTypes.SELF_PLAIN_MESSAGE:
94
return R.layout.item_message_self;
95
case MessageTypes.SELF_DATE_MESSAGE:
96
return R.layout.item_message_date_self;
97
case MessageTypes.OTHER_DATE_MESSAGE:
98
return R.layout.item_message_date;
99
default:
100
return R.layout.item_message_other;
101
102
}
103
}
104
105
class ViewHolder extends RecyclerView.ViewHolder {
106
private TextView selfMessageText;
107
private TextView otherMessageText;
108
private TextView selfDateMessageText;
109
private TextView selfDate;
110
private TextView dateMessageText;
111
private TextView date;
112
113
114
public ViewHolder(View itemView, int viewType) {
115
super(itemView);
116
117
switch (viewType) {
118
case MessageTypes.SELF_PLAIN_MESSAGE:
119
selfMessageText = itemView.findViewById(R.id.selfMessageText);
120
break;
121
case MessageTypes.OTHER_PLAIN_MESSAGE:
122
otherMessageText = itemView.findViewById(R.id.otherMessageText);
123
break;
124
case MessageTypes.SELF_DATE_MESSAGE:
125
selfDateMessageText = itemView.findViewById(R.id.selfDateMessageText);
126
selfDate = itemView.findViewById(R.id.selfDate);
127
break;
128
case MessageTypes.OTHER_DATE_MESSAGE:
129
dateMessageText = itemView.findViewById(R.id.dateMessageText);
130
date = itemView.findViewById(R.id.date);
131
break;
132
default:
133
break;
134
}
135
}
136
}
137
}
Copied!
Here, we did a couple of things:
  • Added our new date message layouts
  • Mapped them to their specific message types
  • Rendered each message based on their message type or rather view type
If you run the app now and send a message with a date, you’ll see the date appearing right below your typed message text. Also, your date messages will appear different for different users:
  • Just the message text and the date for self-messages
  • Additional Yes/No buttons for other users’ messages
Go ahead, try this out.
The date message received with Yes/No options

Add action to the chat bubble buttons

The only thing that’s left in this chapter is to add some actions to the buttons that we added in the previous step.
First, create two empty classes called YesAction and NoAction. These are basically events that we’ll be sending out on the button clicks and act on them when we receive them in the MainActivity.
After you’ve done that, navigate to the ChatRecyclerViewAdapter and modify the following block inside your ViewHolder class like this:
Kotlin
Java
ChatRecyclerViewAdapter.kt
1
MessageTypes.OTHER_DATE_MESSAGE -> {
2
val pickedDate = objectMapper.treeToValue(messageData[0].data, PickedDate::class.java)
3
itemView?.dateMessageText?.text = textPayload
4
itemView?.date?.text = "On: ${pickedDate.date}"
5
6
itemView?.yesButton?.setOnClickListener {
7
EventBus.getDefault().post(YesAction())
8
}
9
10
itemView?.noButton?.setOnClickListener {
11
EventBus.getDefault().post(NoAction())
12
}
13
}
Copied!
ChatRecyclerViewAdapter.java
1
case MessageTypes.OTHER_DATE_MESSAGE:
2
dateMessageText = itemView.findViewById(R.id.dateMessageText);
3
yesButton = itemView.findViewById(R.id.yesButton);
4
noButton = itemView.findViewById(R.id.noButton);
5
date = itemView.findViewById(R.id.date);
6
7
yesButton.setOnClickListener(new View.OnClickListener() {
8
@Override
9
public void onClick(View v) {
10
EventBus.getDefault().post(new YesAction());
11
}
12
});
13
14
noButton.setOnClickListener(new View.OnClickListener() {
15
@Override
16
public void onClick(View v) {
17
EventBus.getDefault().post(new NoAction());
18
}
19
});
20
21
break;
Copied!
Here, we’re basically sending out events using the event bus that we previously added to our app, on each button click.
Now, we need to subscribe to these sent events and act on them in our MainActivity. Navigate to your MainActivity and add the following methods:
Kotlin
Java
MainActivity.kt
1
@Subscribe(threadMode = ThreadMode.MAIN)
2
fun onYesAction(yesAction: YesAction) {
3
messaging.sendTextMessage(
4
channelId = channelId,
5
message = "Yes, I'm available"
6
)
7
}
8
9
@Subscribe(threadMode = ThreadMode.MAIN)
10
fun onNoAction(noAction: NoAction) {
11
messaging.sendTextMessage(
12
channelId = channelId,
13
message = "No, I'm not available"
14
)
15
}
Copied!
MainActivity.java
1
@Subscribe(threadMode = ThreadMode.MAIN)
2
public void onYesAction(YesAction yesAction) {
3
messaging.sendTextMessage(
4
channelId,
5
"Yes, I'm available",
6
new AppliedAclList(
7
new ArrayList<AppliedAcl>(),
8
new ArrayList<AppliedAcl>()
9
),
10
null
11
);
12
}
13
14
@Subscribe(threadMode = ThreadMode.MAIN)
15
public void onNoAction(NoAction noAction) {
16
messaging.sendTextMessage(
17
channelId,
18
"No, I'm not available",
19
new AppliedAclList(
20
new ArrayList<AppliedAcl>(),
21
new ArrayList<AppliedAcl>()
22
),
23
null
24
);
25
}
Copied!
What we’re doing here is listening to the incoming YesAction and NoAction events and sending out a plain text message accordingly.
This will act as a shortcut confirmation message action for our users, kind of like what you see in popular apps like Google Allo and Facebook Messenger.
Sending out a confirmation message on choosing an action
And that’s the end of the chapter. You’ve successfully added custom payloads to your messages and responded to them accordingly to update your UI.
Last modified 3yr ago