> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-v6-beta2-flutter-uikit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Layout & UI

Control the call layout and UI elements during an active session. These methods allow you to change the call layout, enable Picture-in-Picture mode, and update UI badges.

## Prerequisites

* An active [call session](/calls/flutter/join-session)
* Access to the `CallSession` instance

## Get CallSession Instance

Layout and UI methods are called on the `CallSession` singleton:

```dart theme={null}
CallSession? callSession = CallSession.getInstance();
```

<Note>
  `CallSession.getInstance()` returns `null` if no active session exists. Always use the null-aware `?.` operator when calling methods.
</Note>

***

## Set Layout

Change the call layout during an active session.

```dart theme={null}
// Switch to tile layout (grid view)
await CallSession.getInstance()?.setLayout(LayoutType.tile);

// Switch to spotlight layout (active speaker focus)
await CallSession.getInstance()?.setLayout(LayoutType.spotlight);

// Switch to sidebar layout
await CallSession.getInstance()?.setLayout(LayoutType.sidebar);
```

### LayoutType Enum

| Value                  | Description                                              |
| ---------------------- | -------------------------------------------------------- |
| `LayoutType.tile`      | Grid layout showing all participants equally sized       |
| `LayoutType.spotlight` | Focus on the active speaker with others in smaller tiles |
| `LayoutType.sidebar`   | Main speaker with participants in a sidebar              |

<Note>
  When the layout changes, the `onCallLayoutChanged(LayoutType)` callback is triggered on your `LayoutListener`.
</Note>

***

## Set Call Layout Type

Alias for `setLayout()`. Changes the call layout.

```dart theme={null}
await CallSession.getInstance()?.setCallLayoutType(LayoutType.tile);
```

***

## Picture-in-Picture Mode

Enable Picture-in-Picture (PiP) mode to allow users to continue viewing the call while using other apps.

### Enable PiP

```dart theme={null}
await CallSession.getInstance()?.enablePictureInPictureLayout();
```

### Disable PiP

```dart theme={null}
await CallSession.getInstance()?.disablePictureInPictureLayout();
```

### Enter PiP Mode

Enter the system Picture-in-Picture mode directly.

```dart theme={null}
await CallSession.getInstance()?.enterPipMode();
```

<Note>
  PiP behavior differs between platforms. Android uses the system PiP window, while iOS uses a custom overlay. Use `isPipSupported()` to check availability before calling this method.
</Note>

***

## Set Chat Button Unread Count

Update the badge count on the chat button to show unread messages.

```dart theme={null}
// Set unread count
await CallSession.getInstance()?.setChatButtonUnreadCount(5);

// Clear unread count
await CallSession.getInstance()?.setChatButtonUnreadCount(0);
```

| Parameter | Type  | Description                                       |
| --------- | ----- | ------------------------------------------------- |
| `count`   | `int` | Number of unread messages to display on the badge |

<Note>
  The chat button must be visible (`hideChatButton(false)`) for the badge to appear.
</Note>

***

## Listen for Layout Events

Register a `LayoutListener` to receive callbacks when layout changes occur:

```dart theme={null}
CallSession.getInstance()?.layoutListener = LayoutListeners(
  onCallLayoutChanged: (LayoutType layoutType) {
    debugPrint("Layout changed to: $layoutType");
  },
  onParticipantListVisible: () {
    debugPrint("Participant list is now visible");
  },
  onParticipantListHidden: () {
    debugPrint("Participant list is now hidden");
  },
  onPictureInPictureLayoutEnabled: () {
    debugPrint("PiP mode enabled");
  },
  onPictureInPictureLayoutDisabled: () {
    debugPrint("PiP mode disabled");
  },
);
```

<Note>
  Flutter listeners are not lifecycle-aware. You must manually remove listeners in your widget's `dispose()` method to prevent memory leaks.
</Note>

***

## Initial Layout Settings

Configure the initial layout when joining a session:

```dart theme={null}
SessionSettings sessionSettings = CometChatCalls.SessionSettingsBuilder()
    .setLayout(LayoutType.tile)  // Start with tile layout
    .build();
```

***

## Hide UI Elements

Control the visibility of various UI elements:

```dart theme={null}
SessionSettings sessionSettings = CometChatCalls.SessionSettingsBuilder()
    // Panels
    .hideControlPanel(false)         // Show bottom control bar
    .hideHeaderPanel(false)          // Show top header bar
    .hideSessionTimer(false)         // Show session duration timer

    // Buttons
    .hideChangeLayoutButton(false)   // Show layout toggle button
    .hideChatButton(false)           // Show chat button
    .hideParticipantListButton(false) // Show participant list button
    .build();
```

***

## Button Click Listeners

Listen for UI button clicks to implement custom behavior:

```dart theme={null}
CallSession.getInstance()?.addButtonClickListener(ButtonClickListeners(
  onChangeLayoutButtonClicked: () {
    debugPrint("Layout button clicked");
  },
  onChatButtonClicked: () {
    debugPrint("Chat button clicked");
    // Open your chat UI
  },
  onParticipantListButtonClicked: () {
    debugPrint("Participant list button clicked");
  },
));
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Session Control" icon="door-open" href="/calls/flutter/session-control">
    Leave session and hand raise controls
  </Card>

  <Card title="Layout Listener" icon="bell" href="/calls/flutter/layout-listener">
    Handle all layout events
  </Card>
</CardGroup>
