Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content transition api & predictive back example #125

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions example/app/composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.CAMERA"/>

<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".MainApplication"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
android:enableOnBackInvokedCallback="true"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleInstance"
android:configChanges="screenSize|screenLayout|orientation">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.VIEW"/>

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>

<data
android:host="deeplink"
android:scheme="tiamat" />
android:scheme="tiamat"/>
</intent-filter>
</activity>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package composegears.tiamat.example
import android.app.Application
import composegears.tiamat.example.extra.A3rdParty
import composegears.tiamat.example.platform.Platform
import composegears.tiamat.example.platform.start

class MainApplication : Application() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.composegears.tiamat.LocalNavBackHandler
import composegears.tiamat.example.content.App
import composegears.tiamat.example.extra.A3rdParty
import composegears.tiamat.example.platform.Platform
import composegears.tiamat.example.platform.start

@OptIn(ExperimentalFoundationApi::class)
fun main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.composegears.tiamat.*
import composegears.tiamat.example.content.App
import composegears.tiamat.example.extra.A3rdParty
import composegears.tiamat.example.platform.Platform
import composegears.tiamat.example.platform.start
import composegears.tiamat.example.ui.core.LocalScreenHandler
import composegears.tiamat.example.ui.core.ScreenInfo
import kotlinx.browser.window
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.composegears.tiamat.NavController
import com.composegears.tiamat.Navigation
import com.composegears.tiamat.StorageMode
import com.composegears.tiamat.rememberNavController
import com.composegears.tiamat.*
import composegears.tiamat.example.content.content.HomeScreen
import composegears.tiamat.example.content.content.advanced.AdvBackStackAlteration
import composegears.tiamat.example.content.content.advanced.AdvExtensions
import composegears.tiamat.example.content.content.advanced.AdvSharedElementTransition
import composegears.tiamat.example.content.content.apr.APRFreeArgs
import composegears.tiamat.example.content.content.apr.APRNavArgs
import composegears.tiamat.example.content.content.apr.APRNavResult
Expand All @@ -19,6 +17,7 @@ import composegears.tiamat.example.content.content.architecture.ArchViewModel
import composegears.tiamat.example.content.content.navigation.*
import composegears.tiamat.example.extra.A3rdParty
import composegears.tiamat.example.platform.Platform
import composegears.tiamat.example.platform.features
import composegears.tiamat.example.ui.core.AppTheme

@Composable
Expand Down Expand Up @@ -48,13 +47,18 @@ fun App(
ArchCustomSaveState,
AdvExtensions,
AdvBackStackAlteration,
AdvSharedElementTransition,
*(Platform.features() + A3rdParty.features())
.map { it.destination }
.toTypedArray()
),
configuration = navControllerConfig
)
Navigation(rootNavController, Modifier.fillMaxSize())
Navigation(
navController = rootNavController,
modifier = Modifier.fillMaxSize(),
contentTransformProvider = { navigationPlatformDefault(it) }
)
overlay(rootNavController)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.composegears.tiamat.navController
import com.composegears.tiamat.navDestination
import composegears.tiamat.example.content.content.advanced.AdvBackStackAlteration
import composegears.tiamat.example.content.content.advanced.AdvExtensions
import composegears.tiamat.example.content.content.advanced.AdvSharedElementTransition
import composegears.tiamat.example.content.content.apr.APRFreeArgs
import composegears.tiamat.example.content.content.apr.APRNavArgs
import composegears.tiamat.example.content.content.apr.APRNavResult
Expand All @@ -39,6 +40,8 @@ import composegears.tiamat.example.content.content.architecture.ArchViewModel
import composegears.tiamat.example.content.content.navigation.*
import composegears.tiamat.example.extra.A3rdParty
import composegears.tiamat.example.platform.Platform
import composegears.tiamat.example.platform.features
import composegears.tiamat.example.platform.name
import composegears.tiamat.example.ui.core.*

private val HomeItems =
Expand Down Expand Up @@ -127,6 +130,11 @@ private val HomeItems =
description = "Example shows how to use nav-destination extensions (eg: Analytics tracking)",
destination = AdvExtensions
),
AppFeature(
name = "Shared element transition",
description = "Example shows how to use shared element transition",
destination = AdvSharedElementTransition
),
),
),
HomeItem(
Expand All @@ -144,7 +152,10 @@ private val HomeItems =
val HomeScreen: NavDestination<Unit> by navDestination(ScreenInfo("Home")) {
val navController = navController()
Box(
modifier = Modifier.fillMaxSize().systemBarsPadding(),
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surface)
.systemBarsPadding(),
contentAlignment = Alignment.Center
) {
var selectedItem by rememberSaveable { mutableStateOf<String?>(null) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package composegears.tiamat.example.content.content.advanced

import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.composegears.tiamat.*
import composegears.tiamat.example.ui.core.*

@OptIn(ExperimentalSharedTransitionApi::class)
private val LocalSharedTransitionScope = staticCompositionLocalOf<SharedTransitionScope> { error("No scope provided") }

@OptIn(ExperimentalSharedTransitionApi::class)
val AdvSharedElementTransition by navDestination<Unit>(ScreenInfo()) {
Screen("SharedElementTransition") {
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
val nc = rememberNavController(
key = "SharedElementTransition nav controller",
startDestination = AdvSharedElementTransitionScreen1,
destinations = arrayOf(
AdvSharedElementTransitionScreen1,
AdvSharedElementTransitionScreen2,
AdvSharedElementTransitionScreen3,
)
)
SharedTransitionLayout {
CompositionLocalProvider(
LocalSharedTransitionScope provides this
) {
Navigation(
navController = nc,
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
.border(1.dp, MaterialTheme.colorScheme.outlineVariant, RoundedCornerShape(8.dp))
.padding(16.dp),
contentTransformProvider = { navigationSlideInOut(it) }
)
}
}
}
}
}

@OptIn(ExperimentalSharedTransitionApi::class)
private val AdvSharedElementTransitionScreen1 by navDestination<Unit> {
val nc = navController()
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Screen 1", style = MaterialTheme.typography.headlineMedium)
VSpacer()
with(LocalSharedTransitionScope.current) {
Text(
"This is SHARED element on screen 1",
modifier = Modifier
.sharedElement(
state = rememberSharedContentState("element"),
animatedVisibilityScope = this@navDestination,
)
.renderInSharedTransitionScopeOverlay()
.animateEnterExit()
.background(Color.Green.copy(alpha = 0.3f))
.padding(16.dp),
style = MaterialTheme.typography.bodyLarge
)
}
VSpacer()
AppButton(
"Next",
endIcon = Icons.AutoMirrored.Default.KeyboardArrowRight,
onClick = { nc.navigate(AdvSharedElementTransitionScreen2) }
)
}
}
}

@OptIn(ExperimentalSharedTransitionApi::class)
private val AdvSharedElementTransitionScreen2 by navDestination<Unit> {
val nc = navController()
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Screen 2", style = MaterialTheme.typography.headlineMedium)
VSpacer()
with(LocalSharedTransitionScope.current) {
Text(
"This is SHARED element on screen 2",
modifier = Modifier
.sharedElement(
state = rememberSharedContentState("element"),
animatedVisibilityScope = this@navDestination,
)
.renderInSharedTransitionScopeOverlay()
.animateEnterExit()
.background(Color.Red.copy(alpha = 0.3f))
.padding(16.dp),
style = MaterialTheme.typography.bodyLarge
)
}
VSpacer()
Row {
AppButton(
"Back",
startIcon = Icons.AutoMirrored.Default.KeyboardArrowLeft,
onClick = { nc.back() }
)
HSpacer()
AppButton(
"Next",
endIcon = Icons.AutoMirrored.Default.KeyboardArrowRight,
onClick = { nc.navigate(AdvSharedElementTransitionScreen3) }
)
}
}
}
}

@OptIn(ExperimentalSharedTransitionApi::class)
private val AdvSharedElementTransitionScreen3 by navDestination<Unit> {
val nc = navController()
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Screen 3", style = MaterialTheme.typography.headlineMedium)
VSpacer()
with(LocalSharedTransitionScope.current) {
Text(
"This is SHARED element on screen 3",
modifier = Modifier
.sharedElement(
state = rememberSharedContentState("element"),
animatedVisibilityScope = this@navDestination,
)
.renderInSharedTransitionScopeOverlay()
.animateEnterExit()
.background(Color.Blue.copy(alpha = 0.3f))
.padding(16.dp),
style = MaterialTheme.typography.bodyLarge
)
}
VSpacer()
AppButton(
"Back",
startIcon = Icons.AutoMirrored.Default.KeyboardArrowLeft,
onClick = { nc.back() }
)
}
}
}
3 changes: 3 additions & 0 deletions example/platform/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@ kotlin {
implementation(projects.tiamat)
implementation(projects.example.uiCore)
}
androidMain.dependencies {
implementation(libs.androidx.activity.compose)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ package composegears.tiamat.example.platform

import composegears.tiamat.example.ui.core.AppFeature

actual object Platform {
actual fun start() = Unit
actual fun name(): String = "Android"
actual fun features(): List<AppFeature> = emptyList()
}
actual fun Platform.start() = Unit
actual fun Platform.name(): String = "Android"
actual fun Platform.platformFeatures(): List<AppFeature> = emptyList()
Loading