iT邦幫忙

2026 iThome 鐵人賽

DAY 5
2

配合分支:day05/start,Repo: 按我

昨天飆出來的程式,好像怪怪的仔細看會發現新增的日記:標題和內容反了
問題出在哪?繼續昨天的流程,來梳理新增照片的過程發生了什麼事情。

https://ithelp.ithome.com.tw/upload/images/20260824/20141615p12RRhBL3V.png

資料流 (Data Flow)

在程式跑的時候,最重要的東西,就是資料會怎麼流動。包含:

  1. 某個按鈕按下去後,過程發生了什麼?
  2. 這個 Function 回傳了什麼?誰又去呼叫他?
  3. 這個變數,有誰使用?

昨天做的「查證」,就是在梳理資料流。

假設

通常一個功能壞掉的時候,工程師都會假設哪邊出了問題,久而久之越來越厲害就會變成通靈,非常的玄妙。
先確立幾個假設,過程之中再一齊來進行查證作業:

DiaryEntry 或卡片 UI 有壞掉?

簡單粗暴的推測,立刻來看 DiaryEntry 相關的程式碼。從昨天知道的資料流來推測:

https://ithelp.ithome.com.tw/upload/images/20260824/20141615bQ7qOjIHiN.png

進入點 MainActivity 建立時呼叫 onCreate(),並且把 PhotoDiaryApp()叫起來(如果不太熟悉,請複習 Day04 的內容)。昨天知道 PhotoDiaryApp()if/else 來控制 UI 的長相。

這次的目標是看「卡片列表」,也就是 isAddingDiary 非新增日記 狀態,往下找就可以看到 DiaryList()

DiaryList 可以傳入一個 DiaryEntry 的列表(List),看起來日記的 基本資訊 都寫在裡頭。先來看看 DiaryList

https://ithelp.ithome.com.tw/upload/images/20260824/20141615kxXVp7v0vk.png

發現 LazyColumn 裡頭包著 DiaryCard 這應該就是這次要找的。

補充

https://ithelp.ithome.com.tw/upload/images/20260824/20141615FANIQAU5Mf.png

LazyColumn 元件可以重複印出,看看裡頭有一個 items() 代表 每一個物件都會執行後面的 code 區塊 也就是印出 DiaryCard()
每一個 entry 會從 entries 之中拿出來。透過 Android Studio 來看,entry 是一個 DiaryEntry

查證

https://ithelp.ithome.com.tw/upload/images/20260824/20141615n9jTWHjghn.png

DiaryCard 拿出 entry.title 以及 entry.note 的地方,看不出有放錯 🤔 ,的確是 title 放上面,note 放下面。噢對了,entry.title 可以從 entry 的 title 取值。

這個假設「不成立」

標題的 TextField (文字區塊) 有錯?

不然就是打字的時候,存標題和內文的「變數」存錯了?(同樣,變數在 Day04 有做介紹)

PhotoDiaryApp()if/else 來控制 UI 的長相。 這次的目標是看「新增照片」的表格 UI,也就是 isAddingDiary 新增日記 狀態,往下找看到 DiaryForm()

https://ithelp.ithome.com.tw/upload/images/20260824/20141615QBdNfnqteW.png

DiaryForm() 接受兩個 callback function,一個是「按下儲存」的時候,會將兩個 String 帶回來。

String

文字的型別(Type),通常在 Android/Kotlin 的世界裡,String 用來存「文字」。順帶一提,如果存一個「字元」例如:abc 是文字,a 是一個字元。
存字元可以用 Char。(雖然實務上絕大部分的情況都能用 String 打天下)

https://ithelp.ithome.com.tw/upload/images/20260824/20141615DeYe36LNdA.png

接著來看變數的部分,看到標題和內容,onValueChange 也就是輸入框值改變的時候,會跑的程式區塊。title = itnote = itit 是變數,就是這個 value 發生改變的時候的「值」。讀者可能會注意到前述提到 LazyColumnitems(entries) {} 也是類似的東西。

這是 Kotlin 的語法糖(少寫 code 的好東西 :-P)

items(entries) { entry -> // <== 這裡可以自訂這個 it 的名稱
    DiaryCard(entry)
}

否則不給名字,也可以寫成:

items(entries) {
    DiaryCard(it)
}

會拿到一樣的變數結果。

查證

從這邊看起來,變數存對。var titlevar note 分別被標題和內容的 TextField onValueChange callback 更新。那會不會是按下「儲存」按鈕,回錯?

https://ithelp.ithome.com.tw/upload/images/20260824/2014161515O2McSpTP.png

看一下「儲存」按鈕按下去 onClick 後,onSave Function 被叫,同時把 title 和 note 帶回去。
防止忘記,onSave Type 是:(String, String) -> Unit 可以塞兩個 String 傳回去。

這裡看起來也是對⋯ 通常這種時候就好想下班⋯ 好想逃離這一切。
但就像那個挖礦後面有鑽石的圖,答案可能呼之欲出囉。

按下儲存後回傳有問題?

DiaryForm() 把變數回覆給上面叫它的人 (回去 PhotoDiaryApp 程式區塊),做了什麼呢?

https://ithelp.ithome.com.tw/upload/images/20260824/20141615iWe6CvvlHj.png

先看 onSave = 這一塊,還記得 onSave 的 Type 接受兩個 String 嗎?從大括號後面的兩個變數,就是 依照這個順序取出來的,所以第一個值是 title,第二個值是 note,往回看,的確沒有傳錯。

仔細一看會發現,小丑竟是我自己!? 🤡
新建一個 DiaryEntry 的時候竟然放反了 =.=

	DiaryForm(
		onSave = { title, note ->
			entries = listOf(
				DiaryEntry(
					photoResId = R.drawable.diary_default,
					title = note,  // <== =.=
					note = title,  // <== =.=
					mood = "平靜",
					createdAt = LocalDateTime.now()
				)
			) + entries  // <== 塞到本來的列表裡
			isAddingDiary = false
		}
	)

太瞎了,不過老實說在實務上還真的就常有這種瞎事發生。(天啊,好想去渡假⋯)
Day05 的修正,只需要把 titlenote 放到對應的地方即可。

恭喜大家,這大概就是工程師的日常了!瘋狂的通靈找問題算是工作的一環,
現在還沒洗頭,還來得及!(開玩笑的)

TL;DR

  • 資料流(Data Flow):程式跑起來時,資料怎麼流動最重要;今天要用它查「按鈕按下去、Function 回傳什麼、誰呼叫誰、誰用這個變數」。
  • List(列表)DiaryList 吃的是一串 DiaryEntry;日記的基本資訊都在這份列表裡,卡片畫面是照它印出來的。
  • LazyColumn / items()LazyColumn 用來重複印出行;items() 代表每個物件都跑一次後面的區塊,所以每個 entry 都會變成一張 DiaryCard
  • 從物件取值entry.titleentry.note 是從那一筆日記拿出標題和內容;查卡片時先確認這裡有沒有放反呵呵。
  • callbackDiaryForm 接受兩個 callback Function;「按下儲存」時會把兩個 String 帶回去給叫它的人。
  • String:文字的 Type,在 Android/Kotlin 裡用來存「文字」;今天標題和內容就是兩個 String 在流動。
  • Char:單一字元的 Type(例如 a);實務上大多還是用 String。
  • it(語法糖):沒幫 callback function/lambda 參數取名時,值就叫 itonValueChangetitle = it,和 items(entries) { DiaryCard(it) } 是同一套少寫 code 的寫法。
  • Function 的 Type (String, String) -> UnitonSave 可以塞兩個 String 傳回去;大括號後的兩個變數是依這個順序取出來的
  • 對到 DiaryEntry 的欄位:新建日記時 title =note = 要接到對的值;今天的 bug 就是這兩個放反了。

上一篇
[Day04] 第一個手作りAndroid App —— 照片日記!
下一篇
[Day06] Class 與物件、Properties
系列文
我的第一個手作りAndroid App!快樂學習物件導向程式設計!6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndyAWD
iT邦新手 1 級 ‧ 2026-08-24 23:01:42

照片中紅衣服的人是誰啊

你想知道嗎?告訴你一個活動,每個月的第二個星期二的晚上的 TOOCON,可以找到他

我要留言

立即登入留言