This page explains the key functions of open channels in Sendbird UIKit for Android, demonstrating how to create a channel, chat in a channel, configure the channel settings, and list channel participants.
Open channels are a public chat that allows a massive number of users to interact with one other in a more dynamic environment. Open channels can accommodate far more users compared to group channels and don’t require an invitation for the users to enter. To learn more about different behaviors of open channels and group channels, see Channel types on how open channels and group channels work.
An open channel allows dynamic interaction among a massive number of users. Open channels can be easily managed without the need for complex implementation because the OpenChannelFragment uses the OpenChannelMessageListAdapter to manage messages in a channel.
UIKit supports plain text messages, file messages, and media content such as photos and videos. All messages in open channels are cached using memory, and messages that failed to be sent are only kept within the active channel object.
Unlike group channels, open channels in UIKit support an overlayMode. This allows you to add a semi-transparent upper layer on the top of the channel background. The overlayMode can be useful for events like live streaming that requires an open channel to display both an overlapped foreground and background while running a client app.
Note: To quickly build an Android messaging UI, see this tutorial.
UIKit’s OpenChannelFragment class extends the Fragment class and can freely customize the activity. It is recommended to create this fragment using the onCreate() method of the user-generated activity. By default, the header of the channel view is invisible when using the OpenChannelFragment. If you want to display the header, you can configure the view as follows:
public class OpenChannelActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sb_activity);
OpenChannelFragment fragment = createOpenChannelFragment(CHANNEL_URL);
// Put the Fragment in the view.
}
protected OpenChannelFragment createOpenChannelFragment(@NonNull String channelUrl) {
return new OpenChannelFragment.Builder(channelUrl)
.setUseHeader(true)
.build();
}
}
Note : To use the UIKit's fragments as a nested fragment, refer to the Android Developer Documentation's Nested Fragments. Additionally, if the fragment size is small enough to be covered by the soft keyboard, it is recommended to use the keyboard display type as KeyboardDisplayType.Dialog.
The OpenChannelFragment class allows you to customize the UI of your channel view. As shown below, the fragment class is composed of three regions: the header, message list, and message input field.
Acts as an optional ActionBar in the channel activity. By default, the activity displays the channel cover image, channel name, creator name, as well as two buttons on the top left and top right corners, which are all customizable. If the top left button is clicked, the finish() method of the activity is called. If the top right button is selected, the operator is taken to the OpenChannelSettingsActivity while the participant is taken to the ParticipantsListActivity.
Message list
UIKit provides ten different types of messages listed in the table below. If the message grouping is used for your UI, messages are grouped based on a user who sent them and the time those messages were sent. For example, messages sent by each user are divided and displayed by minute.
Message input field
Allows users to either send a text message or send a file message by importing a file, image, or video stored on their devices.
A text message sent by the current user. If the message fails to send, tap the message again to re-send it. Also, the failed message can be deleted by pressing and holding the message. Successfully sent messages can also be copied, edited, and deleted with a long press.
VIEW_TYPE_USER_MESSAGE_OTHER (1)
A text message sent by other users. The message can be copied with a long press.
VIEW_TYPE_FILE_MESSAGE_ME (2)
A file message sent by the current user. If the message fails to send, tap the message again to re-send it. Also, the failed message can be deleted by pressing and holding the message. Successfully sent file messages will open in a new window when tapped, and can be deleted or saved with a long press.
VIEW_TYPE_FILE_MESSAGE_OTHER (3)
A file message sent by other users. The file message will open in a new window when tapped, and the attached file can be saved with a long press.
VIEW_TYPE_FILE_MESSAGE_IMAGE_ME (4)
An image message sent by the current user. If the message fails to send, tap the message again to re-send it. Also, the failed message can be deleted by pressing and holding the message. Images can be previewed through the PhotoViewActivity when tapped, and deleted or saved with a long press.
VIEW_TYPE_FILE_MESSAGE_IMAGE_OTHER (5)
A file message sent by other users. The file can be previewed through the PhotoViewActivity when tapped, and saved with a long press.
VIEW_TYPE_FILE_MESSAGE_VIDEO_ME (6)
A video message sent by the current user. If the message fails to send, tap the message again to re-send it. Also, the failed message can be deleted by pressing and holding the message. Successfully sent video messages will play in a new window when tapped, and can be deleted and saved with a long press.
VIEW_TYPE_FILE_MESSAGE_VIDEO_OTHER (7)
A video message sent by other users. The video will play in a new window when tapped, and saved with a long press.
VIEW_TYPE_ADMIN_MESSAGE (8)
A message sent by the admin. Typically, this message appears when users enter a channel or a channel is created.
VIEW_TYPE_TIME_LINE (9)
A message that displays the message timeline by the date sent if a day or more has passed since delivery.
The OpenChannelFragment.Builder class provides APIs that allow you to customize the OpenChannelFragment fragment. Before building, the OpenChannelFragment’s settings can be configured using the builder’s setters as shown below:
Applies CustomOpenChannelFragment to OpenChannelFragment. By inheritance, CustomOpenChannelFragment should be a subclass of OpenChannelFragment.
setUserHeader()
Determines whether the header is used. (Default: false)
setHeaderTitle()
Specifies the title of the header. (Default: channel name)
setHeaderDescription()
Specifies the description of the header. (Default: participants count)
setUseHeaderLeftButton()
Determines whether the left-side button of the header is used. (Default: true)
setUseHeaderRightButton()
Determines whether the right-side button of the header is used. (Default: true)
setHeaderLeftButtonIconResId()
Specifies the icon of the left-side button of the header. (Default: icon_arrow_left)
setHeaderLeftButtonIcon()
Specifies the icon and the tint on the left-side button of the header. (Default: icon_arrow_left, light mode : primary_300, dark mode : primary_200)
setHeaderRightButtonIconResId()
Specifies the icon of the right-side button of the header. (Default: icon_members (participants), icon_info (operators))
setHeaderRightButtonIcon()
Specifies the icon and the tint on the right-side button of the header. (Default: icon_members (participants), icon_info (operators), light mode : primary_300, dark mode : primary_200)
setInputLeftButtonIconResId()
Specifies the icon of the left-side button of the input box. (Default: icon_add)
setInputLeftButtonIcon()
Specifies the icon and the tint on the left-side button of the input box. (Default: icon_add, light mode : primary_300, dark mode : primary_200)
setInputRightButtonIconResId()
Specifies the icon of the right-side button of the input box. (Default: icon_send)
setInputRightButtonIcon()
Specifies the icon and the tint on the right-side button of the input box. (Default: icon_send, light mode : primary_300, dark mode : primary_200)
setInputHint()
Specifies a placeholder for the text input field. (Default: Enter message)
setHeaderLeftButtonListener()
Specifies the action of the listener for the left-side button of the header. (Default: finish the current activity)
setHeaderRightButtonListener()
Specifies the action of the listener for the right-side button of the header. (Default: start the ParticipantsListActivity (participants), start the OpenChannelSettingsActivity (operators))
setOpenChannelMessageListAdapter()
Specifies the message list adapter. (Default: UIKit's OpenChannelMessageListAdapter)
setListItemClickListener()
Specifies the action of the click listener for a message list item. (Default: action differs by message type)
setListItemLongClickListener()
Specifies the action of the long click listener for a message list item. (Default: action differs by message type)
showInputRightButtonAlways()
Determines whether to show a button on the right-side of the input box at all times. (Default: unused)
setInputLeftButtonListener()
Specifies the action of the listener for the left-side button of the input box. (Default: show a dialog for opening files)
setMessageListParams()
Specifies a set of parameters to retrieve a list of matching messages in the channel by configuring MessageListParams. If specified, the fragment will get the list from Sendbird server. Note that the reverse and nextResultSize properties of MessageListParams are not used in UIKit and thus not effective even if specified.
setUseMessageGroupUI()
Determines whether the message grouping is used in the UI. (Default: true)
setOnProfileClickListener()
(Deprecated. Use setListItemClickListener instead.)Specifies the action of the click listener on a user profile. (Default: displaying the user profile dialog)
setUseUserProfile()
Determines whether to show the user profile dialog. (Default: true)
useOverlayMode()
Determines whether to set overlay style.
setKeyboardDisplayType()
Specifies the keyboard display type for the message input. (Default: KeyboardDisplayType.Plane)
setLoadingDialogHandler()
Sets the custom loading dialog handler. (Default: UIKit's LoadingDialogHandler)
setEmptyIcon()
Specifies the icon when there aren't any messages in the channel. (Default: icon_message)
setEmptyIcon()
Specifies the icon when there aren't any messages in the channel. (Default: icon_message, light mode : onlight_03, dark mode : ondark_03)
setEmptyText()
Specifies the text when there aren't any messages in the channel. (Default: No messages)
setOnEditModeTextChangedListener()
Specifies the listener invoked whenever the message text in the input box is edited in an edit mode. (Default: null)
setInputText()
Specifies the text that appears the input box. (Default: null)
setOnInputTextChangedListener()
Specifies the listener invoked whenever the message text in the input box has changed. (Default: null)
Open channels support the overlayMode, which allows you to put another layer of content on the top of the channel background. With a simple implement, the additional interface can be applied along with other UI components through the overlay style.
The overlayMode can be useful when the background needs to be shown through. The overlayMode is supported for all orientations of the screen. If you'd like to change the styles of overlayMode, change the UIKIt-defined style values in the res/values/styles_overlay.xml file and you can access styles to add .Overlay to the UIKit-defined style names.
Note: You need to keep the original names of the items and parents defined by the UIKit during the process.
OpenChannelFragment fragment = new OpenChannelFragment.Builder(CHANNEL_URL)
.useOverlayMode()
.build();
Click listeners can be added to channel items so that a certain item can perform a specific action when tapped on the screen of a mobile device. Through the listeners, the BaseMessage object is passed as an argument to a parameter, which includes the message type of the tapped message. Different click listeners can be added based on the message type.
builder.setListItemClickListener(new OnIdentifiableItemClickListener<BaseMessage>() {
@Override
public void onIdentifiableItemClick(View view, String identifier, int position, BaseMessage message) {
MessageType type = MessageViewHolderFactory.getMessageType(message);
// Add custom implementation for an message view holder clicked event.
switch (identifier) {
case StringSet.Chat:
// ClickableViewType.Chat
case StringSet.Profile:
// ClickableViewType.Profile
case StringSet.QuoteReply:
// ClickableViewType.Reply
}
}
}).setListItemLongClickListener(new OnIdentifiableItemLongClickListener<BaseMessage>() {
@Override
public void onIdentifiableItemLongClick(View view, String identifier, int position, BaseMessage message) {
MessageType type = MessageViewHolderFactory.getMessageType(message);
// Add custom implementation for an message view holder long clicked event.
switch (identifier) {
case StringSet.Chat:
// ClickableViewType.Chat
case StringSet.Profile:
// ClickableViewType.Profile
case StringSet.QuoteReply:
// ClickableViewType.Reply
}
}
});
A message list can be customized by creating a CustomOpenChannelMessageListAdapter class that inherits the OpenChannelMessageListAdapter and MessageViewHolder classes provided by UIKit, implementing the adapter, and then applying it to the fragment.
Create a CustomOpenChannelMessageListAdapter class by inheriting the OpenChannelMessageListAdapter class and implement the custom adapter.
public class CustomOpenChannelMessageListAdapter extends OpenChannelMessageListAdapter {
public CustomOpenChannelMessageListAdapter(OpenChannel channel) {
super(channel);
}
@NonNull
@Override
public MessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// Create the custom ViewHolder and return it.
// Create your custom ViewHolder or call super.onCreateViewHolder() if you want to use the default.
return new CREATE_YOUR_CUSTOM_VIEWHOLDER();
}
@Override
public void onBindViewHolder(@NonNull MessageViewHolder holder, int position) {
// You must call the super. You can use methods that MessageViewHolder provides
super.onBindViewHolder(holder, position);
// Bind the custom ViewHolder.
}
@Override
public int getItemViewType(int position) {
BaseMessage message = getItem(position);
// Create a message type using a BaseMessage object.
// If you want to use holders that UIKit provides, you have to call the super.
// If you want to implement a custom message type, set the type as a number greater than 1,000.
return super.getItemViewType(position);
}
}
Create a CustomOpenChannelMessageListAdapter class by inheriting the MessageViewHolder class and implement a custom ViewHolder class.
public class CustomMessageViewHolder extends MessageViewHolder {
public CustomMessageViewHolder(View view) {
super(view);
}
@Override
public void bind(BaseChannel channel, @NonNull BaseMessage message) {
// Bind the data to the view holder.
}
@Override
public Map<String, View> getClickableViewMap() {
// Put clickable views with identifers.
clickableViewMap.put(ClickableViewIdentifier.Chat.name(), chatView);
clickableViewMap.put(ClickableViewIdentifier.Profile.name(), profileView);
clickableViewMap.put(ClickableViewIdentifier.QuoteReply.name(), quoteReplyView);
return clickableViewMap;
}
}
To customize the style of channel items, change the UIKit-defined style values in the res/values/styles.xml file. The table below shows the style of channel items you can customize. You need to keep the original names of the items and parents defined by the UIKit during the process.
Note : To apply our Dark theme, create a res/values/styles_dark.xml file and then add .Dark to the UIKit-defined style names.
The size, color, font, and style of text in message timeline.
sb_message_timeline_background
drawable/color
The background image or color of the message timeline.
To apply the declared custom styles, pass the unique URL of the channel and the R.style.Custom to the OpenChannelFragment.Builder constructor as shown below:
new OpenChannelFragment.Builder(CHANNEL_URL, R.style.Custom).build();
UIKit’s ParticipantsListFragment class extends the Fragment class and is designed to take up the whole screen of the activity. It is recommended to create this fragment in the onCreate() method of the user-generated activity. By default, the header of the channel participants list view isn’t visible when using the ParticipantsListFragment.
public class ParticipantsListActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sb_activity);
ParticipantsListFragment Fragment = createParticipantsListFragment(CHANNEL_URL);
// Put the Fragment in the view.
}
protected ParticipantsListFragment createParticipantsListFragment(@NonNull String channelUrl) {
return new ParticipantsListFragment.Builder(channelUrl)
.setUseHeader(true)
.setHeaderTitle(getString(R.string.sb_text_header_participants))
.setEmptyIcon(R.drawable.icon_chat)
.setEmptyText(R.string.sb_text_participants_list_empty)
.build();
}
}
Note : To use UIKit's fragments as a nested fragment, refer to the Android Developer Documentation's Nested Fragments.
The ParticipantsListFragment class allows you to customize the UI of the participant list view. As shown below, the fragment class is composed of two regions: the header and participant list.
Acts as an optional ActionBar in the activity. By default, it displays the title and one button on the top left. The button icon and title can be customized. If the left button is clicked, the finish() method of the activity is called.
Participants list
Consists of each user’s profile image and nickname. By default, You can retrieve a list of participants who are currently online and receiving all messages from an open channel.
The ParticipantsListFragment.Builder class provides APIs that allow you to customize the ParticipantsListFragment fragment. Before building, the ParticipantsListFragment’s settings can be configured using the builder’s setters as shown below:
ParticipantsListFragment Fragment = new ParticipantsListFragment.Builder(CHANNEL_URL)
.setCustomParticipantsListFragment(new CustomParticipantsListFragment())
.setUseHeader(true)
.setHeaderTitle("Participants")
.setUseHeaderLeftButton(true)
.setHeaderLeftButtonIconResId(R.drawable.icon_arrow_left)
.setHeaderLeftButtonListener(leftButtonListener)
.setEmptyIcon(R.drawable.icon_chat)
.setEmptyText(R.string.sb_text_participants_list_empty)
.setParticipantsListAdapter(adapter)
.setItemClickListener(itemClickListener)
.setItemLongClickListener(itemLongClickListener)
.setUseUserProfile(true)
.build();
Applies CustomParticipantsListFragment to ParticipantsListFragment. By inheritance, CustomParticipantsListFragment should be a subclass of ParticipantsListFragment.
setUserHeader()
Determines whether the header is used. (Default: calls from an activity: true, calls from a fragment: false)
setHeaderTitle()
Specifies the title of the header. (Default: Participants)
setUseHeaderLeftButton()
Determines whether the left-side button of the header is used. (Default: true)
setHeaderLeftButtonIconResId()
Specifies the icon of the left-side button of the header. (Default: icon_arrow_left)
setHeaderLeftButtonIcon()
Specifies the icon and the tint for the button on the left side of the header. (Default: icon_arrow_left, light mode : primary_300, dark mode : primary_200)
setHeaderLeftButtonListener()
Specifies the action of the listener for the left-side button of the header. (Default: finish the current activity)
setEmptyIcon()
Specifies the icon when there aren't any participants in the channel. (Default: icon_chat, light mode : onlight_03, dark mode : ondark_03)
setEmptyText()
Specifies the text when there aren't any participants in the channel. (Default: No users)
setParticipantsListAdapter()
Specifies the participant list adapter. (Default: UIKit's ParticipantsListAdapter)
setItemClickListener()
Specifies the action of the click listener for an item of the participant list. (Default: none)
setItemLongClickListener()
Specifies the action of the long click listener for an item of the participant list. (Default: none)
setOnProfileClickListener()
(Deprecated. Use setListItemClickListener instead.)Specifies the action of the click listener on a user profile. (Default: displaying the user profile dialog)
setUseUserProfile()
Determines whether to show the user profile dialog. (Default: false)
Click listeners can be added to participant items so that a certain item can perform a specific action when clicked. Through the listeners, the User object is passed as an argument to a parameter, which can be used to retrieve participant information.
builder.setItemClickListener(new OnItemClickListener<User>() {
@Override
public void onItemClick(View view, int position, User data) {
// Set what action to perform when an item is clicked.
}
}).setItemLongClickListener(new OnItemLongClickListener<User>() {
@Override
public void onItemLongClick(View view, int position, User data) {
// Set what action to perform when an item is long-clicked.
}
});
A participant list can be customized by creating CustomParticipantsListAdapter class that inherits the UserTypeListAdapter and BaseViewHolder<User> classes provided by UIKit, implementing the adapter, and then applying it in the fragment.
Create a CustomParticipantsListAdapter class by inheriting the UserTypeListAdapter class and implement the custom adapter.
public class CustomParticipantsListAdapter extends UserTypeListAdapter {
@NonNull
@Override
public BaseViewHolder<User> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// Create the custom view holder and return it.
// Create your custom viewholder or you can call super.onCreateViewHolder() if you want to use the default.
return new CREATE_YOUR_CUSTOM_VIEWHOLDER();
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder<User> holder, int position) {
// When you call the super, the listener implemented through Builder is attached.
// You can implement your own listener here without calling the super.
super.onBindViewHolder(holder, position);
// Bind the custom view holder.
}
}
Create a CustomParticipantViewHolder class by inheriting the BaseViewHolder<User> class and implement a custom ViewHolder class.
public class CustomParticipantViewHolder extends BaseViewHolder<User> {
public CustomParticipantViewHolder(@NonNull View itemView) {
super(itemView);
}
@Override
public void bind(User item) {
// Bind the data to the view holder.
}
}
To customize the style of participant items, change the UIKit-defined style values in the res/values/styles.xml file. The style of participant items is the same as that of member items. The table below shows the style of member items you can customize. You need to keep the original names of the items and parents defined by UIKit during the process.
Note : To apply our Dark theme, create a res/values/styles_dark.xml file and then add .Dark at the end of each UIKit-defined style name.
The OpenChannelSettingsActivity or OpenChannelSettingsFragment class allows you to configure and customize the settings of each channel. These classes can be used to change the channel name, cover image, or delete the channel. They can also be used to check the number of channel participants or go to the ParticipantsListActivity.
Note : Only operators can update the channel settings.
UIKit’s OpenChannelSettingsFragment class extends the Fragment and is designed to take up the whole screen of the activity. By default, the header isn’t visible when using the OpenChannelSettingsFragment. When creating a OpenChannelSettingsFragment fragment, the unique URL of the channel must be passed as an argument.
public class OpenChannelSettingsActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sb_activity);
OpenChannelSettingsFragment fragment = createOpenChannelSettingsFragment(url);
// Put the Fragment in the view.
}
protected OpenChannelSettingsFragment createOpenChannelSettingsFragment(@NonNull String channelUrl) {
return new OpenChannelSettingsFragment.Builder(channelUrl)
.setUseHeader(true)
.build();
}
}
Note : To use UIKit's fragments as a nested fragment, refer to the Android Developer Documentation's Nested Fragments.
The OpenChannelSettingsFragment class allows you to customize the UI of your channel settings view. As shown below there are three regions of the fragment class: the header, channel information, and settings.
Acts as an optional ActionBar in the activity. By default, it displays the title and two buttons on the top left and right corners, and only the left-side button of the title and the icon can be customized. If the left-side button is tapped, the finish() method of the activity is called. If the right-side button is tapped, a dialog appears asking if the user would like to change the channel’s cover image and name.
Channel information
Includes the channel's cover image and name. The channel’s cover image and name can be changed with the edit button. The change is reflected immediately but loading the new cover image may take some time.
Settings
Provides the Settings menu as shown in the following table.
The OpenChannelSettingsFragment.Builder class provides APIs that allow you to customize the OpenChannelSettingsFragment fragment. Before building, the OpenChannelSettingsFragment can be customized using the builder’s setters as shown below:
OpenChannelSettingsFragment Fragment = new OpenChannelSettingsFragment.Builder(CHANNEL_URL)
.setCustomOpenChannelSettingsFragment(new CustomOpenChannelSettingsFragment())
.setUseHeader(true)
.setHeaderTitle("Settings")
.setUseHeaderLeftButton(true)
.setUseHeaderRightButton(true)
.setHeaderLeftButtonIconResId(R.drawable.icon_arrow_left)
.setHeaderLeftButtonListener(leftButtonListener)
.setOnSettingMenuClickListener(clickListener)
.setLoadingDialogHandler(loadingDialogHandler)
.build();
Applies CustomOpenChannelSettingsFragment to OpenChannelSettingsFragment. By inheritance, CustomOpenChannelSettingsFragment should be a subclass of OpenChannelSettingsFragment.
setUserHeader()
Determines whether the header is used. (Default: calls from an activity: true, calls from a fragment: false)
setHeaderTitle()
Specifies the title of the header. (Default: Channel information)
setUseHeaderLeftButton()
Determines whether the left-side button of the header is used. (Default: true)
setUseHeaderRightButton()
Determines whether the right-side button of the header is used. (Default: true)
setHeaderLeftButtonIconResId()
Specifies the icon of the button on the left side of the header. (Default: icon_arrow_left)
setHeaderLeftButtonIcon()
Specifies the icon and the tint for the button that's on the left side of the header. (Default: icon_arrow_left, light mode : primary_300, dark mode : primary_200)
setHeaderLeftButtonListener()
Specifies the action of listener for the left-side button of the header. (Default: finish the current activity)
setOnSettingMenuClickListener()
Specifies the action of click listener for the items of the menu.
setLoadingDialogHandler()
Sets the custom loading dialog handler. (Default: UIKit's LoadingDialogHandler)
To customize the style of channel settings items, change the UIKit-defined style values in the res/values/styles.xml file. The table below shows the style of channel settings items you can customize. You need to keep the original names of the items and parents defined by the UIKit during the process.
Note : To apply our Dark theme, create a res/values/styles_dark.xml file and then add .Dark to the UIKit-defined style names.
The shape or color of the items in the channel settings.
sb_channel_settings_name_appearance
text appearance
The size, color, font, and style of the text that represents the channel name.
sb_channel_settings_item_appearance
text appearance
The size, color, font, and style of the text that represents the items in the channel settings.
sb_channel_settings_description_appearance
text appearance
The text size, color, font, and style of the item descriptions in the channel settings.
sb_channel_information_title_appearance
text appearance
The text size, color, font, and style of the title in the channel information.
sb_channel_information_content_appearance
text appearance
The text size, color, font, and style of the content in the channel information.
To apply the declared custom styles, pass the unique URL of the channel and R.style.Custom to the OpenChannelSettingsFragment.Builder constructor as shown below:
new OpenChannelSettingsFragment.Builder(CHANNEL_URL, R.style.Custom).build();