M app/build.gradle.kts => app/build.gradle.kts +3 -0
@@ 60,4 60,7 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
+ implementation("androidx.navigation:navigation-compose:2.7.0")
+ implementation("com.google.android.material:material:1.2.0")
+ implementation("androidx.compose.material:material")
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt => app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt +2 -10
@@ 10,18 10,10 @@ import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import com.github.nacabaro.vbhelper.R
import com.github.cfogrady.vbnfc.CryptographicTransformer
import com.github.cfogrady.vbnfc.TagCommunicator
import com.github.cfogrady.vbnfc.data.DeviceType
+import com.github.nacabaro.vbhelper.navigation.AppNavigation
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
class MainActivity : ComponentActivity() {
@@ 45,7 37,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
VBHelperTheme {
-
+ AppNavigation()
}
}
}
A app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt => app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt +25 -0
@@ 0,0 1,25 @@
+package com.github.nacabaro.vbhelper.components
+
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+@Composable
+fun TopBanner(
+ text: String,
+ modifier: Modifier = Modifier
+) {
+ Text(
+ text = text,
+ textAlign = TextAlign.Center,
+ fontSize = 24.sp,
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(16.dp)
+ )
+}
A app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +48 -0
@@ 0,0 1,48 @@
+package com.github.nacabaro.vbhelper.navigation
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import com.github.nacabaro.vbhelper.screens.BattlesScreen
+import com.github.nacabaro.vbhelper.screens.DexScreen
+import com.github.nacabaro.vbhelper.screens.HomeScreen
+import com.github.nacabaro.vbhelper.screens.ScanScreen
+import com.github.nacabaro.vbhelper.screens.StorageScreen
+
+@Composable
+fun AppNavigation() {
+ val navController = rememberNavController()
+
+ Scaffold(
+ bottomBar = {
+ BottomNavigationBar(navController = navController)
+ }
+ ) { contentPadding ->
+ NavHost(
+ navController = navController,
+ startDestination = BottomNavItem.Home.route,
+ modifier = Modifier
+ .padding(contentPadding)
+ ) {
+ composable(BottomNavItem.Battles.route) {
+ BattlesScreen()
+ }
+ composable(BottomNavItem.Home.route) {
+ HomeScreen()
+ }
+ composable(BottomNavItem.Storage.route) {
+ StorageScreen()
+ }
+ composable(BottomNavItem.Scan.route) {
+ ScanScreen()
+ }
+ composable(BottomNavItem.Dex.route) {
+ DexScreen()
+ }
+ }
+ }
+}
A app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt +15 -0
@@ 0,0 1,15 @@
+package com.github.nacabaro.vbhelper.navigation
+
+import com.github.nacabaro.vbhelper.R
+
+sealed class BottomNavItem (
+ var route: String,
+ var icon: Int,
+ var label: String
+) {
+ object Scan : BottomNavItem("Scan", R.drawable.baseline_nfc_24, "Scan")
+ object Battles : BottomNavItem("Battles", R.drawable.baseline_swords_24, "Battles")
+ object Home : BottomNavItem("Home", R.drawable.baseline_cottage_24, "Home")
+ object Dex : BottomNavItem("Dex", R.drawable.baseline_menu_book_24, "Dex")
+ object Storage : BottomNavItem("Storage", R.drawable.baseline_catching_pokemon_24, "Storage")
+}<
\ No newline at end of file
A app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt +41 -0
@@ 0,0 1,41 @@
+package com.github.nacabaro.vbhelper.navigation
+
+import androidx.compose.material3.NavigationBar
+import androidx.compose.material3.NavigationBarItem
+import androidx.compose.material3.Text
+import androidx.compose.material3.Icon
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.res.painterResource
+import androidx.navigation.NavController
+import androidx.navigation.compose.currentBackStackEntryAsState
+
+
+@Composable
+fun BottomNavigationBar(navController: NavController) {
+ val items = listOf(
+ BottomNavItem.Scan,
+ BottomNavItem.Battles,
+ BottomNavItem.Home,
+ BottomNavItem.Dex,
+ BottomNavItem.Storage,
+ )
+ NavigationBar {
+ val currentBackStackEntry = navController.currentBackStackEntryAsState()
+ val currentRoute = currentBackStackEntry.value?.destination?.route
+
+ items.forEach { item ->
+ NavigationBarItem (
+ icon = { Icon(painter = painterResource(item.icon), contentDescription = item.label) },
+ label = { Text(item.label) },
+ selected = currentRoute == item.route,
+ onClick = {
+ navController.navigate(item.route) {
+ popUpTo(navController.graph.startDestinationId) { saveState = true }
+ launchSingleTop = true
+ restoreState = true
+ }
+ }
+ )
+ }
+ }
+}<
\ No newline at end of file
A app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt +9 -0
@@ 0,0 1,9 @@
+package com.github.nacabaro.vbhelper.screens
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+
+@Composable
+fun BattlesScreen() {
+ Text("Battles Screen")
+}
A app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +80 -0
@@ 0,0 1,80 @@
+package com.github.nacabaro.vbhelper.screens
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material3.Card
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import com.github.nacabaro.vbhelper.R
+import com.github.nacabaro.vbhelper.components.TopBanner
+
+@Composable
+fun DexScreen() {
+ Scaffold (
+ topBar = { TopBanner("Discovered Digimon") }
+ ) { contentPadding ->
+ LazyColumn (
+ modifier = Modifier
+ .padding(top = contentPadding.calculateTopPadding())
+ ) {
+ items(100) { i ->
+ DexDiMEntry(
+ name = "Digimon $i",
+ icon = R.drawable.baseline_egg_24,
+ onClick = {},
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ vertical = 8.dp,
+ horizontal = 16.dp
+ )
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun DexDiMEntry(
+ name: String,
+ icon: Int,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Card (
+ shape = MaterialTheme.shapes.medium,
+ modifier = modifier,
+ onClick = onClick
+ ) {
+ Row (
+ horizontalArrangement = Arrangement.Start,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(8.dp)
+ ) {
+ Image (
+ painter = painterResource(id = icon),
+ contentDescription = name,
+ modifier = Modifier
+ .padding(8.dp)
+ .size(64.dp)
+ )
+ Text(
+ text = name,
+ modifier = Modifier
+ .padding(8.dp)
+ )
+ }
+ }
+}<
\ No newline at end of file
A app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt +9 -0
@@ 0,0 1,9 @@
+package com.github.nacabaro.vbhelper.screens
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+
+@Composable
+fun HomeScreen() {
+ Text("Home Screen")
+}
A app/src/main/java/com/github/nacabaro/vbhelper/screens/ScanScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/ScanScreen.kt +68 -0
@@ 0,0 1,68 @@
+package com.github.nacabaro.vbhelper.screens
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+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.material3.Button
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.github.nacabaro.vbhelper.components.TopBanner
+
+@Composable
+fun ScanScreen() {
+ Scaffold (
+ topBar = { TopBanner(text = "Scan a Vital Bracelet") }
+ ) { contentPadding ->
+ Column(
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(contentPadding)
+ ) {
+ ScanButton(
+ text = "Vital Bracelet to App",
+ onClick = {}
+ )
+ Spacer(modifier = Modifier.height(16.dp))
+ ScanButton(
+ text = "App to Vital Bracelet",
+ onClick = {}
+ )
+ }
+ }
+}
+
+@Composable
+fun ScanButton(
+ text: String,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Button(
+ onClick = onClick,
+ modifier = modifier
+ ) {
+ Text(
+ text = text,
+ fontSize = 16.sp,
+ modifier = Modifier
+ .padding(4.dp)
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun ScanScreenPreview() {
+ ScanScreen()
+}<
\ No newline at end of file
A app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +78 -0
@@ 0,0 1,78 @@
+package com.github.nacabaro.vbhelper.screens
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.scrollable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.material3.Card
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import com.github.nacabaro.vbhelper.R
+import com.github.nacabaro.vbhelper.components.TopBanner
+
+@Composable
+fun StorageScreen() {
+ Scaffold (
+ topBar = { TopBanner(text = "My Digimon") }
+ ) { contentPadding ->
+ LazyVerticalGrid(
+ columns = GridCells.Fixed(3),
+ modifier = Modifier
+ .scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
+ .padding(top = contentPadding.calculateTopPadding())
+ ) {
+ items(100) { i ->
+ StorageEntry(
+ name = "Digimon $i",
+ icon = R.drawable.baseline_question_mark_24
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun StorageEntry(
+ name: String,
+ icon: Int,
+ modifier: Modifier = Modifier
+) {
+ Card (
+ shape = MaterialTheme.shapes.medium,
+ modifier = modifier
+ .padding(8.dp)
+ ) {
+ Column (
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxSize()
+ ) {
+ Image(
+ painter = painterResource(id = icon),
+ contentDescription = name,
+ modifier = Modifier
+ .padding(8.dp)
+ .size(64.dp)
+ )
+ Text(
+ text = name,
+ textAlign = TextAlign.Center,
+ modifier = Modifier
+ .padding(8.dp)
+ )
+ }
+ }
+}<
\ No newline at end of file
A app/src/main/res/drawable/baseline_catching_pokemon_24.xml => app/src/main/res/drawable/baseline_catching_pokemon_24.xml +5 -0
@@ 0,0 1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M14.5,12c0,1.38 -1.12,2.5 -2.5,2.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5C13.38,9.5 14.5,10.62 14.5,12zM22,12c0,5.52 -4.48,10 -10,10C6.48,22 2,17.52 2,12S6.48,2 12,2C17.52,2 22,6.48 22,12zM20,12h-4c0,-2.21 -1.79,-4 -4,-4c-2.21,0 -4,1.79 -4,4H4c0,4.41 3.59,8 8,8C16.41,20 20,16.41 20,12z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_cottage_24.xml => app/src/main/res/drawable/baseline_cottage_24.xml +5 -0
@@ 0,0 1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M12,3L6,7.58V6H4v3.11L1,11.4l1.21,1.59L4,11.62V21h7v-6h2v6h7v-9.38l1.79,1.36L23,11.4L12,3zM10,1c0,1.66 -1.34,3 -3,3C6.45,4 6,4.45 6,5H4c0,-1.66 1.34,-3 3,-3c0.55,0 1,-0.45 1,-1H10z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_egg_24.xml => app/src/main/res/drawable/baseline_egg_24.xml +5 -0
@@ 0,0 1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M12,3C8.5,3 5,9.33 5,14c0,3.87 3.13,7 7,7s7,-3.13 7,-7C19,9.33 15.5,3 12,3zM13,18c-3,0 -5,-1.99 -5,-5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1c0,2.92 2.42,3 3,3c0.55,0 1,0.45 1,1S13.55,18 13,18z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_menu_book_24.xml => app/src/main/res/drawable/baseline_menu_book_24.xml +11 -0
@@ 0,0 1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M21,5c-1.11,-0.35 -2.33,-0.5 -3.5,-0.5c-1.95,0 -4.05,0.4 -5.5,1.5c-1.45,-1.1 -3.55,-1.5 -5.5,-1.5S2.45,4.9 1,6v14.65c0,0.25 0.25,0.5 0.5,0.5c0.1,0 0.15,-0.05 0.25,-0.05C3.1,20.45 5.05,20 6.5,20c1.95,0 4.05,0.4 5.5,1.5c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.65,0 3.35,0.3 4.75,1.05c0.1,0.05 0.15,0.05 0.25,0.05c0.25,0 0.5,-0.25 0.5,-0.5V6C22.4,5.55 21.75,5.25 21,5zM21,18.5c-1.1,-0.35 -2.3,-0.5 -3.5,-0.5c-1.7,0 -4.15,0.65 -5.5,1.5V8c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.2,0 2.4,0.15 3.5,0.5V18.5z"/>
+
+ <path android:fillColor="@android:color/white" android:pathData="M17.5,10.5c0.88,0 1.73,0.09 2.5,0.26V9.24C19.21,9.09 18.36,9 17.5,9c-1.7,0 -3.24,0.29 -4.5,0.83v1.66C14.13,10.85 15.7,10.5 17.5,10.5z"/>
+
+ <path android:fillColor="@android:color/white" android:pathData="M13,12.49v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26V11.9c-0.79,-0.15 -1.64,-0.24 -2.5,-0.24C15.8,11.66 14.26,11.96 13,12.49z"/>
+
+ <path android:fillColor="@android:color/white" android:pathData="M17.5,14.33c-1.7,0 -3.24,0.29 -4.5,0.83v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26v-1.52C19.21,14.41 18.36,14.33 17.5,14.33z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_nfc_24.xml => app/src/main/res/drawable/baseline_nfc_24.xml +5 -0
@@ 0,0 1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M20,2L4,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,20L4,20L4,4h16v16zM18,6h-5c-1.1,0 -2,0.9 -2,2v2.28c-0.6,0.35 -1,0.98 -1,1.72 0,1.1 0.9,2 2,2s2,-0.9 2,-2c0,-0.74 -0.4,-1.38 -1,-1.72L13,8h3v8L8,16L8,8h2L10,6L6,6v12h12L18,6z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_question_mark_24.xml => app/src/main/res/drawable/baseline_question_mark_24.xml +5 -0
@@ 0,0 1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M11.07,12.85c0.77,-1.39 2.25,-2.21 3.11,-3.44c0.91,-1.29 0.4,-3.7 -2.18,-3.7c-1.69,0 -2.52,1.28 -2.87,2.34L6.54,6.96C7.25,4.83 9.18,3 11.99,3c2.35,0 3.96,1.07 4.78,2.41c0.7,1.15 1.11,3.3 0.03,4.9c-1.2,1.77 -2.35,2.31 -2.97,3.45c-0.25,0.46 -0.35,0.76 -0.35,2.24h-2.89C10.58,15.22 10.46,13.95 11.07,12.85zM14,20c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2S14,18.9 14,20z"/>
+
+</vector>
A app/src/main/res/drawable/baseline_swords_24.xml => app/src/main/res/drawable/baseline_swords_24.xml +9 -0
@@ 0,0 1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960">
+ <path
+ android:pathData="M762,864 L645,748l-88,88 -28,-28q-23,-23 -23,-57t23,-57l169,-169q23,-23 57,-23t57,23l28,28 -88,88 116,117q12,12 12,28t-12,28l-50,50q-12,12 -28,12t-28,-12ZM880,236L426,690l5,4q23,23 23,57t-23,57l-28,28 -88,-88L198,864q-12,12 -28,12t-28,-12l-50,-50q-12,-12 -12,-28t12,-28l116,-117 -88,-88 28,-28q23,-23 57,-23t57,23l4,5 454,-454h160v160ZM334,377l24,-23 23,-24 -23,24 -24,23ZM278,434L80,236v-160h160l198,198 -57,56 -174,-174h-47v47l174,174 -56,57ZM370,633 L800,203v-47h-47L323,586l47,47ZM370,633 L346,610 323,586 346,610 370,633Z"
+ android:fillColor="#000000"/>
+</vector>