Cleanup UI with Material3 color schemes

This commit is contained in:
Iamlooker 2022-06-15 10:51:12 +05:30
parent 1b92ef93bf
commit 487a6ecc46
14 changed files with 285 additions and 311 deletions

View File

@ -158,7 +158,7 @@ dependencies {
// Core // Core
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21")
implementation("androidx.core:core-ktx:1.9.0-alpha04") implementation("androidx.core:core-ktx:1.9.0-alpha04")
implementation("androidx.appcompat:appcompat:1.4.1") implementation("androidx.appcompat:appcompat:1.4.2")
implementation("androidx.fragment:fragment-ktx:1.5.0-rc01") implementation("androidx.fragment:fragment-ktx:1.5.0-rc01")
implementation("androidx.activity:activity-ktx:1.6.0-alpha04") implementation("androidx.activity:activity-ktx:1.6.0-alpha04")
implementation("androidx.activity:activity-compose:1.6.0-alpha03") implementation("androidx.activity:activity-compose:1.6.0-alpha03")
@ -209,10 +209,9 @@ dependencies {
implementation("androidx.compose.foundation:foundation:$composeVersion") implementation("androidx.compose.foundation:foundation:$composeVersion")
implementation("androidx.compose.runtime:runtime-livedata:$composeVersion") implementation("androidx.compose.runtime:runtime-livedata:$composeVersion")
implementation("androidx.compose.material3:material3:1.0.0-alpha13") implementation("androidx.compose.material3:material3:1.0.0-alpha13")
implementation("androidx.compose.material:material:$composeVersion")
implementation("androidx.compose.animation:animation:$composeVersion") implementation("androidx.compose.animation:animation:$composeVersion")
implementation("androidx.compose.material:material-icons-extended:$composeVersion") implementation("androidx.compose.material:material-icons-extended:$composeVersion")
implementation("com.google.android.material:compose-theme-adapter-3:1.0.10") implementation("com.google.android.material:compose-theme-adapter-3:1.0.11")
debugImplementation ("androidx.compose.ui:ui-tooling:$composeVersion") debugImplementation ("androidx.compose.ui:ui-tooling:$composeVersion")
debugImplementation ("androidx.compose.ui:ui-tooling-preview:$composeVersion") debugImplementation ("androidx.compose.ui:ui-tooling-preview:$composeVersion")

View File

@ -1,8 +1,8 @@
package com.looker.droidify.ui.compose.components package com.looker.droidify.ui.compose.components
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
@ -23,17 +23,16 @@ fun ExpandableBlock(
content: @Composable ColumnScope.() -> Unit content: @Composable ColumnScope.() -> Unit
) { ) {
var expanded by rememberSaveable { mutableStateOf(preExpanded) } var expanded by rememberSaveable { mutableStateOf(preExpanded) }
val backgroundColor by animateColorAsState( val tonalElevation by animateDpAsState(
targetValue = if (expanded) MaterialTheme.colorScheme.surface targetValue = if (expanded) 8.dp
else MaterialTheme.colorScheme.background else 0.dp
) )
Surface( Surface(
modifier = Modifier.animateContentSize(), modifier = Modifier.animateContentSize(),
shape = MaterialTheme.shapes.large, shape = MaterialTheme.shapes.large,
onClick = { expanded = !expanded }, onClick = { expanded = !expanded },
color = backgroundColor, tonalElevation = tonalElevation
tonalElevation = 8.dp
) { ) {
Column(modifier = modifier) { Column(modifier = modifier) {
ExpandableBlockHeader(heading, positive) ExpandableBlockHeader(heading, positive)

View File

@ -1,14 +1,9 @@
package com.looker.droidify.ui.compose.components package com.looker.droidify.ui.compose.components
import androidx.compose.foundation.background import androidx.compose.foundation.layout.*
import androidx.compose.foundation.clickable import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -16,7 +11,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.looker.droidify.database.entity.Repository import com.looker.droidify.database.entity.Repository
@ -24,6 +18,7 @@ import com.looker.droidify.entity.ProductItem
import com.looker.droidify.network.CoilDownloader import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.ui.compose.utils.NetworkImage import com.looker.droidify.ui.compose.utils.NetworkImage
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ProductCard( fun ProductCard(
item: ProductItem, item: ProductItem,
@ -43,14 +38,15 @@ fun ProductCard(
).toString() ).toString()
) )
} }
Surface(
Column(
modifier = Modifier modifier = Modifier
.padding(4.dp) .padding(4.dp)
.requiredSize(80.dp, 116.dp) .requiredSize(80.dp, 116.dp),
.clip(shape = RoundedCornerShape(8.dp)) tonalElevation = 8.dp,
.background(color = MaterialTheme.colorScheme.surface) shape = MaterialTheme.shapes.medium,
.clickable(onClick = { onUserClick(product) }), onClick = { onUserClick(product) }
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
@ -76,6 +72,8 @@ fun ProductCard(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
}
} }
//@Preview //@Preview

View File

@ -1,25 +1,12 @@
package com.looker.droidify.ui.compose.components package com.looker.droidify.ui.compose.components
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material3.*
import androidx.compose.material3.ButtonDefaults.buttonColors import androidx.compose.material3.ButtonDefaults.buttonColors
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf

View File

@ -1,29 +1,14 @@
package com.looker.droidify.ui.compose.components package com.looker.droidify.ui.compose.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.Icon import androidx.compose.material3.*
import androidx.compose.material3.IconButton import androidx.compose.runtime.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
@ -38,22 +23,22 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.looker.droidify.R import com.looker.droidify.R
import com.looker.droidify.ui.compose.theme.surfaceColorAtElevation
import com.looker.droidify.ui.compose.utils.HorizontalExpandingVisibility import com.looker.droidify.ui.compose.utils.HorizontalExpandingVisibility
@Composable @Composable
fun TopBar( fun TopBar(
title: String, title: String,
actions: @Composable (RowScope.() -> Unit) actions: @Composable (RowScope.() -> Unit)
) { ) {
TopAppBar( SmallTopAppBar(
modifier = Modifier.wrapContentHeight(), modifier = Modifier.wrapContentHeight(),
title = { title = {
Text(text = title, style = MaterialTheme.typography.headlineSmall) Text(text = title, style = MaterialTheme.typography.headlineSmall)
}, },
backgroundColor = MaterialTheme.colorScheme.surface, colors = TopAppBarDefaults.smallTopAppBarColors(
contentColor = MaterialTheme.colorScheme.onSurface, containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
elevation = 0.dp, ),
actions = actions actions = actions
) )
} }
@ -66,12 +51,10 @@ fun ExpandableSearchAction(
onClose: () -> Unit, onClose: () -> Unit,
onQueryChanged: (String) -> Unit onQueryChanged: (String) -> Unit
) { ) {
val (expanded, onExpanded) = remember { val (isExpanded, onExpanded) = remember { mutableStateOf(expanded) }
mutableStateOf(expanded)
}
HorizontalExpandingVisibility( HorizontalExpandingVisibility(
expanded = expanded, expanded = isExpanded,
expandedView = { expandedView = {
ExpandedSearchView( ExpandedSearchView(
query = query, query = query,
@ -83,7 +66,6 @@ fun ExpandableSearchAction(
}, },
collapsedView = { collapsedView = {
CollapsedSearchView( CollapsedSearchView(
modifier = modifier,
onExpanded = onExpanded onExpanded = onExpanded
) )
} }
@ -92,7 +74,6 @@ fun ExpandableSearchAction(
@Composable @Composable
fun CollapsedSearchView( fun CollapsedSearchView(
modifier: Modifier = Modifier,
onExpanded: (Boolean) -> Unit onExpanded: (Boolean) -> Unit
) { ) {
TopBarAction( TopBarAction(

View File

@ -54,7 +54,8 @@ fun AppInfoHeader(
Surface( Surface(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.large shape = MaterialTheme.shapes.large,
tonalElevation = 8.dp
) { ) {
Column( Column(
modifier = Modifier.padding(8.dp), modifier = Modifier.padding(8.dp),
@ -85,7 +86,7 @@ fun AppInfoHeader(
} }
MainActionButton( MainActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
actionState = mainAction ?: ActionState.NoAction, actionState = mainAction ?: ActionState.Install,
onClick = { onClick = {
onAction(mainAction) onAction(mainAction)
} }
@ -117,7 +118,8 @@ fun TopBarHeader(
modifier = modifier modifier = modifier
.padding(start = 8.dp, top = 8.dp, end = 8.dp, bottom = 0.dp) .padding(start = 8.dp, top = 8.dp, end = 8.dp, bottom = 0.dp)
.fillMaxWidth(), .fillMaxWidth(),
shape = MaterialTheme.shapes.large shape = MaterialTheme.shapes.large,
tonalElevation = 8.dp
) { ) {
Column { Column {
Row( Row(

View File

@ -103,7 +103,8 @@ fun CategoryChip(
shape = RoundedCornerShape(categoryChipTransitionState.cornerRadius) shape = RoundedCornerShape(categoryChipTransitionState.cornerRadius)
clip = true clip = true
}, },
color = categoryChipTransitionState.contentColor color = categoryChipTransitionState.contentColor,
tonalElevation = 8.dp
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier

View File

@ -6,55 +6,62 @@ val PitchBlack = Color(0xFF000000)
val GreyDark = Color(0xFF2C2C2C) val GreyDark = Color(0xFF2C2C2C)
// Light Theme // Light Theme
val LightPrimary = Color(0xFF006D3E) val md_theme_light_primary = Color(0xFF006D3E)
val LightOnPrimary = Color(0xFFFFFFFF) val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val LightPrimaryContainer = Color(0xFF71FCAD) val md_theme_light_primaryContainer = Color(0xFF96F7B8)
val LightOnPrimaryContainer = Color(0xFF00210F) val md_theme_light_onPrimaryContainer = Color(0xFF00210F)
val LightSecondary = Color(0xFF924C00) val md_theme_light_secondary = Color(0xFF4F6354)
val LightOnSecondary = Color(0xFFFFFFFF) val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val LightSecondaryContainer = Color(0xFFFFDCC1) val md_theme_light_secondaryContainer = Color(0xFFD1E8D5)
val LightOnSecondaryContainer = Color(0xFF2F1400) val md_theme_light_onSecondaryContainer = Color(0xFF0C1F13)
val LightError = Color(0xFFBA1B1B) val md_theme_light_tertiary = Color(0xFF3B6470)
val LightErrorContainer = Color(0xFFFFDAD4) val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val LightOnError = Color(0xFFFFFFFF) val md_theme_light_tertiaryContainer = Color(0xFFBEEAF7)
val LightOnErrorContainer = Color(0xFF410001) val md_theme_light_onTertiaryContainer = Color(0xFF001F26)
val LightBackground = Color(0xFFFBFDF8) val md_theme_light_error = Color(0xFFBA1A1A)
val LightOnBackground = Color(0xFF191C1A) val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val LightSurface = Color(0xFFE8F5E9) val md_theme_light_onError = Color(0xFFFFFFFF)
val LightOnSurface = Color(0xFF191C1A) val md_theme_light_onErrorContainer = Color(0xFF410002)
val LightSurfaceVariant = Color(0xFFDDE5DC) val md_theme_light_background = Color(0xFFFBFDF8)
val LightOnSurfaceVariant = Color(0xFF414942) val md_theme_light_onBackground = Color(0xFF191C1A)
val LightOutline = Color(0xFF707971) val md_theme_light_surface = Color(0xFFFBFDF8)
val LightInversePrimary = Color(0xFF51DF93) val md_theme_light_onSurface = Color(0xFF191C1A)
val LightInverseSurface = Color(0xFF2E312E) val md_theme_light_surfaceVariant = Color(0xFFDCE5DB)
val LightInverseOnSurface = Color(0xFFEFF1EC) val md_theme_light_onSurfaceVariant = Color(0xFF414942)
val md_theme_light_outline = Color(0xFF717971)
val md_theme_light_inverseOnSurface = Color(0xFFF0F1EC)
val md_theme_light_inverseSurface = Color(0xFF2E312E)
val md_theme_light_inversePrimary = Color(0xFF7ADA9D)
val md_theme_light_shadow = Color(0xFF000000)
// Dark Theme // Dark Theme
val DarkPrimary = Color(0xFF51DF93) val md_theme_dark_primary = Color(0xFF7ADA9D)
val DarkOnPrimary = Color(0xFF00391D) val md_theme_dark_onPrimary = Color(0xFF00391E)
val DarkPrimaryContainer = Color(0xFF00522D) val md_theme_dark_primaryContainer = Color(0xFF00522D)
val DarkOnPrimaryContainer = Color(0xFF71FCAD) val md_theme_dark_onPrimaryContainer = Color(0xFF96F7B8)
val DarkSecondary = Color(0xFFFFB77B) val md_theme_dark_secondary = Color(0xFFB6CCB9)
val DarkOnSecondary = Color(0xFF4E2600) val md_theme_dark_onSecondary = Color(0xFF213527)
val DarkSecondaryContainer = Color(0xFF6F3800) val md_theme_dark_secondaryContainer = Color(0xFF384B3D)
val DarkOnSecondaryContainer = Color(0xFFFFDCC1) val md_theme_dark_onSecondaryContainer = Color(0xFFD1E8D5)
val DarkError = Color(0xFFFFB4A9) val md_theme_dark_tertiary = Color(0xFFA3CDDB)
val DarkErrorContainer = Color(0xFF930006) val md_theme_dark_onTertiary = Color(0xFF023640)
val DarkOnError = Color(0xFF680003) val md_theme_dark_tertiaryContainer = Color(0xFF214C57)
val DarkOnErrorContainer = Color(0xFFFFDAD4) val md_theme_dark_onTertiaryContainer = Color(0xFFBEEAF7)
val DarkBackground = Color(0xFF191C1A) val md_theme_dark_error = Color(0xFFFFB4AB)
val DarkOnBackground = Color(0xFFE1E3DE) val md_theme_dark_errorContainer = Color(0xFF93000A)
val DarkSurface = Color(0xFF2C2C2C) val md_theme_dark_onError = Color(0xFF690005)
val DarkOnSurface = Color(0xFFE1E3DE) val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val DarkSurfaceVariant = Color(0xFF414942) val md_theme_dark_background = Color(0xFF191C1A)
val DarkOnSurfaceVariant = Color(0xFFC0C9C0) val md_theme_dark_onBackground = Color(0xFFE1E3DE)
val DarkOutline = Color(0xFF8A938A) val md_theme_dark_surface = Color(0xFF191C1A)
val DarkInversePrimary = Color(0xFFE1E3DE) val md_theme_dark_onSurface = Color(0xFFE1E3DE)
val DarkInverseSurface = Color(0xFF191C1A) val md_theme_dark_surfaceVariant = Color(0xFF414942)
val DarkInverseOnSurface = Color(0xFF006D3E) val md_theme_dark_onSurfaceVariant = Color(0xFFC0C9C0)
val md_theme_dark_outline = Color(0xFF8A938B)
val md_theme_dark_inverseOnSurface = Color(0xFF191C1A)
val md_theme_dark_inverseSurface = Color(0xFFE1E3DE)
val md_theme_dark_inversePrimary = Color(0xFF006D3E)
val md_theme_dark_shadow = Color(0xFF000000)
// Black Theme
val BlackBackground = Color(0xFF000000)
val BlackSurface = Color(0xFF191C1A)
val Seed = Color(0xFF51DF93) val seed = Color(0xFF006D3E)

View File

@ -0,0 +1,13 @@
package com.looker.droidify.ui.compose.theme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Shapes
import androidx.compose.ui.unit.dp
val shapes: Shapes = Shapes(
extraSmall = RoundedCornerShape(8.dp),
small = RoundedCornerShape(12.dp),
medium = RoundedCornerShape(16.dp),
large = RoundedCornerShape(18.dp),
extraLarge = RoundedCornerShape(24.dp)
)

View File

@ -19,81 +19,95 @@ fun AppTheme(
darkTheme -> DarkColors darkTheme -> DarkColors
else -> LightColors else -> LightColors
}, },
shapes = shapes,
content = content content = content
) )
} }
private val LightColors = lightColorScheme( private val LightColors = lightColorScheme(
primary = LightPrimary, primary = md_theme_light_primary,
onPrimary = LightOnPrimary, onPrimary = md_theme_light_onPrimary,
primaryContainer = LightPrimaryContainer, primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = LightOnPrimaryContainer, onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = LightSecondary, secondary = md_theme_light_secondary,
onSecondary = LightOnSecondary, onSecondary = md_theme_light_onSecondary,
secondaryContainer = LightSecondaryContainer, secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = LightOnSecondaryContainer, onSecondaryContainer = md_theme_light_onSecondaryContainer,
surface = LightSurface, tertiary = md_theme_light_tertiary,
onSurface = LightOnSurface, onTertiary = md_theme_light_onTertiary,
surfaceVariant = LightSurfaceVariant, tertiaryContainer = md_theme_light_tertiaryContainer,
onSurfaceVariant = LightOnSurfaceVariant, onTertiaryContainer = md_theme_light_onTertiaryContainer,
outline = LightOutline, error = md_theme_light_error,
background = LightBackground, errorContainer = md_theme_light_errorContainer,
onBackground = LightOnBackground, onError = md_theme_light_onError,
inversePrimary = LightInversePrimary, onErrorContainer = md_theme_light_onErrorContainer,
inverseSurface = LightInverseSurface, background = md_theme_light_background,
inverseOnSurface = LightInverseOnSurface, onBackground = md_theme_light_onBackground,
error = LightError, surface = md_theme_light_surface,
onError = LightOnError, onSurface = md_theme_light_onSurface,
errorContainer = LightErrorContainer, surfaceVariant = md_theme_light_surfaceVariant,
onErrorContainer = LightOnErrorContainer onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
inversePrimary = md_theme_light_inversePrimary,
) )
private val DarkColors = darkColorScheme( private val DarkColors = darkColorScheme(
primary = DarkPrimary, primary = md_theme_dark_primary,
onPrimary = DarkOnPrimary, onPrimary = md_theme_dark_onPrimary,
primaryContainer = DarkPrimaryContainer, primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = DarkOnPrimaryContainer, onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = DarkSecondary, secondary = md_theme_dark_secondary,
onSecondary = DarkOnSecondary, onSecondary = md_theme_dark_onSecondary,
secondaryContainer = DarkSecondaryContainer, secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = DarkOnSecondaryContainer, onSecondaryContainer = md_theme_dark_onSecondaryContainer,
surface = DarkSurface, tertiary = md_theme_dark_tertiary,
onSurface = DarkOnSurface, onTertiary = md_theme_dark_onTertiary,
surfaceVariant = DarkSurfaceVariant, tertiaryContainer = md_theme_dark_tertiaryContainer,
onSurfaceVariant = DarkOnSurfaceVariant, onTertiaryContainer = md_theme_dark_onTertiaryContainer,
outline = DarkOutline, error = md_theme_dark_error,
background = DarkBackground, errorContainer = md_theme_dark_errorContainer,
onBackground = DarkOnBackground, onError = md_theme_dark_onError,
inversePrimary = DarkInversePrimary, onErrorContainer = md_theme_dark_onErrorContainer,
inverseSurface = DarkInverseSurface, background = md_theme_dark_background,
inverseOnSurface = DarkInverseOnSurface, onBackground = md_theme_dark_onBackground,
error = DarkError, surface = md_theme_dark_surface,
onError = DarkOnError, onSurface = md_theme_dark_onSurface,
errorContainer = DarkErrorContainer, surfaceVariant = md_theme_dark_surfaceVariant,
onErrorContainer = DarkOnErrorContainer onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
) )
private val BlackColors = darkColorScheme( private val BlackColors = darkColorScheme(
primary = DarkPrimary, primary = md_theme_dark_primary,
onPrimary = DarkOnPrimary, onPrimary = md_theme_dark_onPrimary,
primaryContainer = DarkPrimaryContainer, primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = DarkOnPrimaryContainer, onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = DarkSecondary, secondary = md_theme_dark_secondary,
onSecondary = DarkOnSecondary, onSecondary = md_theme_dark_onSecondary,
secondaryContainer = DarkSecondaryContainer, secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = DarkOnSecondaryContainer, onSecondaryContainer = md_theme_dark_onSecondaryContainer,
surface = BlackSurface, tertiary = md_theme_dark_tertiary,
onSurface = DarkOnSurface, onTertiary = md_theme_dark_onTertiary,
surfaceVariant = DarkSurfaceVariant, tertiaryContainer = md_theme_dark_tertiaryContainer,
onSurfaceVariant = DarkOnSurfaceVariant, onTertiaryContainer = md_theme_dark_onTertiaryContainer,
outline = DarkOutline, error = md_theme_dark_error,
background = BlackBackground, errorContainer = md_theme_dark_errorContainer,
onBackground = DarkOnBackground, onError = md_theme_dark_onError,
inversePrimary = DarkInversePrimary, onErrorContainer = md_theme_dark_onErrorContainer,
inverseSurface = DarkInverseSurface, background = PitchBlack,
inverseOnSurface = DarkInverseOnSurface, onBackground = md_theme_dark_onBackground,
error = DarkError, surface = PitchBlack,
onError = DarkOnError, onSurface = md_theme_dark_onSurface,
errorContainer = DarkErrorContainer, surfaceVariant = md_theme_dark_surfaceVariant,
onErrorContainer = DarkOnErrorContainer onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
) )

View File

@ -0,0 +1,16 @@
package com.looker.droidify.ui.compose.theme
import androidx.compose.material3.ColorScheme
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlin.math.ln
fun ColorScheme.surfaceColorAtElevation(
elevation: Dp,
): Color {
if (elevation == 0.dp) return surface
val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
return surfaceTint.copy(alpha = alpha).compositeOver(surface)
}

View File

@ -1,12 +1,8 @@
package com.looker.droidify.ui.compose.utils package com.looker.droidify.ui.compose.utils
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.material.Chip
import androidx.compose.material.ChipDefaults.chipColors
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.*
import androidx.compose.material3.Shapes
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -18,7 +14,7 @@ import androidx.compose.ui.unit.dp
/** /**
* Basically a OutlineChip without spamming "ExperimentalMaterialApi" * Basically a OutlineChip without spamming "ExperimentalMaterialApi"
*/ */
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
@Composable @Composable
fun CustomChip( fun CustomChip(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -28,21 +24,10 @@ fun CustomChip(
borderWidth: Dp = 1.dp, borderWidth: Dp = 1.dp,
onClick: (String) -> Unit = {} onClick: (String) -> Unit = {}
) { ) {
Chip( ElevatedAssistChip(
modifier = modifier, modifier = modifier,
shape = Shapes.Full, shape = Shapes.Full,
border = BorderStroke( onClick = { onClick(text) },
width = borderWidth, label = { Text(text = text, color = borderColor) }
color = borderColor.compositeOverBackground(
alpha = 0.5f,
MaterialTheme.colorScheme.surface
) )
),
colors = chipColors(
backgroundColor = containerColor.compositeOverBackground(alpha = 0.1f)
),
onClick = { onClick(text) }
) {
Text(text = text, color = borderColor)
}
} }

View File

@ -9,33 +9,13 @@ import android.view.ViewGroup
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.Chip
import androidx.compose.material.ChipDefaults
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Sync import androidx.compose.material.icons.rounded.Sync
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.*
import androidx.compose.material3.ElevatedButton import androidx.compose.runtime.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
@ -86,7 +66,7 @@ class InstalledFragment : MainNavFragmentX() {
} }
} }
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun InstalledPage() { private fun InstalledPage() {
val primaryList by viewModel.primaryProducts.observeAsState(null) val primaryList by viewModel.primaryProducts.observeAsState(null)
@ -158,11 +138,11 @@ class InstalledFragment : MainNavFragmentX() {
) )
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
Chip( SuggestionChip(
shape = MaterialTheme.shapes.medium, shape = MaterialTheme.shapes.medium,
colors = ChipDefaults.chipColors( colors = SuggestionChipDefaults.suggestionChipColors(
backgroundColor = MaterialTheme.colorScheme.surface, containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface, labelColor = MaterialTheme.colorScheme.onSurface,
), ),
onClick = { onClick = {
secondaryList?.let { secondaryList?.let {
@ -172,16 +152,18 @@ class InstalledFragment : MainNavFragmentX() {
) )
) )
} }
} },
) { icon = {
Icon( Icon(
modifier = Modifier.size(18.dp), modifier = Modifier.size(18.dp),
painter = painterResource(id = R.drawable.ic_download), painter = painterResource(id = R.drawable.ic_download),
contentDescription = stringResource(id = R.string.update_all) contentDescription = stringResource(id = R.string.update_all)
) )
Spacer(modifier = Modifier.width(8.dp)) },
label = {
Text(text = stringResource(id = R.string.update_all)) Text(text = stringResource(id = R.string.update_all))
} }
)
} }
AnimatedVisibility(visible = updatesVisible) { AnimatedVisibility(visible = updatesVisible) {
ProductsHorizontalRecycler(secondaryList, repositories) { item -> ProductsHorizontalRecycler(secondaryList, repositories) { item ->
@ -198,22 +180,24 @@ class InstalledFragment : MainNavFragmentX() {
text = stringResource(id = R.string.installed_applications), text = stringResource(id = R.string.installed_applications),
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) )
Chip( SuggestionChip(
shape = MaterialTheme.shapes.medium, shape = MaterialTheme.shapes.medium,
colors = ChipDefaults.chipColors( colors = SuggestionChipDefaults.suggestionChipColors(
backgroundColor = MaterialTheme.colorScheme.surface, containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface, labelColor = MaterialTheme.colorScheme.onSurface,
), ),
onClick = { } // TODO add sort & filter onClick = { }, // TODO add sort & filter
) { icon = {
Icon( Icon(
modifier = Modifier.size(18.dp), modifier = Modifier.size(18.dp),
painter = painterResource(id = R.drawable.ic_sort), painter = painterResource(id = R.drawable.ic_sort),
contentDescription = stringResource(id = R.string.sort_filter) contentDescription = stringResource(id = R.string.sort_filter)
) )
Spacer(modifier = Modifier.width(8.dp)) },
label = {
Text(text = stringResource(id = R.string.sort_filter)) Text(text = stringResource(id = R.string.sort_filter))
} }
)
} }
ProductsVerticalRecycler(primaryList?.sortedBy(Product::label), ProductsVerticalRecycler(primaryList?.sortedBy(Product::label),
repositories, repositories,

View File

@ -8,25 +8,11 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.Chip
import androidx.compose.material.ChipDefaults
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Sync import androidx.compose.material.icons.rounded.Sync
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.*
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
@ -78,7 +64,7 @@ class LatestFragment : MainNavFragmentX() {
} }
} }
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun LatestPage() { private fun LatestPage() {
val primaryList by viewModel.primaryProducts.observeAsState(null) val primaryList by viewModel.primaryProducts.observeAsState(null)
@ -137,22 +123,24 @@ class LatestFragment : MainNavFragmentX() {
text = stringResource(id = R.string.recently_updated), text = stringResource(id = R.string.recently_updated),
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) )
Chip( SuggestionChip(
shape = MaterialTheme.shapes.medium, shape = MaterialTheme.shapes.medium,
colors = ChipDefaults.chipColors( colors = SuggestionChipDefaults.suggestionChipColors(
backgroundColor = MaterialTheme.colorScheme.surface, containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface, labelColor = MaterialTheme.colorScheme.onSurface,
), ),
onClick = { } // TODO add sort & filter onClick = { }, // TODO add sort & filter
) { icon = {
Icon( Icon(
modifier = Modifier.size(18.dp), modifier = Modifier.size(18.dp),
painter = painterResource(id = R.drawable.ic_sort), painter = painterResource(id = R.drawable.ic_sort),
contentDescription = stringResource(id = R.string.sort_filter) contentDescription = stringResource(id = R.string.sort_filter)
) )
Spacer(modifier = Modifier.width(8.dp)) },
label = {
Text(text = stringResource(id = R.string.sort_filter)) Text(text = stringResource(id = R.string.sort_filter))
} }
)
} }
ProductsVerticalRecycler(primaryList, repositories, ProductsVerticalRecycler(primaryList, repositories,
modifier = Modifier modifier = Modifier