The Central Hub component provides a comprehensive social betting platform where users can share bets, interact with the community, manage their profile, view notifications, and engage with other users. It serves as the central social hub for the Virtual Stadium experience.
This guide will walk you through each step with code examples and best practices.
The Central Hub component requires JWT authentication and a user ID. It can be integrated as a standalone screen or as part of your navigation flow.
Required Parameters:
jwtToken String required
JWT authentication token required to initialize the UI SDK and authenticate the user.
userId String required
The unique identifier of the logged-in user. This is used to personalize the Central Hub experience and distinguish between the user's own profile and other users' profiles.
onBack () -> Unit required
Callback invoked when the user navigates back or closes the Central Hub. Use this to handle navigation back to your app.
Optional Parameters:
modifier Modifier optional
Compose modifier for layout customization (Compose only).
onGetBets (suspend () -> List<BetPayload>)? optional
Lambda function that returns a list of user's bet slips for sharing. If null, bet sharing functionality will be limited.
onCopyToBetSlip (BetPayload) -> Unit optional
Callback invoked when a user copies a bet from another user. Returns the BetPayload to add to your bet slip.
uiSettings CentralHubUISettings optional
Customization settings for theming, fonts, and UI behavior. Default: CentralHubUISettings()
The Central Hub handles its own navigation internally, including profile screens, bet sharing, search, followers, and notifications.
MainActivity.kt:
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
import ag.sportradar.virtualstadium.uisdk.composables.CentralHub
import ag.sportradar.virtualstadium.datasdk.model.BetPayload
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
/**
* TODO(developer): Replace <your-jwt-token> with your actual JWT token
* and <your-user-id> with your actual user ID before running this code.
*/
setContent {
CentralHub(
jwtToken = "<your-jwt-token>",
userId = "<your-user-id>",
modifier = Modifier.fillMaxSize(),
onGetBets = {
// Return user's bet slips for sharing
getUserBetSlips()
},
onCopyToBetSlip = { betPayload ->
// Handle copying bet to user's bet slip
addBetToSlip(betPayload)
},
onBack = {
// Handle back navigation
finish()
}
)
}
}
private suspend fun getUserBetSlips(): List<BetPayload> {
// TODO: Implement your bet slip fetching logic
return emptyList()
}
private fun addBetToSlip(betPayload: BetPayload) {
// TODO: Implement your bet slip logic
}
}Add the Central Hub component using traditional Android Views with XML layout. The component is initialized programmatically with the same required parameters.
Required Parameters:
jwtToken String required
JWT authentication token required to initialize the UI SDK and authenticate the user.
userId String required
The unique identifier of the logged-in user.
onBack () -> Unit required
Callback invoked when the user navigates back or closes the Central Hub.
Optional Parameters:
onGetBets (suspend () -> List<BetPayload>)? optional
Lambda function that returns a list of user's bet slips for sharing.
onCopyToBetSlip (BetPayload) -> Unit optional
Callback invoked when a user copies a bet.
uiSettings CentralHubUISettings optional
Customization settings for theming, fonts, and UI behavior.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ag.sportradar.virtualstadium.uisdk.views.CentralHubView
android:id="@+id/central_hub_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>The Central Hub component supports various configuration options to customize appearance, behavior, and functionality.
onGetBets (suspend () -> List<BetPayload>)? optional
Lambda function that returns a list of user's bet slips for sharing. If null, bet sharing functionality will be limited. This function is called when the user wants to share a bet with the community.
BetPayload Structure:
data class BetPayload(
val betType: BetType, // Single, Multi, Bet Builder, etc.
val selections: List<Selection>,
val stake: Double,
val totalOdds: Double,
val potentialWin: Double,
// ... additional bet details
)onCopyToBetSlip (BetPayload) -> Unit optional
Callback invoked when a user copies a bet from another user's shared bets. Returns the BetPayload to add to your bet slip. Default is empty function {}.
uiSettings CentralHubUISettings optional
Customization settings for theming, fonts, and UI behavior. Default is CentralHubUISettings(). See UI Settings.
The Central Hub provides a rich set of social betting features organized into distinct sections:
The profile section displays user information and activity:
| Feature | Description |
|---|---|
| User Header | Display name, avatar, follower/following counts |
| Profile Statistics | Bets shared, bets copied, engagement metrics |
| My Profile | When viewing own profile: edit profile, manage settings |
| Other Profiles | When viewing others: follow/unfollow, view shared bets |
| Bet Details | Each bet shows type, markets, odds, timestamp, reactions |
The bets section focuses on bet discovery and interaction:
| Feature | Description |
|---|---|
| Bet Feed | Community feed of shared bets from all users |
| Reactions | Like, celebrate, or react to shared bets |
| Comments | Comment on shared bets and engage in discussions |
| Copy Bets | One-tap copying of bets to your bet slip |
| Filter Options | Filter by bet type, time period |
| Share Your Bets | Share your own bet slips with the community |
Search functionality to discover users and bets:
| Feature | Description |
|---|---|
| User Search | Search for users by username or display name |
| Profile Access | Quick access to user profiles from search results |
| Follow from Search | Follow/unfollow users directly from search |
Manage social connections:
| Feature | Description |
|---|---|
| Followers List | View users who follow you |
| Following List | View users you follow |
| Follow Management | Follow/unfollow from the lists |
| Profile Navigation | Navigate to user profiles from lists |
Stay updated with community activity:
| Feature | Description |
|---|---|
| Bet Share Notifications | Notifications when users you follow share bets |
| Comment Notifications | Notifications for comments on your shared bets |
| Social Notifications | Notifications for new followers |
| Read/Unread States | Visual indicators for new notifications |
Complete bet sharing experience:
First-time user experience:
The Central Hub manages its own internal navigation:
Central Hub Entry
├── Onboarding (first-time users only)
│
├── My Profile Tab
│ ├── Edit Profile
│ ├── View Followers
│ ├── View Following
| └── View Notifications
│
├── Bets Tab
│ ├── Bet Details & Comments
│ ├── React to Bets
│ └── Copy Bet
│ └── Share Bet Flow
│ ├── Bet Selection
│ └── Share Confirmation
│
├── Other User Profile
│ ├── Follow/Unfollow
│ ├── View Shared Bets
│ └── View Followers/Following
│
├── Search
│ └── User Profiles
│
└── Notifications
├── Bet Share Notifications
├── Comment Notifications
└── Social NotificationsAll navigation is handled internally by the Central Hub component. The only navigation callback is onBack, which is triggered when users want to exit the Central Hub.
The Central Hub can be extensively customized through the CentralHubUISettings data class. This allows you to match the component's appearance to your app's design system.
Control all color aspects of the Central Hub through CentralHubThemeSettings:
Use your app's font family throughout the Central Hub:
CentralHubUISettings(
fontFamily = myCustomFontFamily
)Additional customization options for behavior and appearance through CentralHubOtherSettings.
Custom Theme Example:
import ag.sportradar.virtualstadium.uisdk.settings.*
import androidx.compose.ui.graphics.Color
val customTheme = CentralHubThemeSettings(
// Core background
background = Color(0xFFF5F5F5),
// Screen-specific colors
onboardingScreenColors = CentralHubOnboardingScreenColors(
// ... customize onboarding colors
),
followersScreenColors = FollowersScreenColors(
// ... customize followers screen colors
),
myHubScreenColors = MyHubScreenColors(
// ... customize my profile screen colors
),
commentingScreenColors = CentralHubCommentingScreenColors(
// ... customize commenting screen colors
),
betShareNotificationsScreenColors = BetShareNotificationsScreenColors(
// ... customize notifications screen colors
),
betsScreenColors = CentralHubBetsColors(
// ... customize bets feed colors
),
searchScreenColors = CentralHubSearchScreenColors(
// ... customize search screen colors
),
// Toast colors
errorToastColors = CentralHubErrorToastColors(
// ... customize error toast colors
),
successToastColors = CentralHubSuccessToastColors(
// ... customize success toast colors
),
// Component colors
cardColors = CentralHubCardsColors(
background = Color.White,
border = Color(0xFFE0E0E0),
// ... other card properties
),
buttonColors = CentralHubButtonsColors(
primaryBackground = Color(0xFF1976D2),
primaryContent = Color.White,
// ... other button properties
),
headerColors = ProfileHeaderColors(
// ... customize profile header colors
),
userStatisticColors = CentralHubProfileStatColors(
// ... customize user statistics colors
),
topBarColors = CentralHubTopBarColors(
background = Color.White,
titleColor = Color.Black,
// ... other top bar properties
),
tabsColors = CentralHubTabsColors(
selectedColor = Color(0xFF1976D2),
unselectedColor = Color.Gray,
// ... other tab properties
),
searchBarColors = CentralHubSearchBarColors(
// ... customize search bar colors
),
alreadyReadDividerColors = CentralHubAlreadyReadDividerColors(
// ... customize read/unread divider colors
),
reactionsColors = CentralHubReactionsColors(
// ... customize reaction colors
),
userHeaderColors = CentralHubUserHeaderColors(
// ... customize user header colors
),
badgeColors = CentralHubBadgeColors(
// ... customize badge colors
),
switchColors = CentralHubSwitchColors(
// ... customize switch colors
),
bottomSheetColors = CentralHubBottomSheetColors(
// ... customize bottom sheet colors
),
betSlipColors = BetSlipColors(
// ... customize bet slip colors
),
loadingIndicatorColors = CentralHubLoadingIndicatorColor(
color = Color(0xFF1976D2)
)
)
val customUISettings = CentralHubUISettings(
theme = customTheme,
fontFamily = myCustomFontFamily,
otherSettings = CentralHubOtherSettings()
)
// Use in CentralHub
CentralHub(
jwtToken = jwtToken,
userId = userId,
uiSettings = customUISettings,
onBack = { /* ... */ }
)To enable bet sharing, provide the onGetBets callback that returns your user's bet slips. The Central Hub will display these bets in a selection screen where users can choose which bet to share.
The BetPayload model represents a bet slip that can be shared and copied. Ensure your bet data is properly mapped to this structure.
Key Requirements:
The same BetPayload structure is used for both sharing bets and copying bets via the onCopyToBetSlip callback.
Bet Sharing Implementation:
import ag.sportradar.virtualstadium.datasdk.model.*
import kotlinx.coroutines.delay
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CentralHub(
jwtToken = jwtToken,
userId = userId,
// Provide user's bet slips for sharing
onGetBets = {
// Fetch user's current bet slips
val myBets = fetchUserBetSlips()
// Map to BetPayload format
myBets.map { bet ->
BetPayload(
id = bet.id,
betType = bet.type,
selections = bet.selections.map { selection ->
Selection(
eventId = selection.eventId,
marketId = selection.marketId,
outcomeId = selection.outcomeId,
eventName = selection.eventName,
marketName = selection.marketName,
outcomeName = selection.outcomeName,
odds = selection.odds
)
},
stake = bet.stake,
totalOdds = bet.totalOdds,
potentialWin = bet.potentialWin,
timestamp = bet.createdAt
)
}
},
// Handle bet copying
onCopyToBetSlip = { copiedBet ->
// Add the copied bet to user's bet slip
addToBetSlip(copiedBet)
// Show confirmation
showToast("Bet copied to slip!")
},
onBack = { finish() }
)
}
}
private suspend fun fetchUserBetSlips(): List<MyBet> {
// TODO: Implement your bet fetching logic
return emptyList()
}
private fun addToBetSlip(bet: BetPayload) {
// TODO: Implement bet slip logic
}
}When using Android Views, properly manage the Central Hub lifecycle to clean up resources when users log out or the view is destroyed.
Call destroy() on the CentralHubView when:
This method clears all user data, logs out from the SDK, and resets the component state.
Always call destroy() when logging out users to ensure data is properly cleared and prevent data leakage.
Lifecycle Management - Views:
class MainActivity : ComponentActivity() {
private lateinit var centralHubView: CentralHubView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
centralHubView = findViewById(R.id.central_hub_view)
centralHubView.init(
jwtToken = jwtToken,
userId = userId,
onBack = { finish() }
)
}
// Handle user logout
fun onUserLogout() {
// Clean up Central Hub data
centralHubView.destroy()
// Navigate to login screen
navigateToLogin()
}
override fun onDestroy() {
super.onDestroy()
// Clean up when activity is destroyed
if (isFinishing) {
centralHubView.destroy()
}
}
}Lifecycle Management - Compose:
// For Compose, lifecycle is handled automatically
// when the Composable leaves composition
@Composable
fun MyScreen() {
var showCentralHub by remember { mutableStateOf(true) }
if (showCentralHub) {
CentralHub(
jwtToken = jwtToken,
userId = userId,
onBack = { showCentralHub = false }
)
}
// Central Hub is automatically cleaned up
// when showCentralHub becomes false
}Complete Central Hub Integration Example:
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
import ag.sportradar.virtualstadium.uisdk.composables.CentralHub
import ag.sportradar.virtualstadium.uisdk.settings.*
import ag.sportradar.virtualstadium.datasdk.model.BetPayload
import kotlinx.coroutines.launch
class CentralHubActivity : ComponentActivity() {
private val viewModel: BettingViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
val jwtToken = viewModel.jwtToken.collectAsState()
val userId = viewModel.userId.collectAsState()
val scope = rememberCoroutineScope()
// Custom theme matching your app
val customUISettings = remember {
CentralHubUISettings(
theme = CentralHubThemeSettings(
background = Color(0xFFF5F5F5),
buttonColors = CentralHubButtonsColors(
primaryBackground = Color(0xFF1976D2),
primaryContent = Color.White
),
loadingIndicatorColors = CentralHubLoadingIndicatorColor(
color = Color(0xFF1976D2)
)
),
fontFamily = yourCustomFontFamily
)
}
CentralHub(
jwtToken = jwtToken.value,
userId = userId.value,
modifier = Modifier.fillMaxSize(),
uiSettings = customUISettings,
onGetBets = {
// Fetch user's bet slips
viewModel.getUserBetSlips()
},
onCopyToBetSlip = { betPayload ->
// Add to bet slip
scope.launch {
viewModel.addBetToSlip(betPayload)
showToast("Bet copied to slip!")
}
},
onBack = {
// Handle back navigation
finish()
}
)
}
}
private fun showToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}