Implement XR overrides `HorizontalFloatingToolbar` Test: On-device; screenshot in bug Bug: 407769443 Relnote: Implement XR overrides `HorizontalFloatingToolbar` Change-Id: Ia419f09280bdf32355b8bfd449ef692d2c4bca7b
diff --git a/xr/compose/material3/material3/api/current.txt b/xr/compose/material3/material3/api/current.txt index 7e01e75..30540d2 100644 --- a/xr/compose/material3/material3/api/current.txt +++ b/xr/compose/material3/material3/api/current.txt
@@ -26,13 +26,21 @@ } public final class FloatingToolbarKt { + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean expanded, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.material3.FloatingToolbarScrollBehavior? scrollBehavior, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? trailingContent, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, androidx.compose.material3.FloatingToolbarScrollBehavior?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional int floatingActionButtonPosition, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar-9EbMwro(boolean, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, int, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean expanded, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.material3.FloatingToolbarScrollBehavior? scrollBehavior, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? trailingContent, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content); method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, androidx.compose.material3.FloatingToolbarScrollBehavior?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional int floatingActionButtonPosition, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content); method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar-VUyBcCc(boolean, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, int, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); + method public static androidx.xr.compose.material3.HorizontalOrbiterProperties getDefaultHorizontalFloatingToolbarOrbiterProperties(); method public static androidx.xr.compose.material3.VerticalOrbiterProperties getDefaultVerticalFloatingToolbarOrbiterProperties(); + method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.HorizontalOrbiterProperties> getLocalHorizontalFloatingToolbarOrbiterProperties(); method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.VerticalOrbiterProperties> getLocalVerticalFloatingToolbarOrbiterProperties(); + property public static androidx.xr.compose.material3.HorizontalOrbiterProperties DefaultHorizontalFloatingToolbarOrbiterProperties; property public static androidx.xr.compose.material3.VerticalOrbiterProperties DefaultVerticalFloatingToolbarOrbiterProperties; + property public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.HorizontalOrbiterProperties> LocalHorizontalFloatingToolbarOrbiterProperties; property public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.VerticalOrbiterProperties> LocalVerticalFloatingToolbarOrbiterProperties; } @@ -113,6 +121,7 @@ public static final class XrComponentOverride.Companion { method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getBasicAlertDialog-sKf2Msg(); + method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getHorizontalFloatingToolbar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationBar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationRail-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationSuiteScaffold-sKf2Msg(); @@ -122,6 +131,7 @@ method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getTwoRowsTopAppBar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getVerticalFloatingToolbar-sKf2Msg(); property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride BasicAlertDialog; + property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride HorizontalFloatingToolbar; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationBar; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationRail; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationSuiteScaffold;
diff --git a/xr/compose/material3/material3/api/restricted_current.txt b/xr/compose/material3/material3/api/restricted_current.txt index 7e01e75..30540d2 100644 --- a/xr/compose/material3/material3/api/restricted_current.txt +++ b/xr/compose/material3/material3/api/restricted_current.txt
@@ -26,13 +26,21 @@ } public final class FloatingToolbarKt { + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean expanded, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.material3.FloatingToolbarScrollBehavior? scrollBehavior, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? trailingContent, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, androidx.compose.material3.FloatingToolbarScrollBehavior?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional int floatingActionButtonPosition, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void HorizontalFloatingToolbar-9EbMwro(boolean, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, int, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.RowScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean expanded, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.material3.FloatingToolbarScrollBehavior? scrollBehavior, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? trailingContent, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content); method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, androidx.compose.material3.FloatingToolbarScrollBehavior?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>?, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.FloatingToolbarColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional int floatingActionButtonPosition, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content); method @BytecodeOnly @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3ExpressiveApi @androidx.compose.runtime.Composable @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public static void VerticalFloatingToolbar-VUyBcCc(boolean, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.ui.Modifier?, androidx.compose.material3.FloatingToolbarColors?, androidx.compose.foundation.layout.PaddingValues?, int, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.layout.ColumnScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int); + method public static androidx.xr.compose.material3.HorizontalOrbiterProperties getDefaultHorizontalFloatingToolbarOrbiterProperties(); method public static androidx.xr.compose.material3.VerticalOrbiterProperties getDefaultVerticalFloatingToolbarOrbiterProperties(); + method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.HorizontalOrbiterProperties> getLocalHorizontalFloatingToolbarOrbiterProperties(); method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.VerticalOrbiterProperties> getLocalVerticalFloatingToolbarOrbiterProperties(); + property public static androidx.xr.compose.material3.HorizontalOrbiterProperties DefaultHorizontalFloatingToolbarOrbiterProperties; property public static androidx.xr.compose.material3.VerticalOrbiterProperties DefaultVerticalFloatingToolbarOrbiterProperties; + property public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.HorizontalOrbiterProperties> LocalHorizontalFloatingToolbarOrbiterProperties; property public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.xr.compose.material3.VerticalOrbiterProperties> LocalVerticalFloatingToolbarOrbiterProperties; } @@ -113,6 +121,7 @@ public static final class XrComponentOverride.Companion { method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getBasicAlertDialog-sKf2Msg(); + method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getHorizontalFloatingToolbar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationBar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationRail-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getNavigationSuiteScaffold-sKf2Msg(); @@ -122,6 +131,7 @@ method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getTwoRowsTopAppBar-sKf2Msg(); method @BytecodeOnly @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public String getVerticalFloatingToolbar-sKf2Msg(); property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride BasicAlertDialog; + property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride HorizontalFloatingToolbar; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationBar; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationRail; property @SuppressCompatibility @androidx.xr.compose.material3.ExperimentalMaterial3XrApi public androidx.xr.compose.material3.XrComponentOverride NavigationSuiteScaffold;
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/AppBar.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/AppBar.kt index 89539ad..956867c 100644 --- a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/AppBar.kt +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/AppBar.kt
@@ -16,7 +16,6 @@ package androidx.xr.compose.material3 -import androidx.compose.foundation.shape.CornerSize import androidx.compose.material3.DefaultSingleRowTopAppBarOverride import androidx.compose.material3.DefaultTwoRowsTopAppBarOverride import androidx.compose.material3.ExperimentalMaterial3Api @@ -32,9 +31,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.unit.dp import androidx.xr.compose.material3.XrSingleRowTopAppBarOverride.SingleRowTopAppBar +import androidx.xr.compose.material3.tokens.XrTokens import androidx.xr.compose.spatial.ContentEdge import androidx.xr.compose.spatial.OrbiterOffsetType -import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape /** [SingleRowTopAppBarOverride] that uses the XR-specific [SingleRowTopAppBar]. */ @ExperimentalMaterial3XrApi @@ -62,7 +61,7 @@ offset = XrSingleRowTopAppBarTokens.OrbiterOffset, offsetType = OrbiterOffsetType.InnerEdge, alignment = Alignment.CenterHorizontally, - shape = SpatialRoundedCornerShape(CornerSize(50)), + shape = XrTokens.ContainerShape, ) /** The [HorizontalOrbiterProperties] used by XR [TopAppBar]. */ @@ -99,7 +98,7 @@ offset = XrTwoRowsTopAppBarTokens.OrbiterOffset, offsetType = OrbiterOffsetType.InnerEdge, alignment = Alignment.CenterHorizontally, - shape = SpatialRoundedCornerShape(CornerSize(50)), + shape = XrTokens.ContainerShape, ) /** The [HorizontalOrbiterProperties] used by XR [TopAppBar]. */
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/EnableXrComponentOverrides.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/EnableXrComponentOverrides.kt index 3ab26d7..5d21cde 100644 --- a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/EnableXrComponentOverrides.kt +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/EnableXrComponentOverrides.kt
@@ -20,6 +20,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ComponentOverrideApi import androidx.compose.material3.LocalBasicAlertDialogOverride +import androidx.compose.material3.LocalHorizontalFloatingToolbarOverride +import androidx.compose.material3.LocalHorizontalFloatingToolbarWithFabOverride import androidx.compose.material3.LocalNavigationBarOverride import androidx.compose.material3.LocalNavigationRailOverride import androidx.compose.material3.LocalShortNavigationBarOverride @@ -106,6 +108,19 @@ add(LocalBasicAlertDialogOverride provides XrBasicAlertDialogOverride) } + if ( + context.shouldOverrideComponent(XrComponentOverride.HorizontalFloatingToolbar) + ) { + add( + LocalHorizontalFloatingToolbarOverride provides + XrHorizontalFloatingToolbarOverride + ) + add( + LocalHorizontalFloatingToolbarWithFabOverride provides + XrHorizontalFloatingToolbarWithFabOverride + ) + } + if (context.shouldOverrideComponent(XrComponentOverride.VerticalFloatingToolbar)) { add(LocalVerticalToolbarOverride provides XrVerticalFloatingToolbarOverride) add( @@ -185,6 +200,11 @@ @ExperimentalMaterial3XrApi public val VerticalFloatingToolbar: XrComponentOverride = XrComponentOverride("VerticalFloatingToolbar") + + /** Material Expressive VerticalFloatingToolbar. */ + @ExperimentalMaterial3XrApi + public val HorizontalFloatingToolbar: XrComponentOverride = + XrComponentOverride("HorizontalFloatingToolbar") } }
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/FloatingToolbar.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/FloatingToolbar.kt index 7612770..1da9015 100644 --- a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/FloatingToolbar.kt +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/FloatingToolbar.kt
@@ -18,25 +18,35 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3ComponentOverrideApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FloatingToolbarColors import androidx.compose.material3.FloatingToolbarDefaults +import androidx.compose.material3.FloatingToolbarDefaults.horizontalEnterTransition +import androidx.compose.material3.FloatingToolbarDefaults.horizontalExitTransition import androidx.compose.material3.FloatingToolbarDefaults.verticalEnterTransition import androidx.compose.material3.FloatingToolbarDefaults.verticalExitTransition +import androidx.compose.material3.FloatingToolbarHorizontalFabPosition import androidx.compose.material3.FloatingToolbarScrollBehavior import androidx.compose.material3.FloatingToolbarVerticalFabPosition +import androidx.compose.material3.HorizontalFloatingToolbarOverride +import androidx.compose.material3.HorizontalFloatingToolbarOverrideScope +import androidx.compose.material3.HorizontalFloatingToolbarWithFabOverride +import androidx.compose.material3.HorizontalFloatingToolbarWithFabOverrideScope import androidx.compose.material3.LocalContentColor import androidx.compose.material3.VerticalFloatingToolbarOverride import androidx.compose.material3.VerticalFloatingToolbarOverrideScope @@ -54,10 +64,159 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.xr.compose.material3.XrVerticalFloatingToolbarOverride.VerticalFloatingToolbar import androidx.xr.compose.material3.XrVerticalFloatingToolbarTokens.ContainerWidth +import androidx.xr.compose.material3.tokens.XrTokens import androidx.xr.compose.spatial.ContentEdge import androidx.xr.compose.spatial.OrbiterOffsetType -import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape + +/** + * A horizontal floating toolbar displays navigation and key actions in a [Row]. It can be + * positioned anywhere on the screen and floats over the rest of the content. + * + * @param expanded whether the FloatingToolbar is in expanded mode, i.e. showing [leadingContent] + * and [trailingContent]. Note that the toolbar will stay expanded in case a touch exploration + * service (e.g., TalkBack) is active. + * @param modifier the [Modifier] to be applied to this FloatingToolbar. + * @param colors the colors used for this floating toolbar. There are two predefined + * [FloatingToolbarColors] at [FloatingToolbarDefaults.standardFloatingToolbarColors] and + * [FloatingToolbarDefaults.vibrantFloatingToolbarColors] which you can use or modify. + * @param contentPadding the padding applied to the content of this FloatingToolbar. + * @param scrollBehavior a [FloatingToolbarScrollBehavior]. If null, this FloatingToolbar will not + * automatically react to scrolling. + * @param leadingContent the leading content of this FloatingToolbar. The default layout here is a + * [Row], so content inside will be placed horizontally. Only showing if [expanded] is true. + * @param trailingContent the trailing content of this FloatingToolbar. The default layout here is a + * [Row], so content inside will be placed horizontally. Only showing if [expanded] is true. + * @param content the main content of this FloatingToolbar. The default layout here is a [Row], so + * content inside will be placed horizontally. + * + * TODO(kmost): Add a @sample tag and create a new sample project for XR. + */ +@ExperimentalMaterial3XrApi +@ExperimentalMaterial3ExpressiveApi +@Composable +public fun HorizontalFloatingToolbar( + expanded: Boolean, + modifier: Modifier = Modifier, + colors: FloatingToolbarColors = FloatingToolbarDefaults.standardFloatingToolbarColors(), + contentPadding: PaddingValues = FloatingToolbarDefaults.ContentPadding, + scrollBehavior: FloatingToolbarScrollBehavior? = null, + leadingContent: @Composable (RowScope.() -> Unit)? = null, + trailingContent: @Composable (RowScope.() -> Unit)? = null, + content: @Composable RowScope.() -> Unit, +) { + val expandedState by rememberUpdatedState(expanded) + HorizontalOrbiter(LocalHorizontalFloatingToolbarOrbiterProperties.current) { + Row( + modifier = + Modifier.then( + scrollBehavior?.let { with(it) { Modifier.floatingScrollBehavior() } } + ?: Modifier + ) + .heightIn(min = XrHorizontalFloatingToolbarTokens.ContainerHeight) + .background(color = colors.toolbarContainerColor) + .padding(contentPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { + CompositionLocalProvider(LocalContentColor provides colors.toolbarContentColor) { + leadingContent?.let { + AnimatedVisibility( + visible = expandedState, + enter = horizontalEnterTransition(expandFrom = Alignment.End), + exit = horizontalExitTransition(shrinkTowards = Alignment.End), + ) { + Row(content = it) + } + } + Row(content = content) + trailingContent?.let { + AnimatedVisibility( + visible = expandedState, + enter = horizontalEnterTransition(expandFrom = Alignment.End), + exit = horizontalExitTransition(shrinkTowards = Alignment.End), + ) { + Row(content = it) + } + } + } + } + } +} + +/** + * A floating toolbar that displays horizontally. The bar features its content within a [Row], and + * an adjacent floating icon button. It can be positioned anywhere on the screen, floating above + * other content, and even in a `Scaffold`'s floating action button slot. Its [expanded] flag + * controls the visibility of the actions with a slide animations. + * + * Note: This component will stay expanded to maintain the toolbar visibility for users with touch + * exploration services enabled (e.g., TalkBack). + * + * In case the toolbar is aligned to the right or the left of the screen, you may apply a + * [FloatingToolbarDefaults.floatingToolbarVerticalNestedScroll] `Modifier` to update the [expanded] + * state when scrolling occurs, as this sample shows: + * + * @sample androidx.compose.material3.samples.HorizontalFloatingToolbarWithFabSample + * + * Note that if your app uses a `Snackbar`, it's best to position the toolbar in a `Scaffold`'s FAB + * slot. This ensures the `Snackbar` appears above the toolbar, preventing any visual overlap or + * interference. See this sample: + * + * @sample androidx.compose.material3.samples.HorizontalFloatingToolbarAsScaffoldFabSample + * @param expanded whether the floating toolbar is expanded or not. In its expanded state, the FAB + * and the toolbar content are organized horizontally. Otherwise, only the FAB is visible. + * @param floatingActionButton a floating action button to be displayed by the toolbar. It's + * recommended to use a [FloatingToolbarDefaults.VibrantFloatingActionButton] or + * [FloatingToolbarDefaults.StandardFloatingActionButton] that is styled to match the [colors]. + * Note that the provided FAB's size is controlled by the floating toolbar and animates according + * to its state. In case a custom FAB is provided, make sure it's set with a + * [Modifier.fillMaxSize] to be sized correctly. + * @param modifier the [Modifier] to be applied to this floating toolbar. + * @param colors the colors used for this floating toolbar. There are two predefined + * [FloatingToolbarColors] at [FloatingToolbarDefaults.standardFloatingToolbarColors] and + * [FloatingToolbarDefaults.vibrantFloatingToolbarColors] which you can use or modify. See also + * [floatingActionButton] for more information on the right FAB to use for proper styling. + * @param contentPadding the padding applied to the content of this floating toolbar. + * @param floatingActionButtonPosition the position of the floating toolbar's floating action + * button. By default, the FAB is placed at the end of the toolbar (i.e. aligned to the right in + * left-to-right layout, or to the left in right-to-left layout). + * @param content the main content of this floating toolbar. The default layout here is a [Row], so + * content inside will be placed horizontally. + */ +@ExperimentalMaterial3XrApi +@ExperimentalMaterial3ExpressiveApi +@Composable +public fun HorizontalFloatingToolbar( + expanded: Boolean, + floatingActionButton: @Composable () -> Unit, + modifier: Modifier = Modifier, + colors: FloatingToolbarColors = FloatingToolbarDefaults.standardFloatingToolbarColors(), + contentPadding: PaddingValues = FloatingToolbarDefaults.ContentPadding, + floatingActionButtonPosition: FloatingToolbarHorizontalFabPosition = + FloatingToolbarHorizontalFabPosition.End, + content: @Composable RowScope.() -> Unit, +) { + HorizontalOrbiter(LocalHorizontalFloatingToolbarOrbiterProperties.current) { + Row( + modifier = + Modifier.background(colors.toolbarContainerColor) + .padding(contentPadding) + .horizontalScroll(rememberScrollState()) + ) { + CompositionLocalProvider(LocalContentColor provides colors.toolbarContentColor) { + if (floatingActionButtonPosition == FloatingToolbarHorizontalFabPosition.Start) { + Box(Modifier.size(ContainerWidth)) { floatingActionButton() } + } + content() + if (floatingActionButtonPosition == FloatingToolbarHorizontalFabPosition.End) { + Box(Modifier.size(ContainerWidth)) { floatingActionButton() } + } + } + } + } +} /** * XR-specific Vertical Floating Toolbar that displays content in a [Column] in an end-aligned @@ -201,15 +360,71 @@ } } +private object XrHorizontalFloatingToolbarTokens { + val OrbiterOffset = 24.dp + + val ContainerHeight = 64.dp +} + private object XrVerticalFloatingToolbarTokens { val OrbiterOffset = 24.dp val ContainerWidth = 64.dp } +/** [HorizontalFloatingToolbarOverride] that uses the XR-specific [HorizontalFloatingToolbar]. */ +@OptIn( + ExperimentalMaterial3ComponentOverrideApi::class, + ExperimentalMaterial3ExpressiveApi::class, + ExperimentalMaterial3XrApi::class, +) +internal object XrHorizontalFloatingToolbarOverride : HorizontalFloatingToolbarOverride { + @Composable + override fun HorizontalFloatingToolbarOverrideScope.HorizontalFloatingToolbar() { + HorizontalFloatingToolbar( + expanded = isExpanded, + modifier = modifier, + colors = colors, + contentPadding = contentPadding, + scrollBehavior = scrollBehavior, + leadingContent = leadingContent, + trailingContent = trailingContent, + content = content, + ) + } +} + +/** + * [HorizontalFloatingToolbarWithFabOverride] that uses the XR-specific [HorizontalFloatingToolbar], + * with a floating action button (FAB). + */ +@OptIn( + ExperimentalMaterial3ExpressiveApi::class, + ExperimentalMaterial3ComponentOverrideApi::class, + ExperimentalMaterial3XrApi::class, +) +internal object XrHorizontalFloatingToolbarWithFabOverride : + HorizontalFloatingToolbarWithFabOverride { + @Composable + override fun HorizontalFloatingToolbarWithFabOverrideScope.HorizontalFloatingToolbarWithFab() { + HorizontalFloatingToolbar( + expanded = isExpanded, + floatingActionButton = floatingActionButton, + modifier = modifier, + colors = colors, + contentPadding = contentPadding, + floatingActionButtonPosition = floatingActionButtonPosition, + content = content, + ) + } +} + /** [VerticalFloatingToolbarOverride] that uses the XR-specific [VerticalFloatingToolbar]. */ -@ExperimentalMaterial3XrApi -@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3ComponentOverrideApi::class) +@OptIn( + ExperimentalMaterial3ExpressiveApi::class, + ExperimentalMaterial3ComponentOverrideApi::class, + ExperimentalMaterial3XrApi::class, +) internal object XrVerticalFloatingToolbarOverride : VerticalFloatingToolbarOverride { @Composable override fun VerticalFloatingToolbarOverrideScope.VerticalFloatingToolbar() { @@ -229,8 +444,11 @@ * [VerticalFloatingToolbarWithFabOverride] that uses the XR-specific [VerticalFloatingToolbar], * with a floating action button (FAB). */ -@ExperimentalMaterial3XrApi -@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3ComponentOverrideApi::class) +@OptIn( + ExperimentalMaterial3ExpressiveApi::class, + ExperimentalMaterial3ComponentOverrideApi::class, + ExperimentalMaterial3XrApi::class, +) internal object XrVerticalFloatingToolbarWithFabOverride : VerticalFloatingToolbarWithFabOverride { @Composable override fun VerticalFloatingToolbarWithFabOverrideScope.VerticalFloatingToolbarWithFab() { @@ -247,6 +465,28 @@ } /** + * The default [HorizontalOrbiterProperties] used by [HorizontalFloatingToolbar] if none is + * specified in [LocalHorizontalFloatingToolbarOrbiterProperties]. + */ +@OptIn(ExperimentalMaterial3XrApi::class) +public val DefaultHorizontalFloatingToolbarOrbiterProperties: HorizontalOrbiterProperties = + HorizontalOrbiterProperties( + position = ContentEdge.Horizontal.Bottom, + offset = XrHorizontalFloatingToolbarTokens.OrbiterOffset, + offsetType = OrbiterOffsetType.InnerEdge, + alignment = Alignment.CenterHorizontally, + shape = XrTokens.ContainerShape, + ) + +/** The [HorizontalOrbiterProperties] used by [HorizontalFloatingToolbar]. */ +@OptIn(ExperimentalMaterial3XrApi::class) +public val LocalHorizontalFloatingToolbarOrbiterProperties: + ProvidableCompositionLocal<HorizontalOrbiterProperties> = + compositionLocalOf { + DefaultHorizontalFloatingToolbarOrbiterProperties + } + +/** * The default [VerticalOrbiterProperties] used by [VerticalFloatingToolbar] if none is specified in * [LocalVerticalFloatingToolbarOrbiterProperties]. */ @@ -257,7 +497,7 @@ offset = XrVerticalFloatingToolbarTokens.OrbiterOffset, offsetType = OrbiterOffsetType.InnerEdge, alignment = Alignment.CenterVertically, - shape = SpatialRoundedCornerShape(CornerSize(50)), + shape = XrTokens.ContainerShape, ) /** The [VerticalOrbiterProperties] used by [VerticalFloatingToolbar]. */
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationBar.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationBar.kt index 14690fc..6252631 100644 --- a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationBar.kt +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationBar.kt
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.foundation.shape.CornerSize import androidx.compose.material3.ColorScheme import androidx.compose.material3.ExperimentalMaterial3ComponentOverrideApi import androidx.compose.material3.LocalContentColor @@ -43,10 +42,10 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.xr.compose.material3.XrNavigationBarOverride.NavigationBar +import androidx.xr.compose.material3.tokens.XrTokens import androidx.xr.compose.spatial.ContentEdge import androidx.xr.compose.spatial.Orbiter import androidx.xr.compose.spatial.OrbiterOffsetType -import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape /** * <a href="https://m3.material.io/components/navigation-bar/overview" class="external" @@ -144,7 +143,7 @@ offset = XrNavigationBarTokens.OrbiterOffset, offsetType = OrbiterOffsetType.InnerEdge, alignment = Alignment.CenterHorizontally, - shape = SpatialRoundedCornerShape(CornerSize(50)), + shape = XrTokens.ContainerShape, ) /** The [HorizontalOrbiterProperties] used by [NavigationBar]. */
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationRail.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationRail.kt index 67ce898..7650940 100644 --- a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationRail.kt +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/NavigationRail.kt
@@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.foundation.shape.CornerSize import androidx.compose.material3.ExperimentalMaterial3ComponentOverrideApi import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.LocalContentColor @@ -41,10 +40,10 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.xr.compose.material3.XrNavigationRailOverride.NavigationRail +import androidx.xr.compose.material3.tokens.XrTokens import androidx.xr.compose.spatial.ContentEdge import androidx.xr.compose.spatial.Orbiter import androidx.xr.compose.spatial.OrbiterOffsetType -import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape /** * <a href="https://m3.material.io/components/navigation-rail/overview" class="external" @@ -155,7 +154,7 @@ offset = XrNavigationRailTokens.OrbiterOffset, offsetType = OrbiterOffsetType.InnerEdge, alignment = Alignment.CenterVertically, - shape = SpatialRoundedCornerShape(CornerSize(50)), + shape = XrTokens.ContainerShape, ) /** The [VerticalOrbiterProperties] used by [NavigationRail]. */
diff --git a/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/tokens/XrTokens.kt b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/tokens/XrTokens.kt new file mode 100644 index 0000000..d854c65 --- /dev/null +++ b/xr/compose/material3/material3/src/main/java/androidx/xr/compose/material3/tokens/XrTokens.kt
@@ -0,0 +1,24 @@ +/* + * Copyright 2025 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.xr.compose.material3.tokens + +import androidx.compose.foundation.shape.CornerSize +import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape + +internal object XrTokens { + val ContainerShape = SpatialRoundedCornerShape(CornerSize(percent = 50)) +}