再次优化加载性能
This commit is contained in:
@@ -240,6 +240,7 @@ fun <T : Any> MyRefreshTableForCard(
|
|||||||
) {
|
) {
|
||||||
val state = rememberPullToRefreshState()
|
val state = rememberPullToRefreshState()
|
||||||
val pagerSate = info.loadState.append
|
val pagerSate = info.loadState.append
|
||||||
|
val refreshState = info.loadState.refresh
|
||||||
LaunchedEffect(pagerSate) {
|
LaunchedEffect(pagerSate) {
|
||||||
if (pagerSate is LoadState.NotLoading) {
|
if (pagerSate is LoadState.NotLoading) {
|
||||||
onFinishRefresh()
|
onFinishRefresh()
|
||||||
@@ -272,30 +273,37 @@ fun <T : Any> MyRefreshTableForCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
LazyVerticalGrid(
|
Box(modifier = M.fillMaxSize()) {
|
||||||
modifier = M.fillMaxSize(),
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(columns),
|
modifier = M.fillMaxSize(),
|
||||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
columns = GridCells.Fixed(columns),
|
||||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||||
) {
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
items(
|
) {
|
||||||
count = info.itemCount,
|
items(
|
||||||
key = info.itemKey { key(it) },
|
count = info.itemCount,
|
||||||
contentType = info.itemContentType { "paging-card" }
|
key = info.itemKey { key(it) },
|
||||||
) { index ->
|
contentType = info.itemContentType { "paging-card" }
|
||||||
info[index]?.let { lineItem ->
|
) { index ->
|
||||||
Box {
|
info[index]?.let { lineItem ->
|
||||||
item(lineItem, index)
|
Box {
|
||||||
|
item(lineItem, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item(contentType = "paging-footer") {
|
||||||
|
when (pagerSate) {
|
||||||
|
is LoadState.NotLoading -> if (pagerSate.endOfPaginationReached)
|
||||||
|
ListNoMore()
|
||||||
|
|
||||||
|
is LoadState.Loading -> ListLoading()
|
||||||
|
is LoadState.Error -> ListError(message = pagerSate.error.message.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item(contentType = "paging-footer") {
|
if (refreshState is LoadState.Loading && info.itemCount == 0) {
|
||||||
when (pagerSate) {
|
Box(modifier = M.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
is LoadState.NotLoading -> if (pagerSate.endOfPaginationReached)
|
ListLoading()
|
||||||
ListNoMore()
|
|
||||||
|
|
||||||
is LoadState.Loading -> ListLoading()
|
|
||||||
is LoadState.Error -> ListError(message = pagerSate.error.message.toString())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -512,6 +520,7 @@ fun <T : Any> MyRefreshTable(
|
|||||||
val listState: LazyListState = rememberLazyListState()
|
val listState: LazyListState = rememberLazyListState()
|
||||||
val state = rememberPullToRefreshState()
|
val state = rememberPullToRefreshState()
|
||||||
val pagerSate = info.loadState.append
|
val pagerSate = info.loadState.append
|
||||||
|
val refreshState = info.loadState.refresh
|
||||||
LaunchedEffect(pagerSate) {
|
LaunchedEffect(pagerSate) {
|
||||||
if (pagerSate is LoadState.NotLoading) {
|
if (pagerSate is LoadState.NotLoading) {
|
||||||
onFinishRefresh()
|
onFinishRefresh()
|
||||||
@@ -553,8 +562,9 @@ fun <T : Any> MyRefreshTable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
var selectIndex by rememberSaveable { mutableStateOf(-1) }
|
Box(modifier = M.fillMaxSize()) {
|
||||||
LazyColumn(state = listState) {
|
var selectIndex by rememberSaveable { mutableStateOf(-1) }
|
||||||
|
LazyColumn(state = listState) {
|
||||||
items(
|
items(
|
||||||
count = info.itemCount,
|
count = info.itemCount,
|
||||||
key = info.itemKey { key(it) },
|
key = info.itemKey { key(it) },
|
||||||
@@ -647,6 +657,12 @@ fun <T : Any> MyRefreshTable(
|
|||||||
is LoadState.Error -> ListError(message = pagerSate.error.message.toString())
|
is LoadState.Error -> ListError(message = pagerSate.error.message.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (refreshState is LoadState.Loading && info.itemCount == 0) {
|
||||||
|
Box(modifier = M.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
ListLoading()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,11 +54,12 @@ open class BaseViewModel : ViewModel() {
|
|||||||
onUI: (T) -> Unit,
|
onUI: (T) -> Unit,
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
if (showDialog) {
|
||||||
|
Toasty.showLoadingDialog(loadingTips)
|
||||||
|
}
|
||||||
|
|
||||||
val result = kotlin.runCatching {
|
val result = kotlin.runCatching {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
if (showDialog) {
|
|
||||||
Toasty.showLoadingDialog(loadingTips)
|
|
||||||
}
|
|
||||||
onIO()
|
onIO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,33 +68,31 @@ open class BaseViewModel : ViewModel() {
|
|||||||
hideLoadingDialog()
|
hideLoadingDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
result.onSuccess { data ->
|
||||||
result.onSuccess { data ->
|
onUI(data)
|
||||||
onUI(data)
|
}.onFailure { exception ->
|
||||||
}.onFailure { exception ->
|
// ✅ 如果是协程取消,不处理,只记录日志
|
||||||
// ✅ 如果是协程取消,不处理,只记录日志
|
if (exception is CancellationException || exception.cause is SocketException && exception.cause?.message?.contains(
|
||||||
if (exception is CancellationException || exception.cause is SocketException && exception.cause?.message?.contains(
|
"Socket closed"
|
||||||
"Socket closed"
|
) == true
|
||||||
) == true
|
) {
|
||||||
) {
|
MyLog.test("协程被取消:${exception.javaClass.simpleName},message=${exception.message}")
|
||||||
MyLog.test("协程被取消:${exception.javaClass.simpleName},message=${exception.message}")
|
return@onFailure
|
||||||
return@onFailure
|
|
||||||
}
|
|
||||||
if (exception is HttpException && exception.code() == 401) {
|
|
||||||
Toasty.loginExpired()
|
|
||||||
Toasty.error("登录已过期")
|
|
||||||
return@onFailure
|
|
||||||
}
|
|
||||||
// 其他异常继续处理
|
|
||||||
exception.printStackTrace()
|
|
||||||
onError(exception)
|
|
||||||
exception.message?.let {
|
|
||||||
Toasty.error(it)
|
|
||||||
}
|
|
||||||
}.also {
|
|
||||||
// ✅ 最终执行的操作
|
|
||||||
onFinish()
|
|
||||||
}
|
}
|
||||||
|
if (exception is HttpException && exception.code() == 401) {
|
||||||
|
Toasty.loginExpired()
|
||||||
|
Toasty.error("登录已过期")
|
||||||
|
return@onFailure
|
||||||
|
}
|
||||||
|
// 其他异常继续处理
|
||||||
|
exception.printStackTrace()
|
||||||
|
onError(exception)
|
||||||
|
exception.message?.let {
|
||||||
|
Toasty.error(it)
|
||||||
|
}
|
||||||
|
}.also {
|
||||||
|
// ✅ 最终执行的操作
|
||||||
|
onFinish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ import androidx.navigation.compose.rememberNavController
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.zIndex
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.bbitcn.f8.pad.M
|
import com.bbitcn.f8.pad.M
|
||||||
@@ -47,8 +48,8 @@ import com.bbitcn.f8.pad.ui.screen.mainFunc.UserScreen
|
|||||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||||
import com.bbitcn.f8.pad.ui.viewmodel.UpdateViewModel
|
import com.bbitcn.f8.pad.ui.viewmodel.UpdateViewModel
|
||||||
import com.cyberecho.ui.screen.ChatDialog
|
import com.cyberecho.ui.screen.ChatDialog
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.xutils.db.annotation.Column
|
|
||||||
|
|
||||||
@Preview(showBackground = true, widthDp = 1280)
|
@Preview(showBackground = true, widthDp = 1280)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -74,9 +75,43 @@ fun MainScreen(
|
|||||||
}
|
}
|
||||||
Box(modifier = M.fillMaxWidth(), contentAlignment = Alignment.BottomStart) {
|
Box(modifier = M.fillMaxWidth(), contentAlignment = Alignment.BottomStart) {
|
||||||
var selectedPage by rememberSaveable { mutableStateOf(0) }
|
var selectedPage by rememberSaveable { mutableStateOf(0) }
|
||||||
|
var contentPage by rememberSaveable { mutableStateOf(0) }
|
||||||
|
var isSwitchingPage by remember { mutableStateOf(false) }
|
||||||
|
val cachedPages = remember { mutableStateListOf<Int>() }
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
val menu by mainViewModel.menu.collectAsState()
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
Row(modifier = M.fillMaxWidth()) {
|
Row(modifier = M.fillMaxWidth()) {
|
||||||
NavigationRail(
|
NavigationRail(
|
||||||
containerColor = MyColors.Black,
|
containerColor = MyColors.Black,
|
||||||
@@ -99,35 +134,37 @@ fun MainScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
selected = selectedPage == index,
|
selected = selectedPage == index,
|
||||||
onClick = { selectedPage = index }
|
onClick = {
|
||||||
)
|
if (selectedPage != index) {
|
||||||
}
|
selectedPage = index
|
||||||
}
|
isSwitchingPage = index !in cachedPages
|
||||||
Box {
|
if (index in cachedPages) {
|
||||||
var index = -1
|
contentPage = index
|
||||||
if (menu.isNotEmpty()) {
|
|
||||||
index = menu[selectedPage].index
|
|
||||||
}
|
|
||||||
when (index) {
|
|
||||||
-1 -> {
|
|
||||||
Box(modifier = M.fillMaxSize(), contentAlignment = Alignment.Center) {
|
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
|
||||||
Text("正在加载菜单,如长时间未响应请点击重新加载")
|
|
||||||
MyButton(text = "刷新菜单") {
|
|
||||||
mainViewModel.refreshMenuPermission()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
}
|
||||||
0 -> HomeScreen(navController)
|
}
|
||||||
1 -> UserScreen(navController)
|
Box(modifier = M.weight(1f).fillMaxSize()) {
|
||||||
2 -> PurchaseScreen(navController, drawerViewModel = drawerViewModel)
|
val selectedMenu = menu.getOrNull(selectedPage)
|
||||||
3 -> FundsScreen(navController, drawerViewModel = drawerViewModel)
|
if (isSwitchingPage && selectedMenu != null && selectedPage !in cachedPages) {
|
||||||
4 -> StatisticsScreen(drawerViewModel = drawerViewModel)
|
MainPageLoading(selectedMenu.title)
|
||||||
5 -> DryCoonScreen(navController, drawerViewModel)
|
} else {
|
||||||
6 -> SettingScreen(navController, updateViewModel = updateViewModel, topInfoViewmodel = topInfoViewmodel){
|
cachedPages.forEach { page ->
|
||||||
mainViewModel.refreshMenuPermission()
|
key(page) {
|
||||||
|
val pageIndex = menu.getOrNull(page)?.index ?: -1
|
||||||
|
MainPageHost(visible = page == contentPage) {
|
||||||
|
MainPageContent(
|
||||||
|
index = pageIndex,
|
||||||
|
navController = navController,
|
||||||
|
drawerViewModel = drawerViewModel,
|
||||||
|
updateViewModel = updateViewModel,
|
||||||
|
topInfoViewmodel = topInfoViewmodel,
|
||||||
|
mainViewModel = mainViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,3 +245,69 @@ fun MainScreen(
|
|||||||
val chatDialogData by mainViewModel.chatDialogData.collectAsState()
|
val chatDialogData by mainViewModel.chatDialogData.collectAsState()
|
||||||
ChatDialog(chatDialogData)
|
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,
|
||||||
|
navController: NavHostController,
|
||||||
|
drawerViewModel: DrawerViewModel,
|
||||||
|
updateViewModel: UpdateViewModel,
|
||||||
|
topInfoViewmodel: TopInfoViewModel,
|
||||||
|
mainViewModel: MainViewModel
|
||||||
|
) {
|
||||||
|
when (index) {
|
||||||
|
-1 -> {
|
||||||
|
Box(modifier = M.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("正在加载菜单,如长时间未响应请点击重新加载")
|
||||||
|
MyButton(text = "刷新菜单") {
|
||||||
|
mainViewModel.refreshMenuPermission()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0 -> HomeScreen(navController)
|
||||||
|
1 -> UserScreen(navController)
|
||||||
|
2 -> PurchaseScreen(navController, drawerViewModel = drawerViewModel)
|
||||||
|
3 -> FundsScreen(navController, drawerViewModel = drawerViewModel)
|
||||||
|
4 -> StatisticsScreen(drawerViewModel = drawerViewModel)
|
||||||
|
5 -> DryCoonScreen(navController, drawerViewModel)
|
||||||
|
6 -> SettingScreen(navController, updateViewModel = updateViewModel, topInfoViewmodel = topInfoViewmodel) {
|
||||||
|
mainViewModel.refreshMenuPermission()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -45,6 +46,7 @@ import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
|||||||
import com.bbitcn.f8.pad.ui.screen.view.common.DatePickerRange
|
import com.bbitcn.f8.pad.ui.screen.view.common.DatePickerRange
|
||||||
import com.bbitcn.f8.pad.ui.screen.view.drawer.DrawerViewModel
|
import com.bbitcn.f8.pad.ui.screen.view.drawer.DrawerViewModel
|
||||||
import com.bbitcn.f8.pad.ui.theme.MyColors
|
import com.bbitcn.f8.pad.ui.theme.MyColors
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -69,8 +71,18 @@ fun StatisticsScreen(
|
|||||||
val ticketMoreDialogData by remember { mutableStateOf(TicketMoreDialogData()) }
|
val ticketMoreDialogData by remember { mutableStateOf(TicketMoreDialogData()) }
|
||||||
var curType by remember { mutableStateOf(StatisticsResponse.Data()) }
|
var curType by remember { mutableStateOf(StatisticsResponse.Data()) }
|
||||||
var queryInput by rememberSaveable { mutableStateOf("") }
|
var queryInput by rememberSaveable { mutableStateOf("") }
|
||||||
|
var queryInputInitialized by rememberSaveable { mutableStateOf(false) }
|
||||||
val pager = statisticsViewModel.statisticsPager.collectAsLazyPagingItems()
|
val pager = statisticsViewModel.statisticsPager.collectAsLazyPagingItems()
|
||||||
val dateRangeSelectDialogData by statisticsViewModel.dateRangeSelectDialogData.collectAsState()
|
val dateRangeSelectDialogData by statisticsViewModel.dateRangeSelectDialogData.collectAsState()
|
||||||
|
LaunchedEffect(queryInput) {
|
||||||
|
if (!queryInputInitialized) {
|
||||||
|
queryInputInitialized = true
|
||||||
|
return@LaunchedEffect
|
||||||
|
}
|
||||||
|
delay(350)
|
||||||
|
statisticsViewModel.updateParamsLike(queryInput)
|
||||||
|
pager.refresh()
|
||||||
|
}
|
||||||
MainFuncFrame {
|
MainFuncFrame {
|
||||||
MyCard(colors = MyColors.LightLightBlueGreen) {
|
MyCard(colors = MyColors.LightLightBlueGreen) {
|
||||||
Row(
|
Row(
|
||||||
@@ -79,9 +91,11 @@ fun StatisticsScreen(
|
|||||||
.padding(10.dp)
|
.padding(10.dp)
|
||||||
) {
|
) {
|
||||||
StatisticsLeft(modifier = M.weight(2f), statisticsViewModel, curType, pager) {
|
StatisticsLeft(modifier = M.weight(2f), statisticsViewModel, curType, pager) {
|
||||||
curType = it
|
if (curType.sgtypesysid != it.sgtypesysid) {
|
||||||
statisticsViewModel.updateParamsCocoonType(it.sgtypesysid)
|
curType = it
|
||||||
pager.refresh()
|
statisticsViewModel.updateParamsCocoonType(it.sgtypesysid)
|
||||||
|
pager.refresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StatisticsMain(
|
StatisticsMain(
|
||||||
modifier = M.weight(8f),
|
modifier = M.weight(8f),
|
||||||
@@ -90,8 +104,6 @@ fun StatisticsScreen(
|
|||||||
queryInput,
|
queryInput,
|
||||||
{
|
{
|
||||||
queryInput = it
|
queryInput = it
|
||||||
statisticsViewModel.updateParamsLike(queryInput)
|
|
||||||
pager.refresh()
|
|
||||||
},
|
},
|
||||||
curType.name,
|
curType.name,
|
||||||
{
|
{
|
||||||
@@ -119,6 +131,7 @@ fun StatisticsLeft(
|
|||||||
) {
|
) {
|
||||||
val daysInfo by statisticsViewModel.daysInfo.collectAsState()
|
val daysInfo by statisticsViewModel.daysInfo.collectAsState()
|
||||||
val statistics by statisticsViewModel.statistics.collectAsState()
|
val statistics by statisticsViewModel.statistics.collectAsState()
|
||||||
|
val dayFormat = remember { SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
@@ -131,10 +144,12 @@ fun StatisticsLeft(
|
|||||||
statisticsViewModel.calDate = it
|
statisticsViewModel.calDate = it
|
||||||
statisticsViewModel.getDaysInfo(it.year.toString(), it.monthValue.toString())
|
statisticsViewModel.getDaysInfo(it.year.toString(), it.monthValue.toString())
|
||||||
}) { start, end ->
|
}) { start, end ->
|
||||||
val dateStart = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(start)
|
val dateStart = dayFormat.parse(start)
|
||||||
val dateEnd = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(end)
|
val dateEnd = dayFormat.parse(end)
|
||||||
statisticsViewModel.refreshDateRange(dateStart to dateEnd)
|
if (dateStart != null && dateEnd != null) {
|
||||||
pager.refresh()
|
statisticsViewModel.refreshDateRange(dateStart to dateEnd)
|
||||||
|
pager.refresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val dateRange by statisticsViewModel.dateRange.collectAsState()
|
val dateRange by statisticsViewModel.dateRange.collectAsState()
|
||||||
DateRangePickTextFiled(M.fillMaxWidth(), dateRange = dateRange) {
|
DateRangePickTextFiled(M.fillMaxWidth(), dateRange = dateRange) {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ fun DatePickerRange(
|
|||||||
// 处理拖动选择日期范围
|
// 处理拖动选择日期范围
|
||||||
var selectedStartDay by remember { mutableStateOf(-1) }
|
var selectedStartDay by remember { mutableStateOf(-1) }
|
||||||
var selectedEndDay by remember { mutableStateOf(-1) }
|
var selectedEndDay by remember { mutableStateOf(-1) }
|
||||||
|
val importantDaySet = remember(importantDateInfoList) { importantDateInfoList.toSet() }
|
||||||
|
|
||||||
val onClickChangeDate: (date: LocalDate) -> Unit = { date ->
|
val onClickChangeDate: (date: LocalDate) -> Unit = { date ->
|
||||||
currentDate = date
|
currentDate = date
|
||||||
@@ -158,7 +159,7 @@ fun DatePickerRange(
|
|||||||
items(currentDate.lengthOfMonth() + 1) { day ->
|
items(currentDate.lengthOfMonth() + 1) { day ->
|
||||||
CalendarDay(
|
CalendarDay(
|
||||||
day,
|
day,
|
||||||
importantDateInfoList.contains(day),
|
importantDaySet.contains(day),
|
||||||
rangeType = if (day == selectedStartDay)
|
rangeType = if (day == selectedStartDay)
|
||||||
if (selectedEndDay == -1
|
if (selectedEndDay == -1
|
||||||
|| selectedEndDay == selectedStartDay
|
|| selectedEndDay == selectedStartDay
|
||||||
|
|||||||
Reference in New Issue
Block a user