From a8928d9acdda3c47fe99d14f48503dfe5b4a1710 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Mon, 23 Dec 2024 16:08:31 +0000 Subject: [PATCH] [Sample] Hook up back button on Android --- .../haze/sample/android/ExoPlayerSample.kt | 14 ++++---- .../haze/sample/android/MainActivity.kt | 8 +++++ .../dev/chrisbanes/haze/sample/Navigator.kt | 24 +++++++++++++ .../dev/chrisbanes/haze/sample/Samples.kt | 35 +++---------------- 4 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Navigator.kt diff --git a/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/ExoPlayerSample.kt b/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/ExoPlayerSample.kt index 17ca2ed9..6785fb3d 100644 --- a/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/ExoPlayerSample.kt +++ b/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/ExoPlayerSample.kt @@ -55,12 +55,11 @@ fun ExoPlayerSample(navigator: Navigator) { AndroidView( factory = { ctx -> // For Haze to work with video players, they need to be configured to use a TextureView. - // For ExoPlayer that needs to be done via a layout file. - val view = LayoutInflater.from(ctx) - .inflate(R.layout.exoplayer, null) as PlayerView - view.apply { - player = exoPlayer - } + // When using ExoPlayer's PlayerView, that needs to be done via a layout attribute. + LayoutInflater.from(ctx).inflate(R.layout.exoplayer, null) as PlayerView + }, + update = { playerView -> + playerView.player = exoPlayer }, modifier = Modifier .fillMaxSize() @@ -77,4 +76,5 @@ fun ExoPlayerSample(navigator: Navigator) { } } -private const val BIG_BUCK_BUNNY = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" +private const val BIG_BUCK_BUNNY = + "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" diff --git a/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/MainActivity.kt b/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/MainActivity.kt index b1b3126c..6d76cf3c 100644 --- a/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/MainActivity.kt +++ b/sample/android/src/main/kotlin/dev/chrisbanes/haze/sample/android/MainActivity.kt @@ -5,8 +5,11 @@ package dev.chrisbanes.haze.sample.android import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.compose.runtime.remember +import dev.chrisbanes.haze.sample.Navigator import dev.chrisbanes.haze.sample.Sample import dev.chrisbanes.haze.sample.Samples @@ -16,8 +19,13 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { + val navigator = remember { Navigator() } + + BackHandler { navigator.navigateUp() } + Samples( appTitle = title.toString(), + navigator = navigator, samples = Samples + AndroidSamples, ) } diff --git a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Navigator.kt b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Navigator.kt new file mode 100644 index 00000000..868c442c --- /dev/null +++ b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Navigator.kt @@ -0,0 +1,24 @@ +// Copyright 2024, Christopher Banes and the Haze project contributors +// SPDX-License-Identifier: Apache-2.0 + +package dev.chrisbanes.haze.sample + +import androidx.compose.runtime.mutableStateListOf + +class Navigator { + + private val backStack = mutableStateListOf() + + val currentSample: Sample? + get() = backStack.lastOrNull() + + fun navigateTo(sample: Sample) { + backStack.add(sample) + } + + fun navigateUp() { + if (backStack.isNotEmpty()) { + backStack.removeLast() + } + } +} diff --git a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt index bc4cd3ee..69a0c69f 100644 --- a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt +++ b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt @@ -10,11 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold @@ -24,10 +20,7 @@ import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import coil3.ImageLoader @@ -61,10 +54,6 @@ data class Sample( val content: @Composable (Navigator) -> Unit, ) -fun interface Navigator { - fun navigateUp() -} - @Composable fun SamplesTheme( useDarkColors: Boolean = isSystemInDarkTheme(), @@ -80,6 +69,7 @@ fun SamplesTheme( @Composable fun Samples( appTitle: String, + navigator: Navigator = remember { Navigator() }, samples: List = Samples, ) { setSingletonImageLoaderFactory { context -> @@ -111,14 +101,8 @@ fun Samples( } SamplesTheme { - var currentSample by remember { mutableStateOf(null) } - - val navigator = remember { - Navigator { currentSample = null } - } - Crossfade( - targetState = currentSample, + targetState = navigator.currentSample, modifier = Modifier.testTagsAsResourceId(true), ) { sample -> if (sample != null) { @@ -127,18 +111,7 @@ fun Samples( Scaffold( topBar = { TopAppBar( - title = { Text(text = currentSample?.title ?: appTitle) }, - navigationIcon = { - if (currentSample != null) { - IconButton(onClick = { currentSample = null }) { - @Suppress("DEPRECATION") - Icon( - imageVector = Icons.Default.ArrowBack, - contentDescription = "Navigate back", - ) - } - } - }, + title = { Text(text = appTitle) }, modifier = Modifier.fillMaxWidth(), ) }, @@ -153,7 +126,7 @@ fun Samples( modifier = Modifier .fillMaxWidth() .testTag(sample.title) - .clickable { currentSample = sample }, + .clickable { navigator.navigateTo(sample) }, ) } }