今天事情比較忙一點,簡單做一下昨天的單日行事曆的UI優化,明天再來處理代辦事項的功能
程式碼如下
package com.example.a2024ironman
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.api.services.calendar.model.Event
import java.text.SimpleDateFormat
import java.util.Locale
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import java.util.Calendar
import java.util.Date
@Composable
fun DayCalendar(selectedDate: String, events: List<Event>, onBack: () -> Unit) {
// 分割日期,並設定預設值以避免錯誤
val dateParts = selectedDate.split(" ")
val month = if (dateParts.size > 0) dateParts[0] else "N/A"
val day = if (dateParts.size > 1) dateParts[1] else "N/A"
val year = if (dateParts.size > 2) dateParts[2] else "N/A"
val formattedDate = "$month/$day"+"日"
// 取得星期幾
val dayOfWeek = try {
val simpleDateFormat = SimpleDateFormat("MMMM dd yyyy", Locale.getDefault())
val parsedDate = simpleDateFormat.parse(selectedDate)
val calendar = Calendar.getInstance()
calendar.time = parsedDate ?: Date()
when (calendar.get(Calendar.DAY_OF_WEEK)) {
Calendar.SUNDAY -> "日"
Calendar.MONDAY -> "一"
Calendar.TUESDAY -> "二"
Calendar.WEDNESDAY -> "三"
Calendar.THURSDAY -> "四"
Calendar.FRIDAY -> "五"
Calendar.SATURDAY -> "六"
else -> "N/A"
}
} catch (e: Exception) {
"N/A"
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(0.dp)
.background(MaterialTheme.colorScheme.background) // 使用主題背景顏色
) {
Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
// 顯示年份區塊
Box(
modifier = Modifier
.fillMaxWidth()
.weight(0.2f)
.padding(bottom = 0.dp)
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Text(
text = year, // 顯示年份
style = MaterialTheme.typography.headlineMedium.copy(color = MaterialTheme.colorScheme.onSurface),
fontSize = 20.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
// 顯示日期和星期區塊
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 0.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
// 顯示月份和日期
Box(
modifier = Modifier
.weight(0.75f)
.padding(end = 0.dp)
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Text(
text = formattedDate, // 正確的日期格式
style = MaterialTheme.typography.headlineMedium.copy(color = MaterialTheme.colorScheme.onSurface),
fontSize = 50.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
// 顯示星期幾
Box(
modifier = Modifier
.weight(0.25f)
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Text(
text = dayOfWeek, // 顯示星期幾
style = MaterialTheme.typography.headlineMedium.copy(color = MaterialTheme.colorScheme.onSurface),
fontSize = 50.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}
// 代辦事項區塊
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(top = 8.dp)
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.TopStart
) {
Column(modifier = Modifier.padding(8.dp)) {
Text(
text = "行程",
style = MaterialTheme.typography.headlineSmall.copy(color = MaterialTheme.colorScheme.onSurface),
modifier = Modifier.padding(bottom = 8.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
if (events.isEmpty()) {
Text(
text = "當天沒有行程",
style = MaterialTheme.typography.bodyLarge.copy(color = MaterialTheme.colorScheme.onSurface),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
} else {
events.forEach { event ->
Text(
text = "• ${event.summary}",
style = MaterialTheme.typography.bodyLarge.copy(color = MaterialTheme.colorScheme.onSurface),
modifier = Modifier.padding(bottom = 4.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}
}
}
}
// 右下角的返回符號
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.BottomStart
) {
IconButton(
onClick = onBack,
modifier = Modifier
.padding(0.dp)
.size(48.dp) // 設定圖示按鈕大小
) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "返回月行事曆",
tint = MaterialTheme.colorScheme.onPrimary // 設定圖示顏色
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun PreviewDayCalendar() {
// 建立模擬的事件列表
val mockEvents = listOf(
Event().apply { summary = "早上會議" },
Event().apply { summary = "午餐約會" },
Event().apply { summary = "下午專案討論" }
)
// 呼叫 DayCalendar 函式並提供模擬資料
DayCalendar(
selectedDate = "2024/09/28",
events = mockEvents,
onBack = {} // 預覽時不需要實際實作返回功能
)
}
上面的程式碼呈現的效果如下!
這邊使用到了前面提過的Modifier
裡的weight
修飾符來調整每個Box
所占用的空間比例,其用法如下
今天請了人來家裡修網路,下午又有事要忙,只能先寫這一點內容,明天我們再來完成代辦事項的建構,我研究一下能否連結到tasks裡,今天的內容就到這邊結束,我們明天再見。