1 /* <lambda>null2 * Copyright (C) 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 @file:OptIn(ExperimentalAnimatableApi::class) 18 19 package com.android.mechanics.demo.presentation 20 21 import androidx.compose.animation.core.ExperimentalAnimatableApi 22 import androidx.compose.foundation.background 23 import androidx.compose.foundation.layout.Arrangement 24 import androidx.compose.foundation.layout.Column 25 import androidx.compose.foundation.layout.ColumnScope 26 import androidx.compose.foundation.layout.Row 27 import androidx.compose.foundation.layout.Spacer 28 import androidx.compose.foundation.layout.fillMaxWidth 29 import androidx.compose.foundation.layout.height 30 import androidx.compose.foundation.layout.padding 31 import androidx.compose.foundation.rememberScrollState 32 import androidx.compose.foundation.verticalScroll 33 import androidx.compose.material.icons.Icons 34 import androidx.compose.material.icons.filled.AllInclusive 35 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi 36 import androidx.compose.material3.Icon 37 import androidx.compose.material3.LocalContentColor 38 import androidx.compose.material3.MaterialTheme 39 import androidx.compose.material3.MaterialTheme.typography 40 import androidx.compose.material3.Text 41 import androidx.compose.runtime.Composable 42 import androidx.compose.runtime.CompositionLocalProvider 43 import androidx.compose.runtime.getValue 44 import androidx.compose.runtime.mutableStateOf 45 import androidx.compose.runtime.remember 46 import androidx.compose.runtime.setValue 47 import androidx.compose.ui.Modifier 48 import androidx.compose.ui.unit.Dp 49 import androidx.compose.ui.unit.dp 50 import com.android.compose.animation.scene.ElementKey 51 import com.android.compose.modifiers.thenIf 52 import com.android.mechanics.demo.staging.behavior.reveal.fadeReveal 53 import com.android.mechanics.demo.staging.behavior.reveal.revealContainer 54 import com.android.mechanics.demo.tuneable.Demo 55 import com.android.mechanics.demo.tuneable.LabelledCheckbox 56 import com.android.mechanics.demo.util.ExpandableCard 57 58 object PredefinedMotionDemo : Demo<PredefinedMotionDemo.Config> { 59 object Elements { 60 val ExpandableContent = ElementKey("ExpandableContent") 61 } 62 63 data class Config(val showItemBackground: Boolean) 64 65 @Composable 66 override fun DemoUi(config: Config, modifier: Modifier) { 67 val colors = MaterialTheme.colorScheme 68 ExpandableCard( 69 modifier = modifier.fillMaxWidth(), 70 header = { Text(text = "Contents", style = typography.titleMedium) }, 71 ) { isExpanded -> 72 Column( 73 verticalArrangement = Arrangement.spacedBy(8.dp), 74 modifier = 75 Modifier.fillMaxWidth() 76 .element(Elements.ExpandableContent) 77 .revealContainer(this@ExpandableCard) 78 .verticalScroll(rememberScrollState()) 79 .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), 80 ) { 81 if (isExpanded) { 82 Spacer(modifier = Modifier.height(24.dp)) 83 repeat(10) { 84 Row( 85 horizontalArrangement = Arrangement.spacedBy(8.dp), 86 modifier = 87 Modifier.noResizeDuringTransitions() 88 .fadeReveal(debug = true) 89 .fillMaxWidth() 90 .thenIf(config.showItemBackground) { 91 Modifier.background(colors.primary) 92 }, 93 ) { 94 CompositionLocalProvider( 95 LocalContentColor provides 96 if (config.showItemBackground) colors.onPrimary 97 else colors.onSurface 98 ) { 99 Icon(Icons.Default.AllInclusive, null) 100 Text(text = "Item ${it + 1}", modifier = Modifier.height(20.dp)) 101 } 102 } 103 } 104 } 105 } 106 } 107 } 108 109 @OptIn(ExperimentalMaterial3ExpressiveApi::class) 110 @Composable 111 override fun rememberDefaultConfig(): Config { 112 return remember { Config(showItemBackground = false) } 113 } 114 115 override var visualizationInputRange by mutableStateOf(0f..1000f) 116 override val collapsedGraphHeight: Dp = 20.dp 117 118 @Composable 119 override fun ColumnScope.ConfigUi(config: Config, onConfigChanged: (Config) -> Unit) { 120 LabelledCheckbox( 121 "Show item background", 122 config.showItemBackground, 123 onCheckedChange = { onConfigChanged(config.copy(showItemBackground = it)) }, 124 modifier = Modifier.fillMaxWidth(), 125 ) 126 } 127 128 override val identifier: String = "predefined_motion" 129 } 130