Skip to content

Commit

Permalink
feat: Implement splash screen on android app and share resources with…
Browse files Browse the repository at this point in the history
… the wear app
  • Loading branch information
Gimbergsson committed Jan 15, 2025
1 parent 5e9d7e5 commit 02baea1
Show file tree
Hide file tree
Showing 8 changed files with 437 additions and 238 deletions.
6 changes: 6 additions & 0 deletions libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ material = "1.12.0"
playServicesWearable = "19.0.0"
playServicesTasks = "18.2.0"
splashscreen = "1.2.0-alpha02"
wear-compose-foundation = "1.4.0"
wear-compose-material = "1.4.0"
wear-compose-material-core = "1.4.0"

# KotlinX
corutines = "1.9.0"
Expand Down Expand Up @@ -67,6 +70,9 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co
androidx-runner = { group = "androidx.test", name = "runner", version.ref = "androidXTestRunner" }

androidx-wear = { group = "androidx.wear", name = "wear", version.ref = "wear" }
androidx-wear-compose-material = { group = "androidx.wear.compose", name = "compose-material", version.ref = "wear-compose-material" }
androidx-wear-compose-material-core = { group = "androidx.wear.compose", name = "compose-material-core", version.ref = "wear-compose-material-core" }
androidx-wear-compose-foundation = { group = "androidx.wear.compose", name = "compose-foundation", version.ref = "wear-compose-foundation" }
androidx-wear-input = { group = "androidx.wear", name = "wear-input", version.ref = "wearInput" }
androidx-wear-tooling-preview = { group = "androidx.wear", name = "wear-tooling-preview", version.ref = "wearToolingPreview" }

Expand Down
8 changes: 8 additions & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ dependencies {
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.compose.compiler)

implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.tooling)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui.tooling.preview)

implementation(libs.androidx.wear.tooling.preview)

implementation(libs.androidx.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.lifecycle.runtime)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package se.dennisgimbergsson.shared.utils

import android.content.res.Configuration
import androidx.compose.ui.tooling.preview.Preview
import androidx.wear.tooling.preview.devices.WearDevices.LARGE_ROUND
import androidx.wear.tooling.preview.devices.WearDevices.RECT
import androidx.wear.tooling.preview.devices.WearDevices.SMALL_ROUND
import androidx.wear.tooling.preview.devices.WearDevices.SQUARE

@Preview(
name = "Light theme",
group = "theme",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
name = "Dark theme",
group = "theme",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
annotation class ThemedPreview

@Preview(
name = "English Locale",
group = "locale",
locale = "en"
)
@Preview(
name = "Swedish Locale",
group = "locale",
locale = "sv"
)
@Preview(
name = "Danish Locale",
group = "locale",
locale = "da"
)
@Preview(
name = "German Locale",
group = "locale",
locale = "de"
)
annotation class LocalePreview

@Preview(
apiLevel = 34,
device = LARGE_ROUND,
group = "round",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 34,
device = SMALL_ROUND,
group = "round",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO,
fontScale = 1.00f,
)
@Preview(
apiLevel = 34,
device = RECT,
group = "rect",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 34,
device = SQUARE,
group = "square",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
annotation class WearPreview
6 changes: 6 additions & 0 deletions shared/src/main/res/mipmap-anydpi/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/appIconBackground"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
3 changes: 3 additions & 0 deletions wearos/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ dependencies {
implementation(libs.androidx.preference)

implementation(libs.androidx.wear)
implementation(libs.androidx.wear.compose.material)
implementation(libs.androidx.wear.compose.material.core)
implementation(libs.androidx.wear.compose.foundation)
implementation(libs.androidx.wear.input)
implementation(libs.androidx.wear.tooling.preview)

Expand Down
Binary file removed wearos/src/main/ic_launcher_2-playstore.png
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package se.dennisgimbergsson.tennisscoreboard.ui.views

import android.content.res.Configuration
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.rotary.onRotaryScrollEvent
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
import androidx.wear.tooling.preview.devices.WearDevices.LARGE_ROUND
import androidx.wear.tooling.preview.devices.WearDevices.RECT
import androidx.wear.tooling.preview.devices.WearDevices.SMALL_ROUND
import androidx.wear.tooling.preview.devices.WearDevices.SQUARE
import kotlinx.coroutines.launch
import se.dennisgimbergsson.shared.data.models.Score
import se.dennisgimbergsson.shared.data.models.Scoreboard
import se.dennisgimbergsson.shared.enums.GameScores
import se.dennisgimbergsson.tennisscoreboard.R
import se.dennisgimbergsson.tennisscoreboard.ui.screens.MainViewState
import se.dennisgimbergsson.tennisscoreboard.ui.theme.TennisScoreboardTheme

@Composable
fun ScoreboardView(
modifier: Modifier = Modifier,
state: MainViewState,
incrementHomeScore: () -> Unit = {},
incrementAwayScore: () -> Unit = {},
clearAll: () -> Unit = {},
decrementHome: () -> Unit = {},
decrementAway: () -> Unit = {},
) {

val focusRequester = remember { FocusRequester() }
val listState = rememberScalingLazyListState()
val coroutineScope = rememberCoroutineScope()

LaunchedEffect(Unit) {
listState.scrollToItem(0)
focusRequester.requestFocus()
}

Scaffold(
modifier = Modifier.fillMaxSize(),
positionIndicator = {
PositionIndicator(scalingLazyListState = listState)
}
) {
ScalingLazyColumn(
modifier = modifier
.fillMaxSize()
.onRotaryScrollEvent {
coroutineScope.launch {
listState.scrollBy(it.verticalScrollPixels)
}
true
}
.focusRequester(focusRequester)
.focusable(),
state = listState,
verticalArrangement = Arrangement.SpaceBetween,
scalingParams = ScalingLazyColumnDefaults.scalingParams(),
) {
item {
ScoreboardView(
state = state,
incrementHomeScore = incrementHomeScore,
incrementAwayScore = incrementAwayScore,
)
}
item {
Column(
modifier = Modifier
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Button(
modifier = Modifier.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
contentPadding = PaddingValues(0.dp),
onClick = { decrementHome() }
) {
Text(
modifier = Modifier.padding(0.dp),
text = stringResource(id = R.string.decrement_home_score),
textAlign = TextAlign.Center,
)
}
Button(
modifier = Modifier.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
contentPadding = PaddingValues(0.dp),
onClick = { decrementAway() }
) {
Text(
text = stringResource(id = R.string.decrement_away_score),
textAlign = TextAlign.Center,
)
}
Button(
modifier = Modifier.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
contentPadding = PaddingValues(0.dp),
onClick = { clearAll() }
) {
Text(
text = stringResource(id = R.string.clear_all_score),
textAlign = TextAlign.Center,
)
}
}
}
item {
Spacer(modifier = Modifier.height(16.dp))
}
}
}
}


@Preview(
apiLevel = 34,
device = LARGE_ROUND,
group = "round",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 34,
device = SMALL_ROUND,
group = "round",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO,
fontScale = 1.00f,
)
@Preview(
apiLevel = 34,
device = RECT,
group = "rect",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 34,
device = SQUARE,
group = "square",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Composable
private fun ScoreboardViewPreview() = TennisScoreboardTheme {
ScoreboardView(
state = MainViewState(
scoreboard = Scoreboard(
homeScore = Score(
gameScore = GameScores.FIFTEEN,
wonGames = 1,
wonSets = 1,
),
awayScore = Score(
gameScore = GameScores.FORTY,
wonGames = 1,
wonSets = 1,
)
)
)
)
}
Loading

0 comments on commit 02baea1

Please sign in to comment.