import io.getstream.video.android.compose.ui.components.call.activecall.CallContent
import io.getstream.video.android.compose.ui.components.call.renderer.LayoutType
@Composable
fun MyCallScreen(call: Call) {
CallContent(
call = call,
layout = LayoutType.GRID // or SPOTLIGHT, DYNAMIC
)
}Runtime Layout Switching
During your application's lifecycle, there will be situations where you'll want to direct your users to a different video layout based on certain events. In this guide, we'll explore how to automatically switch to a video layout that is better suited for when any of the participants starts a screen share session, as well as how to implement manual layout switching controlled by the user.
Available Layouts
The SDK provides three layout options through the LayoutType enum:
DYNAMIC- Automatically chooses between Grid and Spotlight based on pinned participants and dominant speakerSPOTLIGHT- Forces a spotlight view, showing the dominant speaker or the first speaker in the listGRID- Always shows a grid layout, regardless of pinned participants
Using CallContent with Layout
The CallContent composable accepts a layout parameter that controls which layout to render:
Automatic Layout Switching
A common use case is automatically switching to a spotlight layout when someone starts sharing their screen. This can be achieved by observing the screen sharing state and updating the layout accordingly:
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.getstream.video.android.compose.ui.components.call.activecall.CallContent
import io.getstream.video.android.compose.ui.components.call.renderer.LayoutType
import io.getstream.video.android.core.Call
@Composable
fun CallScreenWithAutoLayout(call: Call) {
val screenSharingSession by call.state.screenSharingSession.collectAsStateWithLifecycle()
// Automatically switch to SPOTLIGHT when someone shares screen
val layout = remember(screenSharingSession) {
if (screenSharingSession != null && !screenSharingSession!!.participant.isLocal) {
LayoutType.SPOTLIGHT
} else {
LayoutType.GRID
}
}
CallContent(
call = call,
layout = layout
)
}This pattern detects when a remote participant starts screen sharing and switches to spotlight mode to give the shared content more prominence. When screen sharing stops, it returns to grid mode.
Manual Layout Switching
You can also allow users to manually switch between layouts by maintaining layout state and providing UI controls:
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.AlertDialog
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.GridView
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import io.getstream.video.android.compose.ui.components.call.CallAppBar
import io.getstream.video.android.compose.ui.components.call.activecall.CallContent
import io.getstream.video.android.compose.ui.components.call.renderer.LayoutType
import io.getstream.video.android.core.Call
@Composable
fun CallScreenWithLayoutSwitcher(call: Call) {
var selectedLayout by remember { mutableStateOf(LayoutType.DYNAMIC) }
var showLayoutChooser by remember { mutableStateOf(false) }
CallContent(
call = call,
layout = selectedLayout,
appBarContent = { call ->
CallAppBar(
call = call,
leadingContent = {
IconButton(onClick = { showLayoutChooser = true }) {
Icon(
imageVector = Icons.Default.GridView,
contentDescription = "Change layout"
)
}
}
)
}
)
if (showLayoutChooser) {
LayoutChooserDialog(
currentLayout = selectedLayout,
onLayoutSelected = { layout ->
selectedLayout = layout
showLayoutChooser = false
},
onDismiss = { showLayoutChooser = false }
)
}
}
@Composable
fun LayoutChooserDialog(
currentLayout: LayoutType,
onLayoutSelected: (LayoutType) -> Unit,
onDismiss: () -> Unit
) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text("Choose Layout") },
text = {
Column {
LayoutType.entries.forEach { layout ->
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { onLayoutSelected(layout) }
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = layout == currentLayout,
onClick = { onLayoutSelected(layout) }
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = when (layout) {
LayoutType.DYNAMIC -> "Dynamic"
LayoutType.SPOTLIGHT -> "Spotlight"
LayoutType.GRID -> "Grid"
}
)
}
}
}
},
confirmButton = {}
)
}This example provides a complete layout switching experience where users can select their preferred layout from a dialog. The selected layout is maintained in state and passed to CallContent.
Optional Enhancements
If your application supports more than two video layouts, you might want to consider storing the preferred layout in persistent storage (such as DataStore or SharedPreferences) so when your application toggles back from automatic switching, it returns to the user's preferred layout rather than a default.