iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0

前言

今天事情比較忙一點,簡單做一下昨天的單日行事曆的UI優化,明天再來處理代辦事項的功能

單日UI優化

程式碼如下

  • kotlin
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 = {} // 預覽時不需要實際實作返回功能
    )
}


上面的程式碼呈現的效果如下!
https://ithelp.ithome.com.tw/upload/images/20240930/201626490KfJJBwAjz.jpg
這邊使用到了前面提過的Modifier裡的weight修飾符來調整每個Box所占用的空間比例,其用法如下

  • weight(0.2f): 讓年份區塊占用 20% 的高度
  • weight(0.15f): 讓日期和星期區塊占用 15% 的高度
  • weight(0.65f): 讓代辦事項區塊占用 65% 的高度
    透過調整應該可以讓Box更符合我們理想的的佈局需求。

後話

今天請了人來家裡修網路,下午又有事要忙,只能先寫這一點內容,明天我們再來完成代辦事項的建構,我研究一下能否連結到tasks裡,今天的內容就到這邊結束,我們明天再見。


上一篇
Day15:製作時鐘元件和用animateFloatAsState製作翻頁動畫
下一篇
Day17:連結GOOGLE Task到代辦事項
系列文
github裡永遠有一個還沒做的SideProject :用Kotlin來開發點沒用的酷東西30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言