For starters, Compose definitely needs to make something to get familiar with, so here’s a simple calendar I’ve created for you.

First, I recommend a website, STRINGS Ist, which is a collection of libraries designed to complement Jetpack Compose with features that developers usually need but are not yet available. . Google. Making. IO/accompanist…

Concerto pager implementation (” com. Google. Accompanist: accompanist – pager: 0.21.3 – beta “)

Then there’s a library that helps you create and manage viewModels in Compose

Implementation (‘ androidx. Lifecycle: lifecycle – viewmodel – compose: 2.4.0 ‘)

First of all, calendars have years, months and days, but this one I made doesn’t have a year, so you can add your own.

Create a function where day is the day, selectDay determines if it was clicked on, throws a lambda, handles the click event, and the day passed in by the lambda is used to specify the day. @Composable fun Day(day: Int, selectDay: Int, dayClick: (Int) -> Unit) { Text(text = day.toString(), textAlign = TextAlign.Center, color = if (day == selectDay) Color.Red else Color.White, Clickable = modifier. Clickable {dayClick(day)})} mysqli = modifier. Clickable {dayClick(day)})} mysqli = modifier. Just copy what's inside and change it. enum class MonthEnum { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;  companion object { private val enums = values() fun of(month: Int): MonthEnum { if (month < 1 || month > 12) { throw RuntimeException("Invalid value for MonthOfYear: $month") } return enums[month - 1] } } fun maxLength(): Int { return when (this) { FEBRUARY -> 29 APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30 else -> 31 } } fun minLength(): Int { return when (this) { FEBRUARY -> 28 APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30 else -> 31 } } fun length(leapYear: Boolean): Int { return when (this) { FEBRUARY -> if (leapYear) 29 else 28 APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30 else -> 31}}} /** *@param selectDay dynamic update *@param dayClick highlight *LazyVerticalGrid is used to write a list of grids, Fixed(6) returns the number of days per row *month.length(true), True represents a leap year * / @ OptIn (ExperimentalFoundationApi: : class) @ Composable fun Month (the Month: MonthEnum selectDay: Int, dayClick: (Int) -> Unit ) { Column( modifier = Modifier .fillMaxHeight() .padding(top = 60.dp) ) { Text( text = month.name, modifier = Modifier // .background(Color.Red) .fillMaxWidth(), color = Color.White, textAlign = TextAlign.Center ) Log.i(TAG, "Month: ${month.name} ") LazyVerticalGrid(cells = GridCells.Fixed(6)) { items(month.length(true)) { index -> Day(day = index + 1, selectDay, dayClick)}}}} Next comes the outermost viewpager, Move to page needs to be done when switching @ OptIn (ExperimentalPagerApi: : class) @ Composable fun Calendar (selectDay: Int, move: (Int) -> Unit, dayClick: (Int) -> Unit) {// Reacting to page changes ¶ // The pagerState.currentPage property is updated whenever the selected page changes. // Collect snapshotFlow from snapshot stream reading currentPage { pagerState.currentPage } .collect { move(it) } } HorizontalPager( count = 12, state = pagerState, modifier = Modifier .paint( painter = painterResource( id = R.drawable.background ), contentScale = ContentScale.Crop ) .height(300.dp), verticalAlignment = Alignment.Top ) { index -> Month( month = MonthEnum.of(index + 1), selectDay = selectDay, DayClick = dayClick)}} Because the selected number may be greater than the next month of the switch, it will not be highlighted, so the first day is highlighted by default at each switch, and the outermost lambda is the click event that handles Day. setContent { WeChat_ComposeTheme { val viewModel: MainViewModel = viewModel() Calendar(selectDay = viewModel.selectDay, Move = {viewmodel.selectDay = 1}) {viewmodel.selectDay = it}}} The MutableState class is a single value holder, whose reads and writes are observed by Compose, and which updates the UI when the value changes. class MainViewModel : ViewModel() { var selectDay by mutableStateOf(1) }Copy the code