# Channel

`ChannelScreen` is a ready-to-use chat screen that handles the entire messaging experience. Use it when you want a full-featured chat UI with minimal setup.

**Included features:**

- **Message list**: Displays messages with automatic pagination, date separators, loading states, empty states, and a scroll-to-bottom button for new messages
- **Message composer**: Full-featured input with text formatting, attachment buttons, voice recording, edit mode, and reply-to-message functionality
- **Attachment picker**: Picker for selecting images from gallery, capturing photos/videos, picking files, creating polls, or using commands
- **Message actions**: Long-press menu with options for reactions, reply, thread reply, copy, edit, delete, pin, and flag
- **Reactions**: Emoji picker for adding reactions and display of reaction counts on messages
- **Thread support**: Inline thread replies with automatic navigation to thread view
- **Typing indicators**: Shows when other users are typing in the channel
- **Read receipts**: Displays read status for sent messages

<admonition type="tip">

If you need more control over the layout or want to add custom UI elements, consider using the individual [bound components](/chat/docs/sdk/android/v7/compose/component-architecture/#bound-components) like `MessageList` and `MessageComposer` instead.

</admonition>

## Usage

The benefit of a screen component solution is easy integration. All you need to do to integrate `ChannelScreen` in your app is to call it within `setContent()` in your `Activity` or `Fragment` and pass in the `ChannelViewModelFactory` with your `channelId`:

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Load the ID of the channel you've opened
    val channelId = "messaging:123"

    setContent {
        ChatTheme {
            ChannelScreen(
                viewModelFactory = ChannelViewModelFactory(
                    context = this,
                    channelId = channelId
                )
            )
        }
    }
}
```

This renders the following UI:

![Default ChannelScreen component](/data/docs/chat-sdk/android/v7-latest/_assets/compose_default_channel_screen_component.png)

Next, learn more about handling screen actions.

## Handling Actions

The `ChannelScreen` component exposes several actions for handling user interactions:

```kotlin
@Composable
fun ChannelScreen(
    ..., // State and customization
    onBackPressed: () -> Unit = {},
    onHeaderTitleClick: ((channel: Channel) -> Unit)? = null,
    onChannelAvatarClick: ((Channel) -> Unit)? = null,
    onComposerLinkPreviewClick: ((LinkPreview) -> Unit)? = null,
    onMessageLinkClick: ((Message, String) -> Unit)? = null,
    onUserAvatarClick: ((User) -> Unit)? = null,
    onUserMentionClick: (User) -> Unit = {},
)
```

- `onBackPressed`: Called when the user taps on the header back button.
- `onHeaderTitleClick`: Called when the user taps on the header title. Useful for showing the channel information.
- `onChannelAvatarClick`: Called when the user taps on the channel avatar. Receives the `Channel` object. Can be used to show channel information.
- `onComposerLinkPreviewClick`: Called when the user taps on a link preview in the message composer. Useful for opening the link in a browser or custom handler.
- `onMessageLinkClick`: Called when the user taps on a link within a message. Receives both the `Message` and the URL `String` that was clicked.
- `onUserAvatarClick`: Called when the user taps on another user's avatar in the message list. Useful for showing user profile information.
- `onUserMentionClick`: Called when the user taps on a user mention (e.g., `@username`) within a message. Useful for navigating to the mentioned user's profile.

Here's an example of setting up custom behavior:

```kotlin
ChannelScreen(
    viewModelFactory = viewModelFactory,
    onBackPressed = { finish() },
    onHeaderTitleClick = { channel ->
        // Show channel info
    },
    onChannelAvatarClick = { channel ->
        // Show channel details
    },
    onComposerLinkPreviewClick = { linkPreview ->
        // Open link preview URL
        openUrl(linkPreview.originUrl)
    },
    onMessageLinkClick = { message, url ->
        // Handle link click within a message
        openUrl(url)
    },
    onUserAvatarClick = { user ->
        // Navigate to user profile
        navigateToUserProfile(user.id)
    },
    onUserMentionClick = { user ->
        // Navigate to mentioned user's profile
        navigateToUserProfile(user.id)
    }
)
```

## Customization

The `ChannelScreen` component offers several customization options:

```kotlin
@Composable
fun ChannelScreen(
    viewModelFactory: ChannelViewModelFactory,
    showHeader: Boolean = true,
    reactionSorting: ReactionSorting = ReactionSortingByFirstReactionAt,
    skipPushNotification: Boolean = false,
    skipEnrichUrl: Boolean = false,
    showAnonymousAvatar: Boolean = false,
    verticalArrangement: Arrangement.Vertical = Arrangement.Bottom,
    threadsVerticalArrangement: Arrangement.Vertical = Arrangement.Bottom,
    topBarContent: @Composable (BackAction) -> Unit = { ... },
    bottomBarContent: @Composable () -> Unit = { ... },
    ... // action handlers
)
```

- `viewModelFactory`: The factory that you build yourself. This lets you control not just the way the `ViewModel`s are built, but also their lifecycle, as you can share them between components. This requires of you to provide a `channelId` in order to power the screen and show data, but it also allows you to customize the behavior of the screen through various parameters.
- `showHeader`: Controls whether the messages header is shown or not.
- `reactionSorting`: Defines how reactions are sorted when displayed. Defaults to `ReactionSortingByFirstReactionAt`, which sorts reactions by the time the first reaction of each type was added.
- `skipPushNotification`: When set to `true`, sending messages from this screen will not trigger push notifications to other users. Defaults to `false`.
- `skipEnrichUrl`: When set to `true`, URLs in messages will not be enriched with link previews. Defaults to `false`.
- `showAnonymousAvatar`: When set to `true`, displays avatars for anonymous users in poll comments. Defaults to `false`.
- `verticalArrangement`: Controls the vertical arrangement of messages in the list. Defaults to `Arrangement.Bottom`.
- `threadsVerticalArrangement`: Controls the vertical arrangement of messages in thread views. Defaults to `Arrangement.Bottom`.
- `topBarContent`: A composable slot for customizing the top bar/header content. Receives a `BackAction` parameter that you can use to handle back navigation. Use this to completely replace the default header with your own implementation.
- `bottomBarContent`: A composable slot for customizing the bottom bar content, which by default contains the message composer. Use this to replace or wrap the default composer with additional UI elements.

### Hiding the Header

If you set `showHeader` to `false`, the header is removed from the screen, rendering only the list and the composer.

![ChannelScreen without the ChannelHeader](/data/docs/chat-sdk/android/v7-latest/_assets/compose_custom_channel_screen_component.png)

### Customizing the Top Bar

You can provide a custom top bar using the `topBarContent` parameter:

```kotlin
ChannelScreen(
    viewModelFactory = viewModelFactory,
    topBarContent = { backAction ->
        // Custom header implementation
    }
)
```

### Customizing the Bottom Bar

You can customize the bottom bar to add additional UI elements around the composer:

```kotlin
ChannelScreen(
    viewModelFactory = viewModelFactory,
    bottomBarContent = {
        // Custom bottomBar (composer) implementation
    }
)
```

## Overriding the ViewModels

In case you want to control the logic when using the `ChannelScreen`, you can do so by providing a `ChannelViewModelFactory` that you use to build the respective ViewModels yourself.

Here's an example:

```kotlin
class MessagesActivity : ComponentActivity() {

    // 1
    private val factory by lazy {
        ChannelViewModelFactory(
            context = this,
            channelId = channelId,
            // Customization options
        )
    }

    // 2
    private val listViewModel by viewModels<MessageListViewModel>(factoryProducer = { factory })

    private val attachmentsPickerViewModel by viewModels<AttachmentsPickerViewModel>(factoryProducer = { factory })
    private val composerViewModel by viewModels<MessageComposerViewModel>(factoryProducer = { factory })

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            ChatTheme {
                ChannelScreen(
                    // 3
                    viewModelFactory = factory,
                    onBackPressed = { finish() },
                )
            }
        }
    }
}
```

There are a few steps here that allow you to override and control the ViewModels:

1. You create the `ChannelViewModelFactory` yourself, which lets you describe the data and configuration used to build the `ViewModel`s.
2. You lazily create an instance of the required `ViewModel`s. This means that you'll either build the `ViewModel` first and then pass it to the Compose component, or your Compose component will create the `ViewModel` and you'll get access to it here.
3. You pass in the factory to the `ChannelScreen`, which allows this connection to happen.

The `ViewModel`s should be the same and you should easily be able to react to things like item clicks, changes in the state and more.

## ChannelViewModelFactory Configuration

The `ChannelViewModelFactory` provides extensive configuration options for customizing the behavior of the messages screen. Here's a complete overview of all available parameters:

```kotlin
ChannelViewModelFactory(
    // Required
    context = context,
    channelId = "messaging:123",

    // Navigation
    messageId = null,
    parentMessageId = null,

    // Message display
    messageLimit = 30,
    showSystemMessages = true,
    messageFooterVisibility = MessageFooterVisibility.WithTimeDifference(),
    enforceUniqueReactions = false,

    // Separators and grouping
    dateSeparatorHandler = DateSeparatorHandler.getDefaultDateSeparatorHandler(),
    threadDateSeparatorHandler = DateSeparatorHandler.getDefaultThreadDateSeparatorHandler(),
    messagePositionHandler = MessagePositionHandler.defaultHandler(),

    // Composer settings
    maxAttachmentCount = 10,
    isComposerLinkPreviewEnabled = false,
    isComposerDraftMessageEnabled = true,

    // Thread settings
    showDateSeparatorInEmptyThread = false,
    showThreadSeparatorInEmptyThread = false,
    threadLoadOlderToNewer = false,

    // Features
    autoTranslationEnabled = true,
)
```

### Required Parameters

- `context`: Android context, used internally for clipboard operations and other system services.
- `channelId`: The ID of the channel to display messages for.

### Navigation Parameters

- `messageId`: When provided, the message list will automatically scroll to this message when opened. Useful for deep-linking to specific messages.
- `parentMessageId`: When scrolling to a message that's inside a thread, provide the parent message ID to ensure proper navigation.

### Message Display Parameters

- `messageLimit`: Number of messages to load per page. Defaults to `30`.
- `showSystemMessages`: Whether to display system messages (e.g., "User joined the channel"). Defaults to `true`.
- `messageFooterVisibility`: Controls when message footers (timestamp, read status) are shown. Defaults to showing footers when there's a time difference between messages.
- `enforceUniqueReactions`: When `true`, users can only add one reaction of each type per message. When `false`, users can add multiple reactions of the same type. Defaults to `false`.

### Separator and Grouping Parameters

- `dateSeparatorHandler`: Controls when date separators appear between messages. The default handler shows separators when messages are from different days.
- `threadDateSeparatorHandler`: Same as above but for thread message lists.
- `messagePositionHandler`: Determines message grouping and positioning (e.g., whether a message is the first, middle, or last in a group from the same user).

### Composer Parameters

- `maxAttachmentCount`: Maximum number of attachments allowed per message. Defaults to `10`.
- `isComposerLinkPreviewEnabled`: When `true`, URLs typed in the composer will show link previews. Defaults to `false`.
- `isComposerDraftMessageEnabled`: When `true`, enables draft message support. Unsent messages are saved and restored. Defaults to `true`.

### Thread Parameters

- `showDateSeparatorInEmptyThread`: Whether to show a date separator in threads with no replies. Defaults to `false`.
- `showThreadSeparatorInEmptyThread`: Whether to show the thread separator in threads with no replies. Defaults to `false`.
- `threadLoadOlderToNewer`: Controls the load direction for thread messages. When `false` (default), newer messages load first. When `true`, older messages load first.

### Feature Parameters

- `autoTranslationEnabled`: When `true`, messages are automatically translated based on user language preferences. Defaults to `true`.

### Advanced Parameters

These parameters allow injecting custom implementations for advanced use cases:

- `mediaRecorder`: Custom `StreamMediaRecorder` for voice message recording.
- `userLookupHandler`: Custom handler for user mention lookups in the composer.
- `clipboardHandler`: Custom handler for clipboard operations (copy message).
- `fileToUriConverter`: Custom function for converting files to URI strings.

<admonition type="note">

In addition to the customization options above, you can achieve a unique look and feel by modifying `ChatTheme` parameters.
For more information on how to do so read our [Customizing Components](/chat/docs/sdk/android/v7/compose/general-customization/chat-theme/) page.

</admonition>


---

This page was last updated at 2026-04-10T16:24:22.603Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/v7/compose/message-components/channel-screen/](https://getstream.io/chat/docs/sdk/android/v7/compose/message-components/channel-screen/).