Android 應用程式可執行的板型規格不只直向放置的手機。 隨著電腦分割視窗模式、外接螢幕和摺疊式裝置的推出,相機應用程式必須配合動態視窗大小、不同顯示比例和外部硬體調整。
電話邏輯中斷的原因
相機應用程式經常會做出假設,導致多種外型規格環境發生重大錯誤。
自然方向
- 假設:裝置的自然方向
ROTATION_0一律為直向 - 實際情況:在平板電腦、部分摺疊裝置的內螢幕和桌上型螢幕上,
ROTATION_0通常會以橫向顯示 - 結果:預覽畫面未正確旋轉 90 度
感應器對齊
- 假設:相機感應器的長邊與螢幕的長邊對齊
- 實際情況:可調整大小的視窗可以是正方形或橫向,感應器則保持固定 (通常為 4:3)
- 結果:圖片遭到延展或變形
螢幕密度和大小
- 假設:螢幕的密度和大小不會在執行階段變更
- 事實:在電腦環境中,使用者可以自由調整視窗大小
- 結果:在每個拖曳事件中重新啟動攝影機工作階段,會中斷使用者體驗,並可能導致當機
解決方案 1:使用系統意圖
如果應用程式需要拍攝相片或影片,但不需要專用的自訂相機介面,處理不同外型的最佳方式是啟動裝置預先安裝的系統相機 (請參閱「相機意圖」)
使用系統意圖可將整個擷取體驗委派給裝置原始設備製造商 (OEM) 開發的相機應用程式。這項功能可有效外包表單因子的支援複雜度,包括:
內建大小調整和旋轉支援:摺疊式裝置或平板電腦上的預設相機應用程式,是由製造商專為處理特定裝置的幾何形狀而建構。應用程式的設計可確保裝置展開、旋轉或進入多視窗模式時,應用程式能正常運作。
存取進階硬體功能:OEM 相機應用程式可專屬存取硬體調整演算法 (夜間模式、HDR、特定鏡頭切換),這些演算法難以或無法手動複製。
解決方案 2:使用 Jetpack CameraX
CameraX 是 Jetpack 程式庫,旨在簡化相機應用程式的開發作業。CameraX 可感知生命週期,並以 Surface 為導向。 與 Camera2 不同,每當裝置摺疊、旋轉或調整大小時,CameraX 會自動處理攝影機工作階段的重新設定,確保預覽串流會適應,不會發生延遲或延展的情況。Camera2 則需要手動重新計算感應器方向和表面大小。
PreviewView 等元件會智慧管理不同狀態下的長寬比和縮放類型,例如折疊式裝置從封面螢幕轉換到內螢幕時,可讓您透過單一一致的實作方式支援各種硬體,不必處理複雜的裝置專屬特殊情況。
撰寫
使用 Jetpack Compose 時,請使用專屬的 androidx.camera:camera-compose 程式庫。這個程式庫提供 CameraXViewfinder 可組合函式,專門處理 Compose 生命週期內的複雜幾何形狀,例如大小調整、旋轉和長寬比。
CameraXViewfinder 元件可消除相機應用程式中最常見的錯誤來源:
- 自動座標轉換:建構相機應用程式最困難的部分之一,就是將使用者的輕觸 (螢幕上的 x、y 座標) 對應至相機感應器的座標系統 (0-1、0-1 旋轉),以進行對焦和測光。
CameraXViewfinder提供CoordinateTransformer,即使視窗大小調整或裝置折疊,也能自動處理數學運算。 - 正確的版面配置行為:與
SurfaceView或TextureView不同,CameraXViewfinder可與 Compose 的 z 排序正確搭配使用。您可以疊加 UI 元素 (焦點環、控制項) 或套用修飾符 (圓角、動畫),而不會產生算繪構件。 - 調整大小和顯示比例:
CameraXViewfinder會在內部處理中央裁剪與配合中央邏輯,確保應用程式視窗調整為非標準顯示比例時 (例如分割畫面或桌面視窗模式),預覽畫面不會延展。
View
如果是以 View 為基礎的應用程式,請使用 PreviewView 或 ViewFinderView。
如果您直接使用 SurfaceView 或 TextureView,就必須自行計算長寬比,並套用正確的轉換矩陣。
解決方案 3:動態處理螢幕方向和大小調整
直接使用平台 API 時,請留意裝置旋轉、活動重新啟動和螢幕比例。
停止使用裝置旋轉功能
請勿單獨依賴 Display#getRotation() 或實體感應器方向來決定 UI 版面配置。
- 使用視窗指標:比較應用程式視窗的寬度和高度,藉此判斷版面配置 (橫向與直向 UI),請使用
WindowManager#getCurrentWindowMetrics()。 - 忽略自然方向:您的應用程式可能會在橫向螢幕上以直向視窗顯示。裝置螢幕方向與 UI 邊界無關。
避免活動重新啟動
根據預設,Android 會在設定變更 (例如調整視窗大小) 時刪除應用程式的活動。如果是相機應用程式,則會顯示螢幕閃爍或視訊通話期間連線中斷。
- 資訊清單設定:在資訊清單中宣告設定變更,即可處理大小調整作業,不必重新啟動。
- 動態更新:在
onConfigurationChanged()中,更新攝影機預覽的版面配置參數,以配合新的視窗大小。
顯示比例和裁剪
在摺疊式裝置和電腦視窗上,常見的問題是預覽畫面遭到延展,也就是 4:3 的攝影機畫面強制進入 16:9 或 1:1 的視窗。
- 請勿延展:如果預覽畫面和視窗的顯示比例不同,請勿強制攝影機緩衝區完全符合檢視範圍。
- 中央裁剪 (建議):縮放預覽畫面,填滿視窗最短的維度,並裁剪多餘部分。確保主體不會失真,並填滿畫面。
- 置中顯示 (替代方案):如果必須顯示完整視野 (例如掃描文件),請在視窗內以上下黑邊顯示預覽畫面。
- 置中顯示 (替代方案):如果必須顯示完整視野 (例如掃描文件),請在視窗內以上下黑邊顯示預覽畫面。
加分功能:支援摺疊裝置優先體驗
摺疊式裝置不只是可以彎曲的手機,還提供獨特的硬體狀態,從根本上改善使用者拍攝相片和影片的方式。請勿將摺疊視為待解決的問題,而是利用這項特性建構非摺疊裝置無法提供的功能。
免持模式 (免持拍攝)
免手持模式:使用者可將裝置半摺疊並放在平面上,進行長時間的視訊通話、縮時攝影,以及長時間曝光的夜間攝影。
後置螢幕模式 (高畫質自拍照)
- 在摺疊式手機上,後置鏡頭的畫質通常比前置鏡頭高。 後置螢幕模式可讓使用者展開裝置並轉向,將小型封面螢幕當做後置主鏡頭的即時觀景窗。
- 有了後螢幕模式,你就能拍攝 5000 萬像素以上的自拍、超廣角團體照,以及高品質的 Vlog,不必攜帶額外裝備。
雙螢幕模式 (主題預覽)
- 雙螢幕模式可讓您同時在內螢幕和外螢幕上顯示相機預覽畫面。這項功能非常適合拍攝人物: 拍攝對象可以在外螢幕上看到自己並調整姿勢, 而你則在內螢幕上取景。
- 與後螢幕模式 (會移動整個應用程式) 不同,雙螢幕模式會在封面螢幕上建立次要呈現視窗。