# Custom Message Types
Chat SDK uses [ChatKit](https://github.com/stfalcon-studio/ChatKit/blob/master/docs/COMPONENT_MESSAGES_LIST.md) for the message view so I would recommend that you look at their documentation before trying to add custom message types to Chat SDK. Chat SDK really just exposes the ChatKit custom mesassage API.
## Override Text Message Display
In this example we will override the outcoming text message so that we can append "Hello World!" to every text message.
To do this, the first step is to make a new class that extends the `OutcomingTextMessageViewHolder`.
```
public class CustomOutcomingTextMessageViewHolder extends OutcomingTextMessageViewHolder {
public CustomOutcomingTextMessageViewHolder(View itemView, Object payload) {
super(itemView, payload);
}
@Override
public void onBind(MessageHolder message) {
super.onBind(message);
text.setText(text.getText() + " Hello World");
}
}
```
The `onBind` method is what binds the `MessageHolder` data model to the `MesageViewHolder`.
We then need to make a new subclass of the `TextMessageHandler` class so that we can register the new view holder with Chat SDK.
```
public class CustomTextMessageHandler extends TextMessageHandler {
@Override
public void onBindMessageHolders(Context context, MessageHolders holders) {
holders.setIncomingTextConfig(IncomingTextMessageViewHolder.class, R.layout.view_holder_incoming_text_message, getAvatarClickPayload(context))
.setOutcomingTextConfig(CustomOutcomingTextMessageViewHolder.class, R.layout.view_holder_outcoming_text_message, getAvatarClickPayload(context));
}
}
```
This is where we are registering the view holder with ChatKit. We can also specify custom layout files.
Finally, we need to tell Chat SDK to use this message handler:
```
MessageCustomizer.shared().setTextMessageHandler(new CustomTextMessageHandler());
```
### Creating a Custom Message Type
Chat SDK supports completely custom message types. To do this, we need to use the `IMessageHandler` protocol. We can look at the image message handler as an example:
```
public class ImageMessageHandler extends MessageHandler {
@Override
public void onBindMessageHolders(Context context, MessageHolders holders) {
holders.registerContentType(
(byte) MessageType.Image,
IncomingImageMessageViewHolder.class,
getAvatarClickPayload(context),
R.layout.view_holder_incoming_image_message,
OutcomingImageMessageViewHolder.class,
getAvatarClickPayload(context),
R.layout.view_holder_outcoming_image_message,
MessageCustomizer.shared());
}
@Override
public void onClick(ChatActivity activity, View rootView, Message message) {
if (message.getSender().isMe() && message.getMessageStatus() == MessageSendStatus.Failed) {
super.onClick(activity, rootView, message);
} else if (message.getMessageType().is(MessageType.Image)) {
ImageMessageOnClickHandler.onClick(activity, rootView, message.stringForKey(Keys.ImageUrl));
}
else if (message.getMessageType().is(MessageType.Location)) {
double longitude = message.doubleForKey(Keys.MessageLongitude);
double latitude = message.doubleForKey(Keys.MessageLatitude);
Location location = new Location(ChatSDK.getString(R.string.app_name));
location.setLatitude(latitude);
location.setLongitude(longitude);
LocationMessageOnClickHandler.onClick(activity, location);
}
}
@Override
public MessageHolder onNewMessageHolder(Message message) {
if (message.getMessageType().is(MessageType.Image, MessageType.Location)) {
return new ImageMessageHolder(message);
}
return super.onNewMessageHolder(message);
}
@Override
public boolean hasContentFor(MessageHolder message, byte type) {
return type == MessageType.Image && message instanceof ImageMessageHolder;
}
}
```
- The `onBindMessageHolder` allows us to register our content type with ChatKit
- The `onClick` method is called if the user clicks the message
- The `onNewMessageHolder` method is called to provide a new instance of the message holder
- The `hasContentFor` method lets the system know when this custom message type should be used
To register this with the framework, you can use the following:
```
MessageCustomizer.shared().addMessageHandler(new ImageMessageHandler());
```
### Summary
This may seem complicated, if that's the case, I would recommend thoroughly reviewing the ChatKit documentation. This guide just explains how to access the ChatKit API from within Chat SDK. It doesn't go throught the ChatSDK API in detail.