年视图支持左右滑动切换年份
使用 HorizontalPager 包裹年视图,支持手势滑动切年。 ‹ › 按钮改为 animateScrollToPage,与滑动行为一致。
This commit is contained in:
parent
502f1efc0a
commit
8dad07c0a0
@ -71,7 +71,7 @@ class CalendarViewModel(
|
|||||||
|
|
||||||
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
||||||
var yearViewYear by mutableStateOf(today.year)
|
var yearViewYear by mutableStateOf(today.year)
|
||||||
private set
|
internal set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选中指定日期。
|
* 选中指定日期。
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.PagerDefaults
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@ -16,6 +18,7 @@ import androidx.compose.runtime.mutableIntStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clipToBounds
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
@ -65,6 +68,32 @@ fun CalendarMonthView(
|
|||||||
|
|
||||||
val pagerState = rememberPagerState(initialPage = START_PAGE, pageCount = { Int.MAX_VALUE })
|
val pagerState = rememberPagerState(initialPage = START_PAGE, pageCount = { Int.MAX_VALUE })
|
||||||
|
|
||||||
|
// 年视图分页器
|
||||||
|
val yearPagerState = rememberPagerState(
|
||||||
|
initialPage = START_PAGE,
|
||||||
|
pageCount = { Int.MAX_VALUE }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 进入年视图时同步 yearPagerState 到当前年
|
||||||
|
LaunchedEffect(viewModel.isYearView) {
|
||||||
|
if (viewModel.isYearView) {
|
||||||
|
if (yearPagerState.currentPage != START_PAGE) {
|
||||||
|
yearPagerState.scrollToPage(START_PAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 年视图翻页时同步 yearViewYear
|
||||||
|
LaunchedEffect(yearPagerState) {
|
||||||
|
snapshotFlow { yearPagerState.settledPage }.collect { page ->
|
||||||
|
val offset = page - START_PAGE
|
||||||
|
val targetYear = viewModel.selectedDate.year + offset
|
||||||
|
if (targetYear != viewModel.yearViewYear) {
|
||||||
|
viewModel.yearViewYear = targetYear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 折叠态 WeekPager 切月时,持续同步 CalendarPager 的 pagerState
|
// 折叠态 WeekPager 切月时,持续同步 CalendarPager 的 pagerState
|
||||||
LaunchedEffect(viewModel.selectedDate) {
|
LaunchedEffect(viewModel.selectedDate) {
|
||||||
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
||||||
@ -241,28 +270,12 @@ fun CalendarMonthView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 年视图层
|
// 年视图层:HorizontalPager 支持左右滑动切年
|
||||||
if (viewModel.isYearView || yearProgress > 0.01f) {
|
if (viewModel.isYearView || yearProgress > 0.01f) {
|
||||||
YearGridView(
|
HorizontalPager(
|
||||||
year = viewModel.yearViewYear,
|
state = yearPagerState,
|
||||||
selectedMonth = if (viewModel.yearViewYear == currentYear) currentMonth else 0,
|
beyondViewportPageCount = 1,
|
||||||
today = today,
|
flingBehavior = PagerDefaults.flingBehavior(state = yearPagerState),
|
||||||
onMonthClick = { month ->
|
|
||||||
viewModel.selectMonthFromYearView(month)
|
|
||||||
// 同步 CalendarPager 到目标月份
|
|
||||||
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
|
||||||
val targetPage = yearMonthToPage(
|
|
||||||
viewModel.yearViewYear, month,
|
|
||||||
today.year, today.month.number
|
|
||||||
)
|
|
||||||
if (targetPage != pagerState.currentPage) {
|
|
||||||
coroutineScope.launch { pagerState.scrollToPage(targetPage) }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onYearChange = { newYear ->
|
|
||||||
if (newYear > viewModel.yearViewYear) viewModel.incrementYear()
|
|
||||||
else viewModel.decrementYear()
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
@ -272,7 +285,32 @@ fun CalendarMonthView(
|
|||||||
transformOrigin = TransformOrigin(anchorPivotX, anchorPivotY)
|
transformOrigin = TransformOrigin(anchorPivotX, anchorPivotY)
|
||||||
}
|
}
|
||||||
.padding(horizontal = HORIZONTAL_PADDING_DP.dp)
|
.padding(horizontal = HORIZONTAL_PADDING_DP.dp)
|
||||||
)
|
) { page ->
|
||||||
|
val pageYear = viewModel.selectedDate.year + (page - START_PAGE)
|
||||||
|
YearGridView(
|
||||||
|
year = pageYear,
|
||||||
|
selectedMonth = if (pageYear == currentYear) currentMonth else 0,
|
||||||
|
today = today,
|
||||||
|
onMonthClick = { month ->
|
||||||
|
viewModel.selectMonthFromYearView(month)
|
||||||
|
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
||||||
|
val targetPage = yearMonthToPage(
|
||||||
|
viewModel.yearViewYear, month,
|
||||||
|
today.year, today.month.number
|
||||||
|
)
|
||||||
|
if (targetPage != pagerState.currentPage) {
|
||||||
|
coroutineScope.launch { pagerState.scrollToPage(targetPage) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onYearChange = { newYear ->
|
||||||
|
val offset = newYear - pageYear
|
||||||
|
val targetPage = yearPagerState.currentPage + offset
|
||||||
|
if (targetPage != yearPagerState.currentPage) {
|
||||||
|
coroutineScope.launch { yearPagerState.animateScrollToPage(targetPage) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BottomCard:年视图时隐藏
|
// BottomCard:年视图时隐藏
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user