@ -17,13 +17,18 @@
package com.google.samples.apps.nowinandroid.core.ui.component
package com.google.samples.apps.nowinandroid.core.ui.component
import android.content.res.Configuration
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.size
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.material3.Surface
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.Preview
@ -31,10 +36,11 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.ui.theme.LocalBackgroundTheme
import com.google.samples.apps.nowinandroid.core.ui.theme.LocalBackgroundTheme
import com.google.samples.apps.nowinandroid.core.ui.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.ui.theme.NiaTheme
import kotlin.math.tan
/ * *
/ * *
* The main background for the app .
* The main background for the app .
* Uses [ LocalBackgroundTheme ] to set the color and tonal elevation of a [ Surface ] .
* Uses [ LocalBackgroundTheme ] to set the color and tonal elevation of a [ Box ] .
*
*
* @param modifier Modifier to be applied to the background .
* @param modifier Modifier to be applied to the background .
* @param content The background content .
* @param content The background content .
@ -50,13 +56,16 @@ fun NiaBackground(
color = if ( color == Color . Unspecified ) Color . Transparent else color ,
color = if ( color == Color . Unspecified ) Color . Transparent else color ,
tonalElevation = if ( tonalElevation == Dp . Unspecified ) 0. dp else tonalElevation ,
tonalElevation = if ( tonalElevation == Dp . Unspecified ) 0. dp else tonalElevation ,
modifier = modifier . fillMaxSize ( ) ,
modifier = modifier . fillMaxSize ( ) ,
content = content
) {
)
CompositionLocalProvider ( LocalAbsoluteTonalElevation provides 0. dp ) {
content ( )
}
}
}
}
/ * *
/ * *
* A gradient background for select screens , to be overlaid on top of [ NiaBackground ] .
* A gradient background for select screens . Uses [ LocalBackgroundTheme ] to set the gradient colors
* Uses [ LocalBackgroundTheme ] to set the gradient colors of a [ Box ] .
* of a [ Box ] .
*
*
* @param modifier Modifier to be applied to the background .
* @param modifier Modifier to be applied to the background .
* @param topColor The top gradient color to be rendered .
* @param topColor The top gradient color to be rendered .
@ -70,22 +79,57 @@ fun NiaGradientBackground(
bottomColor : Color = LocalBackgroundTheme . current . secondaryGradientColor ,
bottomColor : Color = LocalBackgroundTheme . current . secondaryGradientColor ,
content : @Composable ( ) -> Unit
content : @Composable ( ) -> Unit
) {
) {
val gradientModifier = Modifier . background (
val currentTopColor by rememberUpdatedState ( topColor )
Brush . verticalGradient (
val currentBottomColor by rememberUpdatedState ( bottomColor )
listOf (
NiaBackground ( modifier ) {
if ( topColor == Color . Unspecified ) Color . Transparent else topColor ,
Box (
Color . Transparent ,
Modifier
if ( bottomColor == Color . Unspecified ) Color . Transparent else bottomColor
. fillMaxSize ( )
. drawWithCache {
// Compute the start and end coordinates such that the gradients are angled 11.06
// degrees off the vertical axis
val offset = size . height * tan (
Math
. toRadians ( 11.06 )
. toFloat ( )
)
)
val start = Offset ( size . width / 2 + offset / 2 , 0f )
val end = Offset ( size . width / 2 - offset / 2 , size . height )
// Create the top gradient that fades out after the halfway point vertically
val topGradient = Brush . linearGradient (
0f to if ( currentTopColor == Color . Unspecified ) {
Color . Transparent
} else {
currentTopColor
} ,
0.724f to Color . Transparent ,
start = start ,
end = end ,
)
)
// Create the bottom gradient that fades in before the halfway point vertically
val bottomGradient = Brush . linearGradient (
0.2552f to Color . Transparent ,
1f to if ( currentBottomColor == Color . Unspecified ) {
Color . Transparent
} else {
currentBottomColor
} ,
start = start ,
end = end ,
)
)
Box (
modifier = modifier
onDrawBehind {
. fillMaxSize ( )
// There is overlap here, so order is important
. then ( gradientModifier )
drawRect ( topGradient )
drawRect ( bottomGradient )
}
}
) {
) {
content ( )
content ( )
}
}
}
}
}
@Preview ( uiMode = Configuration . UI _MODE _NIGHT _NO , name = " Light theme " )
@Preview ( uiMode = Configuration . UI _MODE _NIGHT _NO , name = " Light theme " )