fix: theme issues
This commit is contained in:
parent
61f37f71de
commit
d0fe216097
|
@ -65,6 +65,7 @@ dependencies {
|
||||||
implementation(libs.androidx.datastore.preferences.core.jvm)
|
implementation(libs.androidx.datastore.preferences.core.jvm)
|
||||||
implementation(libs.androidx.datastore.preferences)
|
implementation(libs.androidx.datastore.preferences)
|
||||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||||
|
implementation(libs.accompanist.systemuicontroller)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
|
|
@ -1,35 +1,29 @@
|
||||||
package icu.fur93.esp32_car
|
package icu.fur93.esp32_car
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import androidx.compose.ui.graphics.Color
|
||||||
import android.bluetooth.BluetoothAdapter
|
import android.app.Activity
|
||||||
import android.bluetooth.BluetoothGatt
|
|
||||||
import android.bluetooth.BluetoothGattCallback
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic
|
|
||||||
import android.bluetooth.BluetoothGattDescriptor
|
|
||||||
import android.bluetooth.le.BluetoothLeScanner
|
|
||||||
import android.bluetooth.le.ScanCallback
|
|
||||||
import android.bluetooth.le.ScanFilter
|
|
||||||
import android.bluetooth.le.ScanResult
|
|
||||||
import android.bluetooth.le.ScanSettings
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.os.ParcelUuid
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.SystemBarStyle
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
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.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
@ -44,12 +38,11 @@ import icu.fur93.esp32_car.page.ControlSingleJoystickModePage
|
||||||
import icu.fur93.esp32_car.page.HomePage
|
import icu.fur93.esp32_car.page.HomePage
|
||||||
import icu.fur93.esp32_car.page.SettingsPage
|
import icu.fur93.esp32_car.page.SettingsPage
|
||||||
import icu.fur93.esp32_car.repository.BluetoothRepositoryImpl
|
import icu.fur93.esp32_car.repository.BluetoothRepositoryImpl
|
||||||
|
import icu.fur93.esp32_car.ui.component.BottomNavigationBar
|
||||||
import icu.fur93.esp32_car.ui.theme.Esp32carTheme
|
import icu.fur93.esp32_car.ui.theme.Esp32carTheme
|
||||||
import icu.fur93.esp32_car.viewmodel.CarControlUseCase
|
import icu.fur93.esp32_car.viewmodel.CarControlUseCase
|
||||||
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
import java.util.UUID
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
private val preferencesDataStore by lazy {
|
private val preferencesDataStore by lazy {
|
||||||
|
@ -76,6 +69,17 @@ class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
enableEdgeToEdge(
|
||||||
|
statusBarStyle = SystemBarStyle.auto(
|
||||||
|
lightScrim = Color.Transparent.toArgb(), // 浅色主题下状态栏的微弱遮罩
|
||||||
|
darkScrim = Color.Transparent.toArgb(), // 深色主题下状态栏的微弱遮罩
|
||||||
|
),
|
||||||
|
navigationBarStyle = SystemBarStyle.auto(
|
||||||
|
lightScrim = Color.Transparent.toArgb(), // 浅色主题下导航栏的微弱遮罩
|
||||||
|
darkScrim = Color.Transparent.toArgb(), // 深色主题下导航栏的微弱遮罩
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// 设置全屏显示
|
// 设置全屏显示
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
window.attributes.layoutInDisplayCutoutMode =
|
window.attributes.layoutInDisplayCutoutMode =
|
||||||
|
@ -142,24 +146,51 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun App(viewModel: CarViewModel) {
|
fun App(viewModel: CarViewModel) {
|
||||||
val activity = LocalContext.current as MainActivity
|
|
||||||
activity.window.statusBarColor = MaterialTheme.colorScheme.background.toArgb()
|
|
||||||
|
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|
||||||
NavHost(
|
val isDarkTheme = isSystemInDarkTheme()
|
||||||
navController = navController,
|
val view = LocalView.current
|
||||||
startDestination = Route.Home.route
|
val window = (LocalContext.current as? MainActivity)?.window
|
||||||
) {
|
|
||||||
composable(Route.Home.route) { HomePage(navController, viewModel) }
|
DisposableEffect(isDarkTheme) {
|
||||||
composable(Route.Control.route) { ControlPage(navController, viewModel) }
|
window?.apply {
|
||||||
composable(Route.Settings.route) { SettingsPage(navController, viewModel) }
|
// 2. 设置导航栏颜色为透明
|
||||||
composable(Route.ControlPathfinderMode.route) { ControlPathfinderModePage(navController) }
|
navigationBarColor = Color.Transparent.toArgb()
|
||||||
composable(Route.ControlSingleJoystickMode.route) {
|
// 3. 根据主题设置导航栏图标颜色
|
||||||
ControlSingleJoystickModePage(
|
WindowCompat.getInsetsController(this, view).apply {
|
||||||
navController
|
isAppearanceLightNavigationBars = !isDarkTheme
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
composable(Route.ControlGamepadMode.route) { ControlGamepadModePage(navController) }
|
onDispose {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
bottomBar = {
|
||||||
|
BottomNavigationBar(navController)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
|
) { innerPadding ->
|
||||||
|
Box(Modifier.padding(innerPadding)) {
|
||||||
|
NavHost(
|
||||||
|
navController = navController,
|
||||||
|
startDestination = Route.Home.route
|
||||||
|
) {
|
||||||
|
composable(Route.Home.route) { HomePage(viewModel) }
|
||||||
|
composable(Route.Control.route) { ControlPage(viewModel) }
|
||||||
|
composable(Route.Settings.route) { SettingsPage(viewModel) }
|
||||||
|
composable(Route.ControlPathfinderMode.route) {
|
||||||
|
ControlPathfinderModePage(viewModel)
|
||||||
|
}
|
||||||
|
composable(Route.ControlSingleJoystickMode.route) {
|
||||||
|
ControlSingleJoystickModePage(viewModel)
|
||||||
|
}
|
||||||
|
composable(Route.ControlGamepadMode.route) { ControlGamepadModePage(viewModel) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,14 +1,8 @@
|
||||||
package icu.fur93.esp32_car.page
|
package icu.fur93.esp32_car.page
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.NavController
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
import icu.fur93.esp32_car.ui.layout.ControlModeLayout
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlGamepadModePage(navController: NavController) {
|
fun ControlGamepadModePage(viewModel: CarViewModel) {
|
||||||
ControlModeLayout(
|
|
||||||
content = {
|
|
||||||
},
|
|
||||||
onBack = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -1,14 +1,8 @@
|
||||||
package icu.fur93.esp32_car.page
|
package icu.fur93.esp32_car.page
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.NavController
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
import icu.fur93.esp32_car.ui.layout.ControlModeLayout
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlGyroscopeModePage(navController: NavController) {
|
fun ControlGyroscopeModePage(viewModel: CarViewModel) {
|
||||||
ControlModeLayout(
|
|
||||||
content = {
|
|
||||||
},
|
|
||||||
onBack = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package icu.fur93.esp32_car.page
|
package icu.fur93.esp32_car.page
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
@ -8,43 +9,30 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
|
||||||
import icu.fur93.esp32_car.R
|
import icu.fur93.esp32_car.R
|
||||||
import icu.fur93.esp32_car.Route
|
|
||||||
import icu.fur93.esp32_car.repository.ConnectionState
|
import icu.fur93.esp32_car.repository.ConnectionState
|
||||||
import icu.fur93.esp32_car.ui.card.UnconnectedStatusCard
|
import icu.fur93.esp32_car.ui.card.UnconnectedStatusCard
|
||||||
import icu.fur93.esp32_car.ui.component.BottomNavigationBar
|
|
||||||
import icu.fur93.esp32_car.ui.component.CardButtonGroup
|
import icu.fur93.esp32_car.ui.component.CardButtonGroup
|
||||||
import icu.fur93.esp32_car.ui.component.CardButtonItem
|
import icu.fur93.esp32_car.ui.component.CardButtonItem
|
||||||
import icu.fur93.esp32_car.ui.component.PageTitle
|
import icu.fur93.esp32_car.ui.component.PageTitle
|
||||||
import icu.fur93.esp32_car.ui.layout.MainLayout
|
|
||||||
import icu.fur93.esp32_car.ui.theme.LayoutContentModifier
|
import icu.fur93.esp32_car.ui.theme.LayoutContentModifier
|
||||||
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlPage(navController: NavHostController, viewModel: CarViewModel) {
|
fun ControlPage(viewModel: CarViewModel) {
|
||||||
val connectionState by viewModel.connectionState.collectAsState()
|
val connectionState by viewModel.connectionState.collectAsState()
|
||||||
|
|
||||||
MainLayout(
|
Column(LayoutContentModifier) {
|
||||||
content = {
|
PageTitle("控制")
|
||||||
Column (LayoutContentModifier) {
|
if (connectionState == ConnectionState.CONNECTED) {
|
||||||
PageTitle("控制")
|
ControlPageStatusCard()
|
||||||
if (connectionState == ConnectionState.CONNECTED) {
|
} else {
|
||||||
ControlPageStatusCard()
|
UnconnectedStatusCard(viewModel)
|
||||||
} else {
|
|
||||||
UnconnectedStatusCard(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bottomBar = {
|
|
||||||
BottomNavigationBar(
|
|
||||||
currentRoute = Route.Control.route,
|
|
||||||
navController = navController
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -56,12 +44,16 @@ fun ControlPageStatusCard() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlPageAutoControl() {
|
fun ControlPageAutoControl() {
|
||||||
|
val context = LocalContext.current
|
||||||
return CardButtonGroup(
|
return CardButtonGroup(
|
||||||
title = "自动控制",
|
title = "自动控制",
|
||||||
buttons = listOf(
|
buttons = listOf(
|
||||||
CardButtonItem(
|
CardButtonItem(
|
||||||
text = "循迹模式",
|
text = "循迹模式",
|
||||||
icon = ImageVector.vectorResource(R.drawable.outline_route_24)
|
icon = ImageVector.vectorResource(R.drawable.outline_route_24),
|
||||||
|
onClick = {
|
||||||
|
Toast.makeText(context, "暂未实现", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -69,6 +61,7 @@ fun ControlPageAutoControl() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlPageManualControl() {
|
fun ControlPageManualControl() {
|
||||||
|
val context = LocalContext.current
|
||||||
CardButtonGroup(
|
CardButtonGroup(
|
||||||
title = "手动控制",
|
title = "手动控制",
|
||||||
buttons = listOf(
|
buttons = listOf(
|
||||||
|
@ -82,7 +75,10 @@ fun ControlPageManualControl() {
|
||||||
),
|
),
|
||||||
CardButtonItem(
|
CardButtonItem(
|
||||||
text = "陀螺仪模式",
|
text = "陀螺仪模式",
|
||||||
icon = ImageVector.vectorResource(R.drawable.motion_sensor_active_24)
|
icon = ImageVector.vectorResource(R.drawable.motion_sensor_active_24),
|
||||||
|
onClick = {
|
||||||
|
Toast.makeText(context, "暂未实现", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
package icu.fur93.esp32_car.page
|
package icu.fur93.esp32_car.page
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.NavController
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
import icu.fur93.esp32_car.ui.layout.ControlModeLayout
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlPathfinderModePage(navController: NavController) {
|
fun ControlPathfinderModePage(viewModel: CarViewModel) {
|
||||||
ControlModeLayout(
|
|
||||||
content = {
|
|
||||||
},
|
|
||||||
onBack = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -1,14 +1,8 @@
|
||||||
package icu.fur93.esp32_car.page
|
package icu.fur93.esp32_car.page
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.NavController
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
import icu.fur93.esp32_car.ui.layout.ControlModeLayout
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlSingleJoystickModePage(navController: NavController) {
|
fun ControlSingleJoystickModePage(viewModel: CarViewModel) {
|
||||||
ControlModeLayout(
|
|
||||||
content = {
|
|
||||||
},
|
|
||||||
onBack = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -12,42 +12,30 @@ import icu.fur93.esp32_car.ui.carditem.StatusCardInfo
|
||||||
import icu.fur93.esp32_car.ui.carditem.StatusCardInfraredStatus
|
import icu.fur93.esp32_car.ui.carditem.StatusCardInfraredStatus
|
||||||
import icu.fur93.esp32_car.ui.carditem.StatusCardMotorStatus
|
import icu.fur93.esp32_car.ui.carditem.StatusCardMotorStatus
|
||||||
import icu.fur93.esp32_car.ui.carditem.StatusCardUltrasoundStatus
|
import icu.fur93.esp32_car.ui.carditem.StatusCardUltrasoundStatus
|
||||||
import icu.fur93.esp32_car.ui.component.BottomNavigationBar
|
|
||||||
import icu.fur93.esp32_car.ui.component.PageTitle
|
import icu.fur93.esp32_car.ui.component.PageTitle
|
||||||
import icu.fur93.esp32_car.ui.component.StatusCard
|
import icu.fur93.esp32_car.ui.component.StatusCard
|
||||||
import icu.fur93.esp32_car.ui.layout.MainLayout
|
|
||||||
import icu.fur93.esp32_car.ui.theme.LayoutContentModifier
|
import icu.fur93.esp32_car.ui.theme.LayoutContentModifier
|
||||||
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomePage(navController: NavHostController, viewModel: CarViewModel) {
|
fun HomePage(viewModel: CarViewModel) {
|
||||||
val connectionState by viewModel.connectionState.collectAsState()
|
val connectionState by viewModel.connectionState.collectAsState()
|
||||||
|
|
||||||
MainLayout(
|
Column(LayoutContentModifier) {
|
||||||
content = {
|
PageTitle("标题还没想好")
|
||||||
Column(LayoutContentModifier) {
|
if (connectionState == ConnectionState.CONNECTED) {
|
||||||
PageTitle("标题还没想好")
|
HomePageStatusCard(viewModel)
|
||||||
if (connectionState == ConnectionState.CONNECTED) {
|
} else {
|
||||||
HomePageStatusCard(viewModel)
|
UnconnectedStatusCard(viewModel)
|
||||||
} else {
|
|
||||||
UnconnectedStatusCard(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bottomBar = {
|
|
||||||
BottomNavigationBar(
|
|
||||||
currentRoute = Route.Home.route,
|
|
||||||
navController = navController
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomePageStatusCard(viewModel: CarViewModel) {
|
fun HomePageStatusCard(viewModel: CarViewModel) {
|
||||||
val deviceInfo by viewModel.connectionInfoState.collectAsState()
|
val deviceInfo by viewModel.connectionInfoState.collectAsState()
|
||||||
val carState by viewModel.carState.collectAsState()
|
val carState by viewModel.carState.collectAsState()
|
||||||
|
|
||||||
StatusCard(
|
StatusCard(
|
||||||
cardItems = listOf(
|
cardItems = listOf(
|
||||||
StatusCardInfo(deviceInfo),
|
StatusCardInfo(deviceInfo),
|
||||||
|
|
|
@ -21,41 +21,28 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import icu.fur93.esp32_car.R
|
import icu.fur93.esp32_car.R
|
||||||
import icu.fur93.esp32_car.Route
|
|
||||||
import icu.fur93.esp32_car.repository.BluetoothRepositoryImpl
|
import icu.fur93.esp32_car.repository.BluetoothRepositoryImpl
|
||||||
import icu.fur93.esp32_car.repository.ConnectionState
|
import icu.fur93.esp32_car.repository.ConnectionState
|
||||||
import icu.fur93.esp32_car.ui.component.BottomNavigationBar
|
|
||||||
import icu.fur93.esp32_car.ui.component.PageTitle
|
import icu.fur93.esp32_car.ui.component.PageTitle
|
||||||
import icu.fur93.esp32_car.ui.dialog.BleDeviceScanDialog
|
import icu.fur93.esp32_car.ui.dialog.BleDeviceScanDialog
|
||||||
import icu.fur93.esp32_car.ui.layout.MainLayout
|
|
||||||
import icu.fur93.esp32_car.ui.theme.LayoutContentPadding
|
import icu.fur93.esp32_car.ui.theme.LayoutContentPadding
|
||||||
import icu.fur93.esp32_car.ui.theme.LayoutTopPadding
|
import icu.fur93.esp32_car.ui.theme.LayoutTopPadding
|
||||||
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
import icu.fur93.esp32_car.viewmodel.CarViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsPage(navController: NavHostController, viewModel: CarViewModel) {
|
fun SettingsPage(viewModel: CarViewModel) {
|
||||||
MainLayout(
|
Column {
|
||||||
content = {
|
Column(
|
||||||
Column {
|
Modifier.padding(
|
||||||
Column (
|
top = LayoutTopPadding,
|
||||||
Modifier.padding(
|
start = LayoutContentPadding,
|
||||||
top = LayoutTopPadding,
|
end = LayoutContentPadding
|
||||||
start = LayoutContentPadding,
|
|
||||||
end = LayoutContentPadding
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
PageTitle("设置")
|
|
||||||
}
|
|
||||||
SettingsList(viewModel)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bottomBar = {
|
|
||||||
BottomNavigationBar(
|
|
||||||
currentRoute = Route.Settings.route,
|
|
||||||
navController = navController
|
|
||||||
)
|
)
|
||||||
|
) {
|
||||||
|
PageTitle("设置")
|
||||||
}
|
}
|
||||||
)
|
SettingsList(viewModel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -101,14 +88,18 @@ fun SettingsList(viewModel: CarViewModel) {
|
||||||
fun SettingConnectDeviceItem(viewModel: CarViewModel) {
|
fun SettingConnectDeviceItem(viewModel: CarViewModel) {
|
||||||
var showScanDialog by remember { mutableStateOf(false) }
|
var showScanDialog by remember { mutableStateOf(false) }
|
||||||
var showDisconnectDialog by remember { mutableStateOf(false) }
|
var showDisconnectDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val connectionState by viewModel.connectionState.collectAsState()
|
val connectionState by viewModel.connectionState.collectAsState()
|
||||||
val connectionInfoState by viewModel.connectionInfoState.collectAsState()
|
val connectionInfoState by viewModel.connectionInfoState.collectAsState()
|
||||||
|
|
||||||
|
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text("连接设备") },
|
headlineContent = { Text("连接设备") },
|
||||||
supportingContent = { if (connectionState == ConnectionState.CONNECTED) Text("已连接") else Text("未连接") },
|
supportingContent = {
|
||||||
|
if (connectionState == ConnectionState.CONNECTED) Text("已连接") else Text(
|
||||||
|
"未连接"
|
||||||
|
)
|
||||||
|
},
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
Icon(
|
Icon(
|
||||||
ImageVector.vectorResource(R.drawable.arrow_right_24),
|
ImageVector.vectorResource(R.drawable.arrow_right_24),
|
||||||
|
|
|
@ -8,14 +8,17 @@ import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material.icons.outlined.Home
|
import androidx.compose.material.icons.outlined.Home
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.NavigationBar
|
import androidx.compose.material3.NavigationBar
|
||||||
import androidx.compose.material3.NavigationBarItem
|
import androidx.compose.material3.NavigationBarItem
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavOptions
|
|
||||||
import icu.fur93.esp32_car.Route
|
import icu.fur93.esp32_car.Route
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
data class BottomNavigationItem(
|
data class BottomNavigationItem(
|
||||||
val title: String,
|
val title: String,
|
||||||
|
@ -26,7 +29,6 @@ data class BottomNavigationItem(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar(
|
fun BottomNavigationBar(
|
||||||
currentRoute: String,
|
|
||||||
navController: NavHostController
|
navController: NavHostController
|
||||||
) {
|
) {
|
||||||
val navItems = listOf(
|
val navItems = listOf(
|
||||||
|
@ -50,12 +52,25 @@ fun BottomNavigationBar(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationBar() {
|
val currentRoute = navController
|
||||||
navItems.forEachIndexed{ _, item ->
|
.currentBackStackEntryFlow
|
||||||
|
.collectAsState(initial = navController.currentBackStackEntry)
|
||||||
|
.value?.destination?.route
|
||||||
|
|
||||||
|
NavigationBar(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
|
) {
|
||||||
|
navItems.forEachIndexed { _, item ->
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
icon = { Icon(if (currentRoute == item.route.route) item.selectedIcon else item.icon, item.title) },
|
icon = {
|
||||||
|
Icon(
|
||||||
|
if ((currentRoute
|
||||||
|
?: "").startsWith(item.route.route)
|
||||||
|
) item.selectedIcon else item.icon, item.title
|
||||||
|
)
|
||||||
|
},
|
||||||
label = { Text(item.title) },
|
label = { Text(item.title) },
|
||||||
selected = currentRoute == item.route.route,
|
selected = (currentRoute?:"").startsWith(item.route.route),
|
||||||
onClick = {
|
onClick = {
|
||||||
navController.navigate(item.route.route)
|
navController.navigate(item.route.route)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,21 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import icu.fur93.esp32_car.ui.theme.CardButtonTypography
|
||||||
|
|
||||||
data class CardButtonItem(
|
data class CardButtonItem(
|
||||||
val text: String,
|
val text: String,
|
||||||
|
@ -46,53 +51,27 @@ fun CardButtonGroup(
|
||||||
verticalArrangement = Arrangement.spacedBy(CardButtonGroupGap)
|
verticalArrangement = Arrangement.spacedBy(CardButtonGroupGap)
|
||||||
) {
|
) {
|
||||||
items(buttons.size) { index ->
|
items(buttons.size) { index ->
|
||||||
M3CardButton(buttons[index])
|
CardButton(buttons[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun M3CardButton(item: CardButtonItem) {
|
|
||||||
ElevatedCard(
|
|
||||||
modifier = item.modifier ?: Modifier
|
|
||||||
) {
|
|
||||||
FilledTonalButton(
|
|
||||||
onClick = { item.onClick?.invoke() },
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = item.text,
|
|
||||||
style = MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
contentAlignment = Alignment.CenterEnd
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = item.icon,
|
|
||||||
contentDescription = item.text,
|
|
||||||
modifier = Modifier.size(24.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 原代码注释
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CardButton(
|
fun CardButton(
|
||||||
item: CardButtonItem
|
item: CardButtonItem
|
||||||
) {
|
) {
|
||||||
Card {
|
Button(
|
||||||
|
onClick = { item.onClick?.invoke() },
|
||||||
|
shape = MaterialTheme.shapes.medium,
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
contentColor = MaterialTheme.colorScheme.contentColorFor(MaterialTheme.colorScheme.surfaceVariant)
|
||||||
|
)
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth().padding(12.dp),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 10.dp, bottom = 10.dp),
|
||||||
verticalArrangement = Arrangement.SpaceBetween
|
verticalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
|
@ -107,10 +86,10 @@ fun CardButton(
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = item.icon,
|
imageVector = item.icon,
|
||||||
contentDescription = item.text,
|
contentDescription = item.text,
|
||||||
modifier = Modifier.size(24.dp)
|
modifier = Modifier.size(24.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
|
@ -24,7 +24,9 @@ fun StatusCard(
|
||||||
cardItems: List<CardItem>,
|
cardItems: List<CardItem>,
|
||||||
bottomControl: @Composable() (() -> Unit?)? = null
|
bottomControl: @Composable() (() -> Unit?)? = null
|
||||||
) {
|
) {
|
||||||
Card (Modifier.fillMaxWidth()) {
|
Card (
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
Column(Modifier.fillMaxWidth().padding(20.dp)) {
|
Column(Modifier.fillMaxWidth().padding(20.dp)) {
|
||||||
cardItems.forEachIndexed { index, item ->
|
cardItems.forEachIndexed { index, item ->
|
||||||
StatusCardTitle(item.title)
|
StatusCardTitle(item.title)
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package icu.fur93.esp32_car.ui.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ControlModeLayout(
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
onBack: () -> Unit
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Box(modifier = Modifier.weight(1f)) {
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package icu.fur93.esp32_car.ui.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MainLayout(
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
bottomBar: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
bottomBar = bottomBar
|
|
||||||
) { innerPadding ->
|
|
||||||
Box(Modifier.padding(innerPadding)) {
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,6 +14,7 @@ datastoreCoreAndroid = "1.1.1"
|
||||||
datastorePreferencesCoreJvm = "1.1.1"
|
datastorePreferencesCoreJvm = "1.1.1"
|
||||||
datastorePreferences = "1.1.1"
|
datastorePreferences = "1.1.1"
|
||||||
lifecycleViewmodelCompose = "2.9.0-alpha08"
|
lifecycleViewmodelCompose = "2.9.0-alpha08"
|
||||||
|
accompanistSystemuicontroller = "0.36.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
@ -36,6 +37,7 @@ androidx-datastore-core-android = { group = "androidx.datastore", name = "datast
|
||||||
androidx-datastore-preferences-core-jvm = { group = "androidx.datastore", name = "datastore-preferences-core-jvm", version.ref = "datastorePreferencesCoreJvm" }
|
androidx-datastore-preferences-core-jvm = { group = "androidx.datastore", name = "datastore-preferences-core-jvm", version.ref = "datastorePreferencesCoreJvm" }
|
||||||
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }
|
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version = "2.7.0" }
|
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version = "2.7.0" }
|
||||||
|
accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanistSystemuicontroller" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|
Loading…
Reference in New Issue