Move Compose to Material3 (Material You)

Optimize Image Processing for Jetpack Compose
Update Dependencies
This commit is contained in:
LooKeR 2022-02-25 11:56:10 +05:30
parent e1e1916126
commit 000bd16256
7 changed files with 177 additions and 117 deletions

View File

@ -135,9 +135,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat-resources:1.4.1'
implementation 'androidx.fragment:fragment-ktx:1.4.1'
implementation 'androidx.activity:activity-ktx:1.4.0'
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.navigation:navigation-fragment-ktx:2.5.0-alpha01"
implementation "androidx.navigation:navigation-ui-ktx:2.5.0-alpha01"
implementation "androidx.preference:preference-ktx:1.2.0"
implementation "androidx.navigation:navigation-fragment-ktx:2.5.0-alpha03"
implementation "androidx.navigation:navigation-ui-ktx:2.5.0-alpha03"
// Material3
implementation 'com.google.android.material:material:1.6.0-alpha02'
@ -171,7 +171,7 @@ dependencies {
implementation "org.jetbrains:markdown:0.2.4"
// Coroutines / Lifecycle
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
@ -179,20 +179,20 @@ dependencies {
implementation 'androidx.paging:paging-runtime-ktx:3.1.0'
// Room
implementation 'androidx.room:room-runtime:2.4.1'
implementation 'androidx.room:room-ktx:2.4.1'
implementation 'androidx.room:room-rxjava3:2.4.1'
kapt 'androidx.room:room-compiler:2.4.1'
implementation 'androidx.room:room-runtime:2.4.2'
implementation 'androidx.room:room-ktx:2.4.2'
implementation 'androidx.room:room-rxjava3:2.4.2'
kapt 'androidx.room:room-compiler:2.4.2'
// Compose
implementation "androidx.compose.runtime:runtime:1.2.0-alpha02"
implementation "androidx.compose.ui:ui:1.2.0-alpha02"
implementation "androidx.compose.ui:ui-tooling:1.2.0-alpha02"
implementation "androidx.compose.foundation:foundation:1.2.0-alpha02"
implementation "androidx.compose.foundation:foundation-layout:1.2.0-alpha02"
implementation "androidx.compose.runtime:runtime-livedata:1.2.0-alpha02"
implementation "androidx.compose.material:material:1.2.0-alpha02"
implementation "com.google.android.material:compose-theme-adapter:1.1.3"
implementation "androidx.compose.runtime:runtime:1.2.0-alpha04"
implementation "androidx.compose.ui:ui:1.2.0-alpha04"
implementation "androidx.compose.ui:ui-tooling:1.2.0-alpha04"
implementation "androidx.compose.foundation:foundation:1.2.0-alpha04"
implementation "androidx.compose.runtime:runtime-livedata:1.2.0-alpha04"
implementation "androidx.compose.material3:material3:1.0.0-alpha06"
implementation "androidx.compose.material:material:1.2.0-alpha04"
implementation "com.google.android.material:compose-theme-adapter:1.1.5"
}
// using a task as a preBuild dependency instead of a function that takes some time insures that it runs

View File

@ -145,7 +145,7 @@ object CoilDownloader {
fun createIconUri(
packageName: String, icon: String, metadataIcon: String,
address: String, auth: String
address: String?, auth: String?
): Uri = Uri.Builder().scheme("https").authority(HOST_ICON)
.appendQueryParameter(QUERY_ADDRESS, address)
.appendQueryParameter(QUERY_AUTHENTICATION, auth)

View File

@ -1,30 +1,25 @@
package com.looker.droidify.ui.compose
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.rememberImagePainter
import com.looker.droidify.R
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.ProductItem
import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.ui.compose.components.NetworkImage
import com.looker.droidify.ui.compose.theme.AppTheme
@Composable
@ -33,36 +28,31 @@ fun ProductRow(
repo: Repository? = null,
onUserClick: (ProductItem) -> Unit = {}
) {
val imageData by remember {
mutableStateOf(
CoilDownloader.createIconUri(
item.packageName,
item.icon,
item.metadataIcon,
repo?.address,
repo?.authentication
)
)
}
Row(
modifier = Modifier
.padding(4.dp)
.fillMaxWidth()
.background(color = MaterialTheme.colors.surface, shape = RoundedCornerShape(8.dp))
.background(color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(8.dp))
.clip(shape = RoundedCornerShape(8.dp))
.clickable(onClick = { onUserClick(item) })
.padding(8.dp)
) {
// TODO: Fix the issue where coil doesn't fallback to the palceholder
val imagePainter =
if (repo != null) rememberImagePainter(
CoilDownloader.createIconUri(
item.packageName,
item.icon,
item.metadataIcon,
repo.address,
repo.authentication
), builder = {
placeholder(R.drawable.ic_application_default)
error(R.drawable.ic_application_default)
}
) else painterResource(id = R.drawable.ic_application_default)
Image(
painter = imagePainter,
modifier = Modifier
.requiredSize(56.dp)
.clip(shape = RoundedCornerShape(8.dp)),
contentScale = ContentScale.Crop,
contentDescription = null
NetworkImage(
modifier = Modifier.size(56.dp),
data = imageData
)
Column(
@ -84,24 +74,23 @@ fun ProductRow(
fontWeight = FontWeight.Bold,
softWrap = true,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.body1
style = MaterialTheme.typography.bodyMedium
)
Text(
text = item.version,
modifier = Modifier
.align(Alignment.CenterEnd),
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.body2
style = MaterialTheme.typography.bodySmall
)
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
modifier = Modifier.fillMaxHeight(),
text = item.summary,
style = MaterialTheme.typography.body2
style = MaterialTheme.typography.bodySmall
)
}
}
}
}
@ -112,60 +101,49 @@ fun ProductColumn(
repo: Repository? = null,
onUserClick: (ProductItem) -> Unit = {}
) {
val imageData by remember {
mutableStateOf(
CoilDownloader.createIconUri(
item.packageName,
item.icon,
item.metadataIcon,
repo?.address,
repo?.authentication
)
)
}
Column(
modifier = Modifier
.padding(4.dp)
.requiredSize(72.dp, 96.dp)
.background(color = MaterialTheme.colors.surface, shape = RoundedCornerShape(8.dp))
.background(color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(8.dp))
.clip(shape = RoundedCornerShape(8.dp))
.clickable(onClick = { onUserClick(item) })
.padding(4.dp)
.padding(4.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// TODO: Fix the issue where coil doesn't fallback to the palceholder
val imagePainter = if (repo != null)
rememberImagePainter(
CoilDownloader.createIconUri(
item.packageName,
item.icon,
item.metadataIcon,
repo.address,
repo.authentication
), builder = {
placeholder(R.drawable.ic_application_default)
error(R.drawable.ic_application_default)
}
)
else painterResource(id = R.drawable.ic_application_default)
Image(
painter = imagePainter,
modifier = Modifier
.requiredSize(56.dp)
.clip(shape = RoundedCornerShape(8.dp))
.align(Alignment.CenterHorizontally),
contentScale = ContentScale.Crop,
contentDescription = null
NetworkImage(
modifier = Modifier.size(56.dp),
data = imageData
)
Text(
text = item.name,
modifier = Modifier
.align(Alignment.CenterHorizontally),
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.body2,
style = MaterialTheme.typography.bodyLarge,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
text = item.version,
modifier = Modifier
.align(Alignment.CenterHorizontally),
style = MaterialTheme.typography.overline,
style = MaterialTheme.typography.labelSmall,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
}
}

View File

@ -0,0 +1,40 @@
package com.looker.droidify.ui.compose.components
import android.net.Uri
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import coil.annotation.ExperimentalCoilApi
import coil.compose.rememberImagePainter
import com.looker.droidify.R
import com.looker.droidify.ui.compose.theme.LocalShapes
@OptIn(ExperimentalCoilApi::class)
@Composable
fun NetworkImage(
modifier: Modifier = Modifier,
data: Uri?,
contentScale: ContentScale = ContentScale.Crop,
shape: CornerBasedShape = RoundedCornerShape(LocalShapes.current.medium)
) {
Box(modifier) {
val painter = rememberImagePainter(data = data) {
placeholder(R.drawable.ic_application_default)
error(R.drawable.ic_application_default)
}
Image(
painter = painter,
contentDescription = "This is Album Art",
contentScale = contentScale,
modifier = Modifier
.matchParentSize()
.clip(shape)
)
}
}

View File

@ -57,5 +57,4 @@ val DarkInverseOnSurface = Color(0xFF006D3E)
val BlackBackground = Color(0xFF000000)
val BlackSurface = Color(0xFF191C1A)
val Seed = Color(0xFF51DF93)
val Seed = Color(0xFF51DF93)

View File

@ -1,11 +1,15 @@
package com.looker.droidify.ui.compose.theme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Shapes
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
val AppShapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(8.dp),
large = RoundedCornerShape(16.dp)
)
@Immutable
data class ShapeSize(
val small: Dp = 4.dp,
val medium: Dp = 8.dp,
val large: Dp = 16.dp,
)
val LocalShapes = staticCompositionLocalOf { ShapeSize() }

View File

@ -1,10 +1,11 @@
package com.looker.droidify.ui.compose.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import com.looker.droidify.utility.isBlackTheme
@Composable
@ -13,52 +14,90 @@ fun AppTheme(
blackTheme: Boolean = isBlackTheme,
content: @Composable () -> Unit
) {
MaterialTheme(
shapes = AppShapes,
colors = when {
darkTheme && blackTheme -> BlackColors
darkTheme -> DarkColors
else -> LightColors
},
content = content
)
CompositionLocalProvider(LocalShapes provides ShapeSize()) {
MaterialTheme(
colorScheme = when {
darkTheme && blackTheme -> BlackColors
darkTheme -> DarkColors
else -> LightColors
},
content = content
)
}
}
private val LightColors = lightColors(
private val LightColors = lightColorScheme(
primary = LightPrimary,
primaryVariant = LightPrimaryContainer,
onPrimary = LightOnPrimary,
primaryContainer = LightPrimaryContainer,
onPrimaryContainer = LightOnPrimaryContainer,
secondary = LightSecondary,
secondaryVariant = LightSecondaryContainer,
onSecondary = LightOnSecondary,
secondaryContainer = LightSecondaryContainer,
onSecondaryContainer = LightOnSecondaryContainer,
surface = LightSurface,
onSurface = LightOnSurface,
surfaceVariant = LightSurfaceVariant,
onSurfaceVariant = LightOnSurfaceVariant,
outline = LightOutline,
background = LightBackground,
onBackground = LightOnBackground,
error = LightError
inversePrimary = LightInversePrimary,
inverseSurface = LightInverseSurface,
inverseOnSurface = LightInverseOnSurface,
error = LightError,
onError = LightOnError,
errorContainer = LightErrorContainer,
onErrorContainer = LightOnErrorContainer
)
private val DarkColors = darkColors(
private val DarkColors = darkColorScheme(
primary = DarkPrimary,
primaryVariant = DarkPrimaryContainer,
onPrimary = DarkOnPrimary,
primaryContainer = DarkPrimaryContainer,
onPrimaryContainer = DarkOnPrimaryContainer,
secondary = DarkSecondary,
secondaryVariant = DarkSecondaryContainer,
onSecondary = DarkOnSecondary,
secondaryContainer = DarkSecondaryContainer,
onSecondaryContainer = DarkOnSecondaryContainer,
surface = DarkSurface,
onSurface = DarkOnSurface,
surfaceVariant = DarkSurfaceVariant,
onSurfaceVariant = DarkOnSurfaceVariant,
outline = DarkOutline,
background = DarkBackground,
onBackground = DarkOnBackground,
error = DarkError
inversePrimary = DarkInversePrimary,
inverseSurface = DarkInverseSurface,
inverseOnSurface = DarkInverseOnSurface,
error = DarkError,
onError = DarkOnError,
errorContainer = DarkErrorContainer,
onErrorContainer = DarkOnErrorContainer
)
private val BlackColors = darkColors(
private val BlackColors = darkColorScheme(
primary = DarkPrimary,
primaryVariant = DarkPrimaryContainer,
onPrimary = DarkOnPrimary,
primaryContainer = DarkPrimaryContainer,
onPrimaryContainer = DarkOnPrimaryContainer,
secondary = DarkSecondary,
secondaryVariant = DarkSecondaryContainer,
onSecondary = DarkOnSecondary,
secondaryContainer = DarkSecondaryContainer,
onSecondaryContainer = DarkOnSecondaryContainer,
surface = BlackSurface,
onSurface = DarkOnSurface,
surfaceVariant = DarkSurfaceVariant,
onSurfaceVariant = DarkOnSurfaceVariant,
outline = DarkOutline,
background = BlackBackground,
onBackground = DarkOnBackground,
error = DarkError
inversePrimary = DarkInversePrimary,
inverseSurface = DarkInverseSurface,
inverseOnSurface = DarkInverseOnSurface,
error = DarkError,
onError = DarkOnError,
errorContainer = DarkErrorContainer,
onErrorContainer = DarkOnErrorContainer
)