[go: nahoru, domu]

blob: 6b18f9a9b599daa4c61a2d450cebf8808c875b28 [file] [log] [blame]
Clara Bayarri581b24d2020-02-10 16:15:28 +00001/*
2 * Copyright 2020 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
17package androidx.ui.material.studies.rally
18
19import androidx.animation.LinearEasing
20import androidx.animation.transitionDefinition
Doris Liua69d17b2020-06-19 16:39:42 -070021import androidx.animation.tween
Clara Bayarri581b24d2020-02-10 16:15:28 +000022import androidx.compose.Composable
23import androidx.compose.remember
24import androidx.ui.animation.ColorPropKey
Doris Liud2aa99c2020-07-07 15:11:15 -070025import androidx.ui.animation.transition
Adam Powell999a89b2020-03-11 09:08:07 -070026import androidx.ui.core.Modifier
Louis Pullen-Freilichddda7be2020-07-17 18:28:12 +010027import androidx.compose.foundation.Text
28import androidx.compose.foundation.selection.selectable
Clara Bayarri581b24d2020-02-10 16:15:28 +000029import androidx.ui.graphics.Color
30import androidx.ui.graphics.vector.VectorAsset
Clara Bayarri581b24d2020-02-10 16:15:28 +000031import androidx.ui.layout.Row
32import androidx.ui.layout.Spacer
Adam Powell999a89b2020-03-11 09:08:07 -070033import androidx.ui.layout.fillMaxWidth
34import androidx.ui.layout.padding
35import androidx.ui.layout.preferredHeight
36import androidx.ui.layout.preferredWidth
Clara Bayarri581b24d2020-02-10 16:15:28 +000037import androidx.ui.material.MaterialTheme
Andrey Kulikov602ef012020-03-05 18:12:54 +000038import androidx.ui.material.Surface
Matvei Malkov6788d20b2020-05-28 18:35:55 +010039import androidx.ui.material.ripple.RippleIndication
Clara Bayarri581b24d2020-02-10 16:15:28 +000040import androidx.ui.unit.dp
41import java.util.Locale
42
43@Composable
44fun RallyTopAppBar(
45 allScreens: List<RallyScreenState>,
Clara Bayarri255d76a2020-02-12 12:23:09 +000046 onTabSelected: (RallyScreenState) -> Unit,
Clara Bayarri581b24d2020-02-10 16:15:28 +000047 currentScreen: RallyScreenState
48) {
Adam Powell999a89b2020-03-11 09:08:07 -070049 Surface(Modifier.preferredHeight(TabHeight).fillMaxWidth()) {
Clara Bayarri581b24d2020-02-10 16:15:28 +000050 Row {
51 allScreens.forEachIndexed { index, screen ->
52 RallyTab(
53 text = screen.name.toUpperCase(Locale.getDefault()),
54 icon = screen.icon,
Clara Bayarri255d76a2020-02-12 12:23:09 +000055 onSelected = { onTabSelected(screen) },
Andrey Kulikov602ef012020-03-05 18:12:54 +000056 selected = currentScreen.ordinal == index
57 )
Clara Bayarri581b24d2020-02-10 16:15:28 +000058 }
59 }
60 }
61}
62
63@Composable
64private fun RallyTab(
65 text: String,
66 icon: VectorAsset,
67 onSelected: () -> Unit,
68 selected: Boolean
69) {
70 TabTransition(selected = selected) { tabTintColor ->
Matvei Malkov6788d20b2020-05-28 18:35:55 +010071 Row(
72 modifier = Modifier
73 .padding(16.dp)
74 .preferredHeight(TabHeight)
75 .selectable(
76 selected = selected,
77 onClick = onSelected,
78 indication = RippleIndication(bounded = false)
79 )
80 ) {
81 Icon(vectorImage = icon, tintColor = tabTintColor)
82 if (selected) {
83 Spacer(Modifier.preferredWidth(12.dp))
84 Text(text, color = tabTintColor)
Clara Bayarri581b24d2020-02-10 16:15:28 +000085 }
86 }
87 }
88}
89
90@Composable
91private fun TabTransition(
92 selected: Boolean,
Louis Pullen-Freilich3a54b942020-05-07 13:23:03 +010093 children: @Composable (color: Color) -> Unit
Clara Bayarri581b24d2020-02-10 16:15:28 +000094) {
Louis Pullen-Freilichb2591852020-03-23 19:00:09 +000095 val color = MaterialTheme.colors.onSurface
Clara Bayarri581b24d2020-02-10 16:15:28 +000096 val transitionDefinition = remember {
97 transitionDefinition {
98 state(true) {
99 this[TabTintColorKey] = color
100 }
101
102 state(false) {
103 this[TabTintColorKey] = color.copy(alpha = InactiveTabOpacity)
104 }
105
106 transition(fromState = false, toState = true) {
Doris Liua69d17b2020-06-19 16:39:42 -0700107 TabTintColorKey using tween(
108 durationMillis = TabFadeInAnimationDuration,
109 delayMillis = TabFadeInAnimationDelay,
Clara Bayarri581b24d2020-02-10 16:15:28 +0000110 easing = LinearEasing
Doris Liua69d17b2020-06-19 16:39:42 -0700111 )
Clara Bayarri581b24d2020-02-10 16:15:28 +0000112 }
113
114 transition(fromState = true, toState = false) {
Doris Liua69d17b2020-06-19 16:39:42 -0700115 TabTintColorKey using tween(
116 durationMillis = TabFadeOutAnimationDuration,
117 delayMillis = TabFadeInAnimationDelay,
Clara Bayarri581b24d2020-02-10 16:15:28 +0000118 easing = LinearEasing
Doris Liua69d17b2020-06-19 16:39:42 -0700119 )
Clara Bayarri581b24d2020-02-10 16:15:28 +0000120 }
121 }
122 }
Doris Liud2aa99c2020-07-07 15:11:15 -0700123 val state = transition(transitionDefinition, selected)
124 children(state[TabTintColorKey])
Clara Bayarri581b24d2020-02-10 16:15:28 +0000125}
126
127private val TabTintColorKey = ColorPropKey()
128private val TabHeight = 56.dp
129private const val InactiveTabOpacity = 0.60f
130
131private const val TabFadeInAnimationDuration = 150
132private const val TabFadeInAnimationDelay = 100
133private const val TabFadeOutAnimationDuration = 100