"Interaction-Feedback"
- 互動回饋三層模型:點擊確認、等待指示、結果通知
使用者操作後的回饋依時間分層,缺層的症狀是重複提交與重複導航 — 診斷「按了沒反應」與多步驟流程卡狀態問題的檢查框架,涵蓋按鈕級與畫面級兩個尺度。
- 按鈕狀態設計:一個按鈕的完整生命週期
按鈕每種視覺狀態各傳達一種系統訊息 — 設計按鈕互動、無障礙焦點與非同步回饋時的狀態清單依據。
- 時間感知與回應策略:Loading 的形式由等待時間門檻決定
100ms / 400ms / 1s / 10s 時間門檻對應不同回饋策略 — 決定操作該不該顯示 loading、用 spinner、skeleton 還是進度條的判準。
- 通知模式選擇:SnackBar、Dialog、Banner 與 Bottom Sheet
操作結果該用 SnackBar 閃一下還是彈 Dialog 問使用者 — 干擾程度與是否需要使用者操作的二軸判準,選錯形式的症狀是通知被忽略或流程被打斷
- Debounce(防連點)
說明合併短時間內重複觸發的技巧,以及 leading-edge 與 trailing-edge 兩種執行語意在按鈕防連點上的差別
- U.C5 匯出按鈕按下零回饋 — 狀態機完備但 UI 沒接線
Flutter app 匯出設定頁的確認匯出按鈕 onPressed 是空 callback,按下畫面毫無變化 — 使用者無法分辨匯出成功、進行中、還是功能根本沒做。ViewModel 的 idle/inProgress/completed/failed 狀態機早已完備,缺的只是頁面接線與三層回饋
- Doherty Threshold(400ms 門檻)
說明 400ms 回應時間門檻的出身(IBM 生產力研究)、現代設計慣例的轉譯過程,以及它跟 Nielsen 感知門檻的量測差異
- Touch Target(觸控目標)
實機測試點列表行文字卻無反應、或可用性測試觀察到使用者重複點擊同一行時使用。觸控目標有兩層要求:尺寸不小於平台底線、範圍涵蓋視覺暗示的可點區域——後者在列表行展開/收合場景最常被忽略。
- U.C7 商品條碼的誤導性查無結果 — 可本地判定的錯誤讓使用者白等 API
Flutter app 的 ISBN 掃描器接受所有 EAN-13 條碼,掃到一般商品條碼(非 978/979 開頭)時送 API 查詢,2 秒後回「查無結果」— 訊息誠實但誤導,使用者以為書找不到,實際上是掃錯了條碼。正確回饋是本地立即判定「這不是書籍條碼」
- Affordance(操作暗示)
說明介面元素透過外觀傳達「可以對它做什麼」的訊號 — 可點、可捲、可拖的暗示與實際行為對齊時介面才可預測
- U.C8 標籤行只有箭頭可點 — 觸控目標小於視覺單元
列表行的展開/收合看起來整行可點、實機測試點文字卻無反應時使用。gesture 只掛在尾端箭頭 icon 上、整行的視覺暗示範圍遠大於實際可點區域,使用者體感等同功能壞掉。
- U.C9 提取成功卻誤報失敗 — 結果通知鏈路被搶通道
操作實際成功、資料已寫入,UI 卻顯示失敗時使用。多 context 的訊息通道語意(誰負責回應)是結果通知鏈路的一部分,async listener 搶通道會把 undefined 當成回應送回
- U.C11 抓到 96/928 本就顯示完成 — 完成判定的證據強度不足
批次 / 遍歷類操作宣告完成、實際只處理了一部分:「連續 N 輪沒有變化」是暫時停滯的訊號、不是窮盡的證據 — 完成判定需要獨立的窮盡證據(總數對照、終止標記)
- U.C15 切換按鈕顯示目標模式被讀成當前狀態 — 標籤語意歧義
模式切換按鈕的文字被使用者讀成「現在的狀態」而非「按了會去哪」— 單顆文字按鈕無法自證標籤是現態還是目標,歧義是結構性的,解法是把狀態顯示與切換動作的責任拆開
- U.C18 狀態圖示被當成按鈕點 — 非互動指示與動作按鈕同形
使用者回報「某個按鈕點了沒反應」、查程式發現那不是按鈕時使用。非互動的狀態圖示與動作按鈕同列混排且形態近似(描邊 vs 實心),使用者無法區分可點性
- U.C19 「已選擇」計數被版面擠壓成省略號 — 回饋死在 layout
狀態文字顯示成「...」、資料層查起來卻一切正常 — 回饋鏈的最後一哩是版面,flex 寬度競爭把關鍵計數整串壓成省略號,state 正確、使用者拿到零資訊
- U.C20 管理模式操作全是佔位 — dev toast 讓未接線看起來有反應
UI 有按鈕、domain 層功能也寫完、按下去只有開發提示或 log:佔位 handler 比沒有按鈕更糟 — 按鈕的存在承諾功能存在,dev toast 讓開發自測「有反應」、掩蓋未接線