浏览代码

添加跳转路由

cc12458 1 月之前
父节点
当前提交
c70889e83e

+ 1 - 0
.idea/gradle.xml

@@ -11,6 +11,7 @@
           <set>
             <option value="$PROJECT_DIR$" />
             <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/core" />
           </set>
         </option>
       </GradleProjectSettings>

+ 5 - 0
app/build.gradle.kts

@@ -2,6 +2,7 @@ plugins {
   alias(libs.plugins.android.application)
   alias(libs.plugins.kotlin.android)
   alias(libs.plugins.kotlin.compose)
+  alias(libs.plugins.kotlin.serialization)
 }
 
 android {
@@ -41,6 +42,8 @@ dependencies {
   implementation(libs.androidx.core.ktx)
   implementation(libs.androidx.lifecycle.runtime.ktx)
   implementation(libs.androidx.activity.compose)
+  implementation(libs.androidx.navigation.compose)
+  implementation(libs.serialization.json)
   implementation(platform(libs.androidx.compose.bom))
   implementation(libs.androidx.ui)
   implementation(libs.androidx.ui.graphics)
@@ -53,4 +56,6 @@ dependencies {
   androidTestImplementation(libs.androidx.ui.test.junit4)
   debugImplementation(libs.androidx.ui.tooling)
   debugImplementation(libs.androidx.ui.test.manifest)
+
+  implementation(project(":core"))
 }

+ 2 - 3
app/src/main/AndroidManifest.xml

@@ -10,13 +10,12 @@
       android:label="@string/app_name"
       android:roundIcon="@mipmap/ic_launcher_round"
       android:supportsRtl="true"
-      android:theme="@style/Theme.SixappletContainer"
+      android:theme="@style/Theme.Six"
       tools:targetApi="31">
     <activity
         android:name=".MainActivity"
         android:exported="true"
-        android:label="@string/app_name"
-        android:theme="@style/Theme.SixappletContainer">
+        android:theme="@style/Theme.Six">
       <intent-filter>
         <action android:name="android.intent.action.MAIN" />
 

+ 13 - 27
app/src/main/java/com/hzliuzhi/applet/container/MainActivity.kt

@@ -4,44 +4,30 @@ import android.os.Bundle
 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.tooling.preview.Preview
-import com.hzliuzhi.applet.container.ui.theme.SixappletContainerTheme
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.rememberNavController
+import com.hzliuzhi.applet.container.navigation.Host
+import com.hzliuzhi.applet.core.theme.SixTheme
 
 class MainActivity : ComponentActivity() {
+  private var navController: NavHostController? = null
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     enableEdgeToEdge()
     setContent {
-      SixappletContainerTheme {
-        Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
-          Greeting(
-            name = "Android",
-            modifier = Modifier.padding(innerPadding)
-          )
+      navController = rememberNavController().also {
+        SixTheme {
+          Scaffold() { padding ->
+            Host(
+              navController = it,
+              modifier = Modifier.padding(padding)
+            )
+          }
         }
       }
     }
   }
-}
-
-@Composable
-fun Greeting(name: String, modifier: Modifier = Modifier) {
-  Text(
-    text = "Hello $name!",
-    modifier = modifier
-  )
-}
-
-@Preview(showBackground = true)
-@Composable
-fun GreetingPreview() {
-  SixappletContainerTheme {
-    Greeting("Android")
-  }
 }

+ 35 - 0
app/src/main/java/com/hzliuzhi/applet/container/navigation/Host.kt

@@ -0,0 +1,35 @@
+package com.hzliuzhi.applet.container.navigation
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.rememberNavController
+import com.hzliuzhi.applet.container.R
+
+@Composable
+fun Host(
+  modifier: Modifier = Modifier,
+  navController: NavHostController = rememberNavController(),
+) {
+  NavHost(
+    startDestination = rememberRoute(),
+    navController = navController,
+    modifier = modifier.fillMaxSize(),
+  ) {
+    app(navController = navController)
+  }
+}
+
+@Composable
+fun rememberRoute(): Any {
+  val context = LocalContext.current.applicationContext
+  return remember {
+    runCatching {
+      context.resources.getString(R.string.app_screen).toRoute()
+    }.getOrNull() ?: AppRoute.Home
+  }
+}

+ 22 - 0
app/src/main/java/com/hzliuzhi/applet/container/navigation/Route.kt

@@ -0,0 +1,22 @@
+package com.hzliuzhi.applet.container.navigation
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import com.hzliuzhi.applet.container.ui.HomeScreen
+import kotlinx.serialization.Serializable
+
+sealed class AppRoute {
+  @Serializable
+  data object Home : AppRoute()
+}
+
+fun NavGraphBuilder.app(navController: NavController) {
+  composable<AppRoute.Home> { _ ->
+    HomeScreen(
+      modifier = Modifier.fillMaxSize()
+    )
+  }
+}

+ 17 - 0
app/src/main/java/com/hzliuzhi/applet/container/navigation/RouteExtra.kt

@@ -0,0 +1,17 @@
+package com.hzliuzhi.applet.container.navigation
+
+import com.hzliuzhi.applet.browser.navigation.BrowserRoute
+
+data class DeepLink(
+  val scheme: String = "six-applet://",
+)
+
+internal fun String?.toRoute(): Any? {
+  val value = this?.replace(DeepLink().scheme, "") ?: ""
+  return when {
+    value.startsWith("home") -> AppRoute.Home
+    value.startsWith("browser/web?url=") -> BrowserRoute.Web().copy(url = value.substringAfter("browser/web?url="))
+    value.startsWith("browser/kiosk?url=") -> BrowserRoute.Kiosk().copy(url = value.substringAfter("browser/kiosk?url="))
+    else -> null
+  }
+}

+ 26 - 0
app/src/main/java/com/hzliuzhi/applet/container/ui/HomeScreen.kt

@@ -0,0 +1,26 @@
+package com.hzliuzhi.applet.container.ui
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import com.hzliuzhi.applet.core.theme.SixTheme
+
+
+@Composable
+fun HomeScreen(
+  modifier: Modifier = Modifier,
+) {
+  Text(
+    text = "Hello Home!",
+    modifier = modifier
+  )
+}
+
+@Preview(showBackground = true)
+@Composable
+fun GreetingPreview() {
+  SixTheme {
+    HomeScreen()
+  }
+}

+ 4 - 0
app/src/main/res/values/route.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <string name="app_screen" />
+</resources>

+ 0 - 5
app/src/main/res/values/themes.xml

@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-  <style name="Theme.SixappletContainer" parent="android:Theme.Material.Light.NoActionBar" />
-</resources>

+ 1 - 0
build.gradle.kts

@@ -3,4 +3,5 @@ plugins {
   alias(libs.plugins.android.application) apply false
   alias(libs.plugins.kotlin.android) apply false
   alias(libs.plugins.kotlin.compose) apply false
+  alias(libs.plugins.android.library) apply false
 }

+ 1 - 0
core/.gitignore

@@ -0,0 +1 @@
+/build

+ 47 - 0
core/build.gradle.kts

@@ -0,0 +1,47 @@
+plugins {
+  alias(libs.plugins.android.library)
+  alias(libs.plugins.kotlin.android)
+  alias(libs.plugins.kotlin.compose)
+}
+
+android {
+  namespace = "com.hzliuzhi.applet.core"
+  compileSdk = 35
+
+  defaultConfig {
+    minSdk = 26
+
+    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+    consumerProguardFiles("consumer-rules.pro")
+  }
+
+  buildTypes {
+    release {
+      isMinifyEnabled = false
+      proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
+    }
+  }
+  compileOptions {
+    sourceCompatibility = JavaVersion.VERSION_11
+    targetCompatibility = JavaVersion.VERSION_11
+  }
+  kotlinOptions {
+    jvmTarget = "11"
+  }
+  buildFeatures {
+    compose = true
+  }
+}
+
+dependencies {
+
+  implementation(libs.androidx.core.ktx)
+  implementation(libs.androidx.appcompat)
+  implementation(platform(libs.androidx.compose.bom))
+  implementation(libs.androidx.ui)
+  implementation(libs.androidx.ui.graphics)
+  implementation(libs.androidx.material3)
+  testImplementation(libs.junit)
+  androidTestImplementation(libs.androidx.junit)
+  androidTestImplementation(libs.androidx.espresso.core)
+}

+ 0 - 0
core/consumer-rules.pro


+ 21 - 0
core/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 24 - 0
core/src/androidTest/java/com/hzliuzhi/applet/core/ExampleInstrumentedTest.kt

@@ -0,0 +1,24 @@
+package com.hzliuzhi.applet.core
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+  @Test
+  fun useAppContext() {
+    // Context of the app under test.
+    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+    assertEquals("com.hzliuzhi.applet.core.test", appContext.packageName)
+  }
+}

+ 4 - 0
core/src/main/AndroidManifest.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+</manifest>

+ 1 - 1
app/src/main/java/com/hzliuzhi/applet/container/ui/theme/Color.kt → core/src/main/java/com/hzliuzhi/applet/core/theme/Color.kt

@@ -1,4 +1,4 @@
-package com.hzliuzhi.applet.container.ui.theme
+package com.hzliuzhi.applet.core.theme
 
 import androidx.compose.ui.graphics.Color
 

+ 2 - 3
app/src/main/java/com/hzliuzhi/applet/container/ui/theme/Theme.kt → core/src/main/java/com/hzliuzhi/applet/core/theme/Theme.kt

@@ -1,6 +1,5 @@
-package com.hzliuzhi.applet.container.ui.theme
+package com.hzliuzhi.applet.core.theme
 
-import android.app.Activity
 import android.os.Build
 import androidx.compose.foundation.isSystemInDarkTheme
 import androidx.compose.material3.MaterialTheme
@@ -34,7 +33,7 @@ private val LightColorScheme = lightColorScheme(
 )
 
 @Composable
-fun SixappletContainerTheme(
+fun SixTheme(
   darkTheme: Boolean = isSystemInDarkTheme(),
   // Dynamic color is available on Android 12+
   dynamicColor: Boolean = true,

+ 1 - 1
app/src/main/java/com/hzliuzhi/applet/container/ui/theme/Type.kt → core/src/main/java/com/hzliuzhi/applet/core/theme/Type.kt

@@ -1,4 +1,4 @@
-package com.hzliuzhi.applet.container.ui.theme
+package com.hzliuzhi.applet.core.theme
 
 import androidx.compose.material3.Typography
 import androidx.compose.ui.text.TextStyle

+ 0 - 0
app/src/main/res/values/colors.xml → core/src/main/res/values/colors.xml


+ 4 - 0
core/src/main/res/values/themes.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <style name="Theme.Six" parent="android:Theme.Material.Light.NoActionBar" />
+</resources>

+ 17 - 0
core/src/test/java/com/hzliuzhi/applet/core/ExampleUnitTest.kt

@@ -0,0 +1,17 @@
+package com.hzliuzhi.applet.core
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+  @Test
+  fun addition_isCorrect() {
+    assertEquals(4, 2 + 2)
+  }
+}

+ 9 - 0
gradle/libs.versions.toml

@@ -1,6 +1,7 @@
 [versions]
 agp = "8.9.3"
 kotlin = "2.1.21"
+serializationJson = "1.7.3"
 coreKtx = "1.16.0"
 junit = "4.13.2"
 junitVersion = "1.2.1"
@@ -8,9 +9,12 @@ espressoCore = "3.6.1"
 lifecycleRuntimeKtx = "2.9.1"
 activityCompose = "1.10.1"
 composeBom = "2025.06.00"
+appcompat = "1.7.1"
+
 
 [libraries]
 androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
 junit = { group = "junit", name = "junit", version.ref = "junit" }
 androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
 androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@@ -24,9 +28,14 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
 androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
 androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
 androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+
+serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serializationJson" }
 
 [plugins]
 android-application = { id = "com.android.application", version.ref = "agp" }
+android-library = { id = "com.android.library", version.ref = "agp" }
 kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
 kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
 

+ 1 - 1
settings.gradle.kts

@@ -21,4 +21,4 @@ dependencyResolutionManagement {
 
 rootProject.name = "Six-applet.Container"
 include(":app")
- 
+include(":core")