Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.animation.samples

import androidx.annotation.Sampled
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.CustomizedLookaheadAnimationVisualDebugging
import androidx.compose.animation.ExperimentalLookaheadAnimationVisualDebugApi
import androidx.compose.animation.LookaheadAnimationVisualDebugging
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalLookaheadAnimationVisualDebugApi::class)
@Sampled
@Composable
fun LookaheadAnimationVisualDebuggingSample() {
var isExpanded by mutableStateOf(false)
// Wrap content with LookaheadAnimationVisualDebugging to enable visual debugging.
// Optional parameters allow color customization and decision of whether to show key labels.
// Note that enabling LookaheadAnimationVisualDebugging affects the entire UI subtree generated
// by the content lambda. It applies to all descendants, regardless of whether they are defined
// within the same lexical scope.
LookaheadAnimationVisualDebugging(isShowKeyLabelEnabled = true) {
SharedTransitionLayout(Modifier.fillMaxSize().clickable { isExpanded = !isExpanded }) {
AnimatedVisibility(visible = isExpanded) {
Box(
Modifier.offset(100.dp, 100.dp)
.size(200.dp)
.sharedElement(
rememberSharedContentState(key = "box"),
animatedVisibilityScope = this,
)
.background(Color.Red)
)
}
AnimatedVisibility(visible = !isExpanded) {
Box(
Modifier.offset(0.dp, 0.dp)
.size(50.dp)
.sharedElement(
rememberSharedContentState(key = "box"),
animatedVisibilityScope = this,
)
.background(Color.Blue)
)
}
}
}
}

@OptIn(ExperimentalLookaheadAnimationVisualDebugApi::class)
@Sampled
@Composable
fun CustomizedLookaheadAnimationVisualDebuggingSample() {
var isExpanded by mutableStateOf(false)
// Wrap content with LookaheadAnimationVisualDebugging to enable visual debugging.
// Optional parameters allow color customization and decision of whether to show key labels.
// Note that enabling LookaheadAnimationVisualDebugging affects the entire UI subtree generated
// by the content lambda. It applies to all descendants, regardless of whether they are defined
// within the same lexical scope.
LookaheadAnimationVisualDebugging {
// Wrap content with CustomizedLookaheadAnimationVisualDebugging to customize the color of
// the bounds visualizations in the specified scope.
CustomizedLookaheadAnimationVisualDebugging(Color.Black) {
SharedTransitionLayout(Modifier.fillMaxSize().clickable { isExpanded = !isExpanded }) {
AnimatedVisibility(visible = isExpanded) {
Box(
Modifier.offset(100.dp, 100.dp)
.size(200.dp)
.sharedElement(
rememberSharedContentState(key = "box"),
animatedVisibilityScope = this,
)
.background(Color.Red)
)
}
AnimatedVisibility(visible = !isExpanded) {
Box(
Modifier.offset(0.dp, 0.dp)
.size(50.dp)
.sharedElement(
rememberSharedContentState(key = "box"),
animatedVisibilityScope = this,
)
.background(Color.Blue)
)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,10 @@ internal class LookaheadAnimationVisualDebugHelper() {
}

/**
* Allows enabling and customizing shared element and animated bounds animation debugging.
* Allows enabling and customizing shared element and animated bounds animation debugging. Note that
* enabling LookaheadAnimationVisualDebugging affects the entire UI subtree generated by the content
* lambda. It applies to all descendants, regardless of whether they are defined within the same
* lexical scope.
*
* @param isEnabled Boolean specifying whether to enable animation debugging.
* @param overlayColor The color of the translucent film covering everything underneath the lifted
Expand All @@ -539,6 +542,10 @@ internal class LookaheadAnimationVisualDebugHelper() {
* @param isShowKeyLabelEnabled Boolean specifying whether to print animated element keys.
* @param content The composable content that debugging visualizations will apply to, although which
* visualizations appear depends on where the Modifiers are placed.
*
* An example of how to use it:
*
* @sample androidx.compose.animation.samples.LookaheadAnimationVisualDebuggingSample
*/
@Composable
@ExperimentalLookaheadAnimationVisualDebugApi
Expand All @@ -564,11 +571,18 @@ public fun LookaheadAnimationVisualDebugging(
}

/**
* Allows customizing a particular shared element or animated bounds animation for debugging.
* Allows customizing a particular shared element or animated bounds animation for debugging. Note
* that enabling CustomizedLookaheadAnimationVisualDebugging affects the entire UI subtree generated
* by the content lambda. It applies to all descendants, regardless of whether they are defined
* within the same lexical scope.
*
* @param debugColor The custom color specified for animation debugging visualizations.
* @param content The composable content that debugging visualizations will apply to, although which
* visualizations appear depends on where the Modifiers are placed.
*
* An example of how to use it:
*
* @sample androidx.compose.animation.samples.CustomizedLookaheadAnimationVisualDebuggingSample
*/
@Composable
@ExperimentalLookaheadAnimationVisualDebugApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,26 @@
package androidx.compose.remote.player.compose

import androidx.annotation.RestrictTo
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.size
import androidx.compose.remote.core.CoreDocument
import androidx.compose.remote.player.compose.impl.RemoteDocumentViewPlayer
import androidx.compose.remote.core.operations.Theme
import androidx.compose.remote.player.core.RemoteDocument
import androidx.compose.remote.player.core.action.NamedActionHandler
import androidx.compose.remote.player.core.action.StateUpdaterActionCallback
import androidx.compose.remote.player.core.platform.BitmapLoader
import androidx.compose.remote.player.core.state.StateUpdater
import androidx.compose.remote.player.view.RemoteComposePlayer
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView

/** A player of a [CoreDocument] */
@Composable
Expand All @@ -40,16 +53,64 @@ public fun RemoteDocumentPlayer(
onNamedAction: (name: String, value: Any?, stateUpdater: StateUpdater) -> Unit = { _, _, _ -> },
bitmapLoader: BitmapLoader? = null,
) {
RemoteDocumentViewPlayer(
document = document,
documentWidth = documentWidth,
documentHeight = documentHeight,
modifier = modifier,
debugMode = debugMode,
init = init,
update = update,
onAction = onAction,
onNamedAction = onNamedAction,
bitmapLoader = bitmapLoader,
var inDarkTheme by remember { mutableStateOf(false) }
var playbackTheme by remember { mutableIntStateOf(Theme.UNSPECIFIED) }

val remoteDoc = remember(document) { RemoteDocument(document) }

inDarkTheme =
when (AppCompatDelegate.getDefaultNightMode()) {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> isSystemInDarkTheme()
AppCompatDelegate.MODE_NIGHT_YES -> true
AppCompatDelegate.MODE_NIGHT_NO -> false
AppCompatDelegate.MODE_NIGHT_UNSPECIFIED -> isSystemInDarkTheme()
else -> {
false
}
}

playbackTheme =
if (inDarkTheme) {
Theme.DARK
} else {
Theme.LIGHT
}

AndroidView(
modifier = modifier.size(documentWidth.dp, documentHeight.dp),
factory = {
RemoteComposePlayer(it).apply {
init(this)
if (bitmapLoader != null) {
setBitmapLoader(bitmapLoader)
}
}
},
update = { remoteComposePlayer ->
remoteComposePlayer.setTheme(playbackTheme)
remoteComposePlayer.setDocument(remoteDoc)
remoteComposePlayer.setDebug(debugMode)
remoteComposePlayer.document.document.clearActionCallbacks()
remoteComposePlayer.document.document.addIdActionListener { id, value ->
onAction.invoke(id, value)
}
remoteComposePlayer.document.document.addActionCallback(
object :
StateUpdaterActionCallback(
remoteComposePlayer.stateUpdater,
object : NamedActionHandler {
override fun execute(
name: String,
value: Any?,
stateUpdater: StateUpdater,
) {
onNamedAction.invoke(name, value, stateUpdater)
}
},
) {}
)
// use
update(remoteComposePlayer)
},
)
}

This file was deleted.

1 change: 1 addition & 0 deletions docs-tip-of-tree/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ dependencies {
docs(project(":resourceinspection:resourceinspection-annotation"))
kmpDocs(project(":room3:room3-common"))
docs(project(":room3:room3-guava"))
docs(project(":room3:room3-livedata"))
kmpDocs(project(":room3:room3-migration"))
kmpDocs(project(":room3:room3-paging"))
docs(project(":room3:room3-paging-guava"))
Expand Down
1 change: 1 addition & 0 deletions room3/integration-tests/kotlintestapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ tasks.withType(KotlinCompilationTask).configureEach {
dependencies {
implementation(project(":room3:room3-common"))
implementation(project(":room3:room3-runtime"))
implementation(project(":room3:room3-livedata"))
implementation(project(":room3:room3-paging"))
implementation(project(":room3:room3-sqlite-wrapper"))
implementation(project(":paging:paging-runtime"))
Expand Down
Loading