优化性能
This commit is contained in:
@@ -204,6 +204,7 @@ fun MyTable(
|
||||
ratio: List<Float>,
|
||||
items: List<List<Any>>,
|
||||
verticalPadding: Dp = 5.dp,
|
||||
itemKey: ((List<Any>, Int) -> Any)? = null,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
TableHeadLine(
|
||||
@@ -211,7 +212,13 @@ fun MyTable(
|
||||
list = headerStrings.zip(ratio.map { it.toInt() })
|
||||
)
|
||||
LazyColumn {
|
||||
items(count = items.size) { itIndex ->
|
||||
items(
|
||||
count = items.size,
|
||||
key = { index ->
|
||||
itemKey?.invoke(items[index], index)
|
||||
?: items[index].joinToString(separator = "|") { it.toString() } + "#$index"
|
||||
}
|
||||
) { itIndex ->
|
||||
TableContent(
|
||||
verticalPadding = verticalPadding,
|
||||
modifier = M
|
||||
@@ -317,6 +324,7 @@ fun <T : Any> MyAnyTable(
|
||||
|
||||
// 每行
|
||||
info: List<T>,
|
||||
itemKey: ((T) -> Any)? = null,
|
||||
onLongClick: (T) -> Unit = {},
|
||||
onClick: (T) -> Unit = {},
|
||||
|
||||
@@ -330,7 +338,10 @@ fun <T : Any> MyAnyTable(
|
||||
)
|
||||
var selectIndex by rememberSaveable { mutableStateOf(-1) }
|
||||
LazyColumn {
|
||||
items(count = info.size) { index ->
|
||||
items(
|
||||
count = info.size,
|
||||
key = { index -> itemKey?.invoke(info[index]) ?: "${info[index].hashCode()}-$index" }
|
||||
) { index ->
|
||||
// 每行
|
||||
val lineItem = info[index]
|
||||
Card(
|
||||
@@ -418,6 +429,7 @@ fun <T : Any> MyTable2(
|
||||
modifier: Modifier = Modifier,
|
||||
infos: List<T>,
|
||||
items: List<MyTableData<T>>,
|
||||
itemKey: ((T) -> Any)? = null,
|
||||
onLongClick: (T) -> Unit = {},
|
||||
onClick: (T) -> Unit = {},
|
||||
onExpend: @Composable (T) -> Unit = {},
|
||||
@@ -433,7 +445,10 @@ fun <T : Any> MyTable2(
|
||||
var selectIndex by rememberSaveable { mutableStateOf(-1) }
|
||||
|
||||
LazyColumn {
|
||||
items(count = infos.size) { index ->
|
||||
items(
|
||||
count = infos.size,
|
||||
key = { index -> itemKey?.invoke(infos[index]) ?: "${infos[index].hashCode()}-$index" }
|
||||
) { index ->
|
||||
val lineItem = infos[index]
|
||||
|
||||
Card(
|
||||
|
||||
@@ -172,15 +172,9 @@ fun MyButton(
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
if (enabled) {
|
||||
onClick()
|
||||
} else {
|
||||
Toasty.showToast("正在开发中,敬请期待")
|
||||
}
|
||||
},
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
enabled = true,
|
||||
enabled = enabled,
|
||||
interactionSource = interactionSource,
|
||||
shape = shape,
|
||||
border = border,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
package com.bbitcn.f8.pad.receiver
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -35,10 +37,15 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
private val _signalStrength = MutableStateFlow(0)
|
||||
val signalStrength = _signalStrength.asStateFlow()
|
||||
|
||||
private val _bluetoothEnabled = MutableStateFlow(false)
|
||||
val bluetoothEnabled = _bluetoothEnabled.asStateFlow()
|
||||
|
||||
private val connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
private val telephonyManager =
|
||||
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
private val bluetoothManager =
|
||||
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
|
||||
/**
|
||||
* 信号强度监听器
|
||||
@@ -78,6 +85,12 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
private val bluetoothReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context?, intent: Intent?) {
|
||||
refreshBluetoothStatus()
|
||||
}
|
||||
}
|
||||
|
||||
fun register() {
|
||||
val batteryIntentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
|
||||
@@ -85,10 +98,15 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
batteryReceiver,
|
||||
batteryIntentFilter
|
||||
)
|
||||
context.registerReceiverCompat(
|
||||
bluetoothReceiver,
|
||||
IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
|
||||
)
|
||||
|
||||
connectivityManager.registerDefaultNetworkCallback(networkCallback)
|
||||
registerSignalStrengthListener()
|
||||
refreshNetworkStatus()
|
||||
refreshBluetoothStatus()
|
||||
// 开始轮询网络状态 防止状态假死
|
||||
PollingTask.getInstance("SystemInfoReceiver").startPollingTaskOnIOThread("NetworkStatusPolling",30_000) {
|
||||
refreshNetworkStatus()
|
||||
@@ -97,6 +115,11 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
|
||||
fun unregister() {
|
||||
context.unregisterReceiver(batteryReceiver)
|
||||
runCatching {
|
||||
context.unregisterReceiver(bluetoothReceiver)
|
||||
}.onFailure {
|
||||
MyLog.appError("取消蓝牙监听失败:${it.message}")
|
||||
}
|
||||
runCatching {
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}.onFailure {
|
||||
@@ -159,6 +182,12 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshBluetoothStatus() {
|
||||
_bluetoothEnabled.value = runCatching {
|
||||
bluetoothManager.adapter?.isEnabled == true
|
||||
}.getOrDefault(false)
|
||||
}
|
||||
|
||||
private fun registerSignalStrengthListener() {
|
||||
runCatching {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
|
||||
@@ -181,7 +181,7 @@ fun TabPagerScreen(
|
||||
}
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
beyondViewportPageCount = tabs.size,
|
||||
beyondViewportPageCount = 1,
|
||||
modifier = M
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
|
||||
@@ -19,14 +19,13 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import com.bbitcn.f8.pad.M
|
||||
@@ -48,7 +47,6 @@ import com.bbitcn.f8.pad.ui.screen.mainFunc.UserScreen
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||
import com.bbitcn.f8.pad.ui.viewmodel.UpdateViewModel
|
||||
import com.cyberecho.ui.screen.ChatDialog
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Preview(showBackground = true, widthDp = 1280)
|
||||
@@ -75,41 +73,13 @@ fun MainScreen(
|
||||
}
|
||||
Box(modifier = M.fillMaxWidth(), contentAlignment = Alignment.BottomStart) {
|
||||
var selectedPage by rememberSaveable { mutableStateOf(0) }
|
||||
var contentPage by rememberSaveable { mutableStateOf(0) }
|
||||
var isSwitchingPage by remember { mutableStateOf(false) }
|
||||
val cachedPages = remember { mutableStateListOf<Int>() }
|
||||
val pageStateHolder = rememberSaveableStateHolder()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val menu by mainViewModel.menu.collectAsState()
|
||||
LaunchedEffect(menu, selectedPage) {
|
||||
if (menu.isEmpty()) {
|
||||
contentPage = 0
|
||||
isSwitchingPage = false
|
||||
cachedPages.clear()
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
val safeSelectedPage = selectedPage.coerceIn(0, menu.lastIndex)
|
||||
if (safeSelectedPage != selectedPage) {
|
||||
selectedPage = safeSelectedPage
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
cachedPages.removeAll { it !in menu.indices }
|
||||
if (cachedPages.isEmpty()) {
|
||||
cachedPages.add(safeSelectedPage)
|
||||
}
|
||||
|
||||
if (contentPage != safeSelectedPage && safeSelectedPage !in cachedPages) {
|
||||
isSwitchingPage = true
|
||||
withFrameNanos { }
|
||||
delay(180)
|
||||
cachedPages.add(safeSelectedPage)
|
||||
contentPage = safeSelectedPage
|
||||
isSwitchingPage = false
|
||||
} else if (contentPage != safeSelectedPage) {
|
||||
contentPage = safeSelectedPage
|
||||
isSwitchingPage = false
|
||||
LaunchedEffect(menu) {
|
||||
if (menu.isNotEmpty() && selectedPage !in menu.indices) {
|
||||
selectedPage = selectedPage.coerceIn(0, menu.lastIndex)
|
||||
}
|
||||
}
|
||||
Row(modifier = M.fillMaxWidth()) {
|
||||
@@ -137,24 +107,14 @@ fun MainScreen(
|
||||
onClick = {
|
||||
if (selectedPage != index) {
|
||||
selectedPage = index
|
||||
isSwitchingPage = index !in cachedPages
|
||||
if (index in cachedPages) {
|
||||
contentPage = index
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Box(modifier = M.weight(1f).fillMaxSize()) {
|
||||
val selectedMenu = menu.getOrNull(selectedPage)
|
||||
if (isSwitchingPage && selectedMenu != null && selectedPage !in cachedPages) {
|
||||
MainPageLoading(selectedMenu.title)
|
||||
} else {
|
||||
cachedPages.forEach { page ->
|
||||
key(page) {
|
||||
val pageIndex = menu.getOrNull(page)?.index ?: -1
|
||||
MainPageHost(visible = page == contentPage) {
|
||||
val pageIndex = menu.getOrNull(selectedPage)?.index ?: -1
|
||||
pageStateHolder.SaveableStateProvider(pageIndex) {
|
||||
MainPageContent(
|
||||
index = pageIndex,
|
||||
navController = navController,
|
||||
@@ -166,9 +126,6 @@ fun MainScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = M
|
||||
.width(70.dp)
|
||||
@@ -246,39 +203,6 @@ fun MainScreen(
|
||||
ChatDialog(chatDialogData)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainPageLoading(title: String) {
|
||||
Box(modifier = M.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text(
|
||||
text = "正在加载$title...",
|
||||
color = MyColors.Gray,
|
||||
fontSize = MaterialTheme.typography.bodyLarge.fontSize
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainPageHost(
|
||||
visible: Boolean,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = if (visible) {
|
||||
M
|
||||
.fillMaxSize()
|
||||
.alpha(1f)
|
||||
.zIndex(1f)
|
||||
} else {
|
||||
M
|
||||
.size(0.dp)
|
||||
.alpha(0f)
|
||||
.zIndex(0f)
|
||||
}
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainPageContent(
|
||||
index: Int,
|
||||
|
||||
@@ -43,7 +43,6 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.bbitcn.f8.pad.M
|
||||
import com.bbitcn.f8.pad.R
|
||||
import com.bbitcn.f8.pad.base.WhiteText
|
||||
import com.bbitcn.f8.pad.base.isBluetoothEnabled
|
||||
import com.bbitcn.f8.pad.receiver.SystemInfoReceiver
|
||||
import com.bbitcn.f8.pad.ui.screen.view.drawer.DrawerViewModel
|
||||
import com.bbitcn.f8.pad.ui.theme.MyColors
|
||||
@@ -81,8 +80,6 @@ fun MyTopBar(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val systemInfoReceiver = remember { SystemInfoReceiver(context) }
|
||||
val date by topInfoViewModel.date.collectAsState()
|
||||
val time by topInfoViewModel.time.collectAsState()
|
||||
val logoState by topInfoViewModel.logoState.collectAsState()
|
||||
val versionName = remember { MyUtil.getVersionName() }
|
||||
|
||||
@@ -98,9 +95,33 @@ fun MyTopBar(
|
||||
.height(45.dp)
|
||||
.background(color = MyColors.Black),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
TopBarLogoTitle(
|
||||
logoState = logoState,
|
||||
versionName = versionName,
|
||||
navController = navController,
|
||||
topInfoViewModel = topInfoViewModel
|
||||
)
|
||||
Spacer(modifier = M.weight(1f))
|
||||
if (curPageName != "login") {
|
||||
TopBarStatusArea(
|
||||
drawerViewModel = drawerViewModel,
|
||||
topInfoViewModel = topInfoViewModel,
|
||||
systemInfoReceiver = systemInfoReceiver
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopBarLogoTitle(
|
||||
logoState: Pair<Pair<Int, String>, Int>,
|
||||
versionName: String,
|
||||
navController: NavController,
|
||||
topInfoViewModel: TopInfoViewModel
|
||||
) {
|
||||
AnimatedContent(
|
||||
logoState,
|
||||
targetState = logoState,
|
||||
transitionSpec = {
|
||||
EnterTransition.None togetherWith ExitTransition.None
|
||||
},
|
||||
@@ -109,13 +130,11 @@ fun MyTopBar(
|
||||
indication = null
|
||||
) {
|
||||
if (logoState.first.first != R.drawable.logo_white) {
|
||||
// 当前页面
|
||||
// val curPage = navController.currentDestination?.route ?: "main"
|
||||
// Toasty.setCurPage(curPage)
|
||||
topInfoViewModel.toScreen()
|
||||
navController.popBackStack()
|
||||
}
|
||||
},
|
||||
label = "topBarLogo"
|
||||
) {
|
||||
Image(
|
||||
modifier = M
|
||||
@@ -129,7 +148,8 @@ fun MyTopBar(
|
||||
targetState = logoState,
|
||||
transitionSpec = {
|
||||
EnterTransition.None togetherWith ExitTransition.None
|
||||
}, label = "animated content"
|
||||
},
|
||||
label = "topBarTitle"
|
||||
) { value ->
|
||||
Row(verticalAlignment = Alignment.Bottom) {
|
||||
Text(
|
||||
@@ -146,25 +166,19 @@ fun MyTopBar(
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Spacer(modifier = M.weight(1f))
|
||||
if (curPageName != "login") {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopBarStatusArea(
|
||||
drawerViewModel: DrawerViewModel,
|
||||
topInfoViewModel: TopInfoViewModel,
|
||||
systemInfoReceiver: SystemInfoReceiver
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val padding = M.padding(horizontal = 5.dp)
|
||||
// Image(
|
||||
// modifier = M
|
||||
// .clickable{
|
||||
// topInfoViewModel.getFrpNewVersion()
|
||||
// }
|
||||
// .padding(end = 5.dp)
|
||||
// .size(25.dp),
|
||||
// painter = painterResource(id = R.drawable.icon_sos),
|
||||
// contentDescription = "frp",
|
||||
// )
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 5.dp)
|
||||
@@ -172,95 +186,81 @@ fun MyTopBar(
|
||||
painter = painterResource(id = R.drawable.icon_lock),
|
||||
contentDescription = "screen_lock",
|
||||
)
|
||||
DeviceStatusCluster(
|
||||
drawerViewModel = drawerViewModel,
|
||||
topInfoViewModel = topInfoViewModel,
|
||||
systemInfoReceiver = systemInfoReceiver
|
||||
)
|
||||
TopBarClock(topInfoViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DeviceStatusCluster(
|
||||
drawerViewModel: DrawerViewModel,
|
||||
topInfoViewModel: TopInfoViewModel,
|
||||
systemInfoReceiver: SystemInfoReceiver
|
||||
) {
|
||||
Row(
|
||||
modifier = M.clickable { drawerViewModel.openSetDrawer() },
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isBluetoothEnabled()) {
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 5.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(id = R.drawable.bluetooth),
|
||||
contentDescription = "蓝牙",
|
||||
)
|
||||
val bluetoothEnabled by systemInfoReceiver.bluetoothEnabled.collectAsState()
|
||||
if (bluetoothEnabled) {
|
||||
TopBarIcon(R.drawable.bluetooth, "蓝牙")
|
||||
}
|
||||
|
||||
val printer1 by PrinterBT.state.collectAsState()
|
||||
val printer2 by JTPrinterUSB.state.collectAsState()
|
||||
val printerState = if (printer1 == 1 || printer2 == 1) 1 else 0
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 5.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(id = if (printerState == 1) R.drawable.print_on else R.drawable.print_off),
|
||||
contentDescription = "打印机",
|
||||
TopBarIcon(
|
||||
icon = if (printerState == 1) R.drawable.print_on else R.drawable.print_off,
|
||||
contentDescription = "打印机"
|
||||
)
|
||||
|
||||
val water by WaterCutMeterBT.state.collectAsState()
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 5.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(id = if (water == 1) R.drawable.water_on else R.drawable.water_off),
|
||||
contentDescription = "含水仪",
|
||||
TopBarIcon(
|
||||
icon = if (water == 1) R.drawable.water_on else R.drawable.water_off,
|
||||
contentDescription = "含水仪"
|
||||
)
|
||||
|
||||
val scale1 by ScaleBT.state.collectAsState()
|
||||
val scale2 by ScaleSerial.state.collectAsState()
|
||||
val scaleState = if (scale1 == 1 || scale2 == 1) 1 else 0
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 5.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(id = if (scaleState == 1) R.drawable.scale_on else R.drawable.scale_off),
|
||||
contentDescription = "电子秤",
|
||||
TopBarIcon(
|
||||
icon = if (scaleState == 1) R.drawable.scale_on else R.drawable.scale_off,
|
||||
contentDescription = "电子秤"
|
||||
)
|
||||
//分隔符
|
||||
|
||||
VerticalDivider(
|
||||
modifier = padding
|
||||
modifier = M
|
||||
.padding(horizontal = 5.dp)
|
||||
.width(1.dp),
|
||||
color = MyColors.White
|
||||
)
|
||||
// 电量显示
|
||||
|
||||
val batteryVisible by topInfoViewModel.batteryVisible.collectAsState()
|
||||
if (batteryVisible) {
|
||||
val batteryLevel by systemInfoReceiver.batteryLevel.collectAsState()
|
||||
BatteryLevelBoxWithImage(batteryLevel)
|
||||
}
|
||||
|
||||
val signalStrength by systemInfoReceiver.signalStrength.collectAsState()
|
||||
val networkType by systemInfoReceiver.networkType.collectAsState()
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = 10.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(
|
||||
id =
|
||||
if (networkType == "WIFI") {
|
||||
when (signalStrength) {
|
||||
0 -> R.drawable.server_0
|
||||
1 -> R.drawable.wifi_2
|
||||
2 -> R.drawable.wifi_2
|
||||
3 -> R.drawable.wifi_3
|
||||
4 -> R.drawable.wifi_4
|
||||
else -> R.drawable.server_0
|
||||
}
|
||||
} else if (networkType == "Cellular") {
|
||||
when (signalStrength) {
|
||||
0 -> R.drawable.server_0
|
||||
1 -> R.drawable._4g_1
|
||||
2 -> R.drawable._4g_2
|
||||
3 -> R.drawable._4g_3
|
||||
4 -> R.drawable._4g_4
|
||||
else -> R.drawable._4g_0
|
||||
}
|
||||
} else if (networkType == "Ethernet") {
|
||||
R.drawable.rj45
|
||||
} else {
|
||||
R.drawable.server_0
|
||||
}
|
||||
),
|
||||
TopBarIcon(
|
||||
icon = networkIconResource(networkType, signalStrength),
|
||||
contentDescription = "信号",
|
||||
endPadding = 10
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopBarClock(topInfoViewModel: TopInfoViewModel) {
|
||||
val date by topInfoViewModel.date.collectAsState()
|
||||
val time by topInfoViewModel.time.collectAsState()
|
||||
|
||||
WhiteText(
|
||||
text = date,
|
||||
fontSize = 15.sp,
|
||||
@@ -272,7 +272,44 @@ fun MyTopBar(
|
||||
fontSize = 30.sp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopBarIcon(
|
||||
icon: Int,
|
||||
contentDescription: String,
|
||||
endPadding: Int = 5
|
||||
) {
|
||||
Image(
|
||||
modifier = M
|
||||
.padding(end = endPadding.dp)
|
||||
.size(25.dp),
|
||||
painter = painterResource(id = icon),
|
||||
contentDescription = contentDescription,
|
||||
)
|
||||
}
|
||||
|
||||
private fun networkIconResource(networkType: String, signalStrength: Int): Int {
|
||||
return when (networkType) {
|
||||
"WIFI" -> when (signalStrength) {
|
||||
0 -> R.drawable.server_0
|
||||
1 -> R.drawable.wifi_2
|
||||
2 -> R.drawable.wifi_2
|
||||
3 -> R.drawable.wifi_3
|
||||
4 -> R.drawable.wifi_4
|
||||
else -> R.drawable.server_0
|
||||
}
|
||||
|
||||
"Cellular" -> when (signalStrength) {
|
||||
0 -> R.drawable.server_0
|
||||
1 -> R.drawable._4g_1
|
||||
2 -> R.drawable._4g_2
|
||||
3 -> R.drawable._4g_3
|
||||
4 -> R.drawable._4g_4
|
||||
else -> R.drawable._4g_0
|
||||
}
|
||||
|
||||
"Ethernet" -> R.drawable.rj45
|
||||
else -> R.drawable.server_0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +337,7 @@ fun BatteryLevelBoxWithImage(batteryLevel: Int) {
|
||||
) {
|
||||
val fillWidth = size.width * batteryLevel / 100
|
||||
drawRect(
|
||||
color = if (batteryLevel > 0.2f) MyColors.Green else MyColors.Red, // 低电量红色
|
||||
color = if (batteryLevel > 20) MyColors.Green else MyColors.Red, // 低电量红色
|
||||
topLeft = Offset(0f, 0f), // 从左上角开始填充
|
||||
size = Size(fillWidth, size.height) // 宽度根据电量动态变化
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -203,14 +203,17 @@ fun Messages(
|
||||
modifier = M
|
||||
.fillMaxSize()
|
||||
) {
|
||||
items(chatRecords) {
|
||||
itemsIndexed(
|
||||
items = chatRecords,
|
||||
key = { index, message -> "${message.timestamp}-${message.isFromUser}-$index" }
|
||||
) { index, it ->
|
||||
Message(
|
||||
modifier = M,
|
||||
msg = it,
|
||||
isEndMessageByAuthor = true,
|
||||
isNewMessageByAuthor = true
|
||||
)
|
||||
if (chatRecords.indexOf(it) == chatRecords.size - 1) {
|
||||
if (index == chatRecords.lastIndex) {
|
||||
DateHeader(System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -137,7 +138,7 @@ fun HomeScreenInLandscape(
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
ShortCut(homeViewModel)
|
||||
ShortCut(navController, homeViewModel)
|
||||
}
|
||||
}
|
||||
Column(
|
||||
@@ -227,7 +228,7 @@ fun HomeScreenInPortrait(
|
||||
.weight(0.5f)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
ShortCut(homeViewModel)
|
||||
ShortCut(navController, homeViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,8 +359,10 @@ fun WeatherInfo(homeViewModel: HomeViewModel) {
|
||||
})
|
||||
}
|
||||
LazyRow {
|
||||
items(weatherInfo.casts) {
|
||||
val index = weatherInfo.casts.indexOf(it)
|
||||
itemsIndexed(
|
||||
items = weatherInfo.casts,
|
||||
key = { index, item -> item.date.ifEmpty { "weather-$index" } }
|
||||
) { index, it ->
|
||||
WeatherItem(
|
||||
it.weekstr,
|
||||
it.date,
|
||||
@@ -430,8 +433,10 @@ fun MessageInfo(homeViewModel: HomeViewModel) {
|
||||
})
|
||||
}
|
||||
LazyColumn {
|
||||
items(count = notices.size) { index ->
|
||||
val notice = notices[index]
|
||||
items(
|
||||
items = notices,
|
||||
key = { it.id }
|
||||
) { notice ->
|
||||
MessageItem(
|
||||
homeViewModel,
|
||||
true,
|
||||
@@ -503,7 +508,7 @@ fun MessageItem(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShortCut(homeViewModel: HomeViewModel) {
|
||||
fun ShortCut(navController: NavController, homeViewModel: HomeViewModel) {
|
||||
Row(modifier = M.fillMaxHeight(), verticalAlignment = Alignment.CenterVertically) {
|
||||
Box(
|
||||
modifier = M
|
||||
@@ -527,12 +532,10 @@ fun ShortCut(homeViewModel: HomeViewModel) {
|
||||
)
|
||||
}
|
||||
LazyRow(verticalAlignment = Alignment.CenterVertically) {
|
||||
item {
|
||||
// ShowCutItem(R.drawable.user_add, "新增用户", onClick = {})
|
||||
// ShowCutItem(R.drawable.user_query, "用户查询", onClick = {})
|
||||
// ShowCutItem(R.drawable.silk_add, "新增收茧", onClick = {})
|
||||
// ShowCutItem(R.drawable.silk_trans, "茧转移", onClick = {})
|
||||
// ShowCutItem(R.drawable.device_link, "设备连接", onClick = {})
|
||||
item(key = "addUser") {
|
||||
ShowCutItem(R.drawable.user_add, "新增农户") {
|
||||
navController.navigate("addUser")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@@ -111,8 +111,10 @@ fun SettingWeather(
|
||||
InputFrame("本周天气预报") {
|
||||
Column {
|
||||
LazyRow {
|
||||
items(weatherInfo.casts) {
|
||||
val index = weatherInfo.casts.indexOf(it)
|
||||
itemsIndexed(
|
||||
items = weatherInfo.casts,
|
||||
key = { index, item -> item.date.ifEmpty { "weather-$index" } }
|
||||
) { index, it ->
|
||||
WeatherItem(
|
||||
it.weekstr, it.date, it.dayweatherpic,
|
||||
it.nighttemp + "~" + it.daytemp + "℃", index
|
||||
|
||||
@@ -1,53 +1,49 @@
|
||||
package com.bbitcn.f8.pad.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Purple80,
|
||||
secondary = PurpleGrey80,
|
||||
tertiary = Pink80
|
||||
primary = MyColors.BlueGreen,
|
||||
onPrimary = MyColors.White,
|
||||
primaryContainer = MyColors.LightBlueGreen,
|
||||
secondary = MyColors.Green,
|
||||
tertiary = MyColors.Orange,
|
||||
background = MyColors.Black,
|
||||
surface = Color(0xFF202625),
|
||||
onBackground = MyColors.White,
|
||||
onSurface = MyColors.White,
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color(0xFFFFFBFE),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
*/
|
||||
primary = MyColors.BlueGreen,
|
||||
onPrimary = MyColors.White,
|
||||
primaryContainer = MyColors.LightBlueGreen,
|
||||
secondary = MyColors.Green,
|
||||
tertiary = MyColors.Orange,
|
||||
background = Color(0xFFF7FAFA),
|
||||
surface = MyColors.White,
|
||||
surfaceVariant = MyColors.LightBlue,
|
||||
onBackground = MyColors.Black,
|
||||
onSurface = MyColors.Black,
|
||||
outline = MyColors.Disabled,
|
||||
)
|
||||
|
||||
@Composable
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun AppTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
// Dynamic color is available on Android 12+
|
||||
dynamicColor: Boolean = true,
|
||||
dynamicColor: Boolean = false,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
val context = LocalContext.current
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
val colorScheme = if (darkTheme) {
|
||||
DarkColorScheme
|
||||
} else {
|
||||
LightColorScheme
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Reference in New Issue
Block a user