)
Open Headunit HeadUnitScreenConfig 屏幕配置模型一套配置管所有顯示參數(shù)【免費(fèi)下載鏈接】open-headunitHeadunit App for displaying Android Auto項(xiàng)目地址: https://gitcode.com/GitHub_Trending/he/open-headunitOpen Headunit 是一款把 Android 平板或手機(jī)變成 Android Auto 車機(jī)主機(jī)的開源應(yīng)用而 HeadUnitScreenConfig.kt 是它的屏幕配置中樞分辨率、DPI、縮放比例、邊距、畫面填充模式……所有顯示參數(shù)都由這一個(gè)對(duì)象統(tǒng)一計(jì)算、統(tǒng)一出口。搞懂它你就搞懂了 Open Headunit 的屏幕配置模型。為什么需要一套配置管所有顯示參數(shù)車機(jī)上投屏的顯示效果取決于一串參數(shù)投到車機(jī)上的分辨率是多少畫面按 FILL/CONTAIN/COVER 哪種方式適配四周留多少邊距DPI 是多少像素寬高比是多少如果每個(gè)模塊各自計(jì)算參數(shù)之間必然打架。Open Headunit 的做法是把全部顯示參數(shù)收攏進(jìn)HeadUnitScreenConfig這個(gè)單例對(duì)象外部模塊只負(fù)責(zé)讀結(jié)果和上報(bào)變化計(jì)算邏輯只有一份。核心配置模型它到底管哪些參數(shù)HeadUnitScreenConfig以 Kotlin 單例object形式存在核心狀態(tài)包括參數(shù)含義screenWidthPx / screenHeightPx剔除系統(tǒng)邊條后可用的投屏畫布尺寸density / densityDpi屏幕密度可被用戶在設(shè)置中手動(dòng)覆蓋scaleFactor / scaleFactor投屏畫面的縮放系數(shù)negotiatedResolutionType與手機(jī)協(xié)商后的視頻分辨率800x480 至 4KvideoFitMode畫面填充模式FILL / CONTAIN / COVERsystemInsetLeft/Top/Right/Bottom系統(tǒng)邊條導(dǎo)航欄、劉海等內(nèi)邊距isResolutionLocked分辨率鎖定狀態(tài)防止會(huì)話中途重協(xié)商這些字段幾乎都有private或private set外部只能調(diào)用方法取值——這就是單一出口的關(guān)鍵init(context, displayMetrics, settings) 是唯一的寫入口。配置是怎么算出來(lái)的四步流水線第一步選一個(gè)錨點(diǎn)畫布投屏區(qū)域到底以誰(shuí)為準(zhǔn)ProjectionCanvasPolicy.kt 定義了清晰的優(yōu)先級(jí)SURFACE真實(shí)渲染表面最權(quán)威WINDOWActivity 窗口布局區(qū)域CACHE上次會(huì)話在同一設(shè)置下測(cè)量的畫布DISPLAY系統(tǒng)顯示指標(biāo)兜底測(cè)量值還會(huì)打上設(shè)置哈希標(biāo)簽——設(shè)置一變舊測(cè)量自動(dòng)作廢。第二步減去內(nèi)邊距得到可用畫布updateInsets()會(huì)在系統(tǒng)邊條出現(xiàn)/消失時(shí)實(shí)時(shí)刷新 systemInset 四值避免邊條被重復(fù)減掉兩次這類細(xì)節(jié)問(wèn)題。第三步協(xié)商分辨率并封頂recalculate() 是核心引擎按用戶選擇的分辨率調(diào)用 NegotiatedResolutionPolicy 選出協(xié)商分辨率用SystemOptimizer.hardCeiling給小屏封頂避免小面板解碼超出自身能力的大幀若設(shè)備只有 2.4GHz 無(wú)線鏈路NarrowBandProfilePolicy 會(huì)按帶寬再降一檔原則始終是只降不升用戶主動(dòng)選的低分辨率絕不被抬高第四步算出縮放與邊距最終通過(guò) ProjectionGeometryPolicy.kt 產(chǎn)出getScaleX()、getWidthMargin()、getLeftMargin()等對(duì)外 APIgetPixelAspectRatioE4() 則自動(dòng)推算非正方形像素比保證地圖和卡片不被拉扁。誰(shuí)在消費(fèi)這套配置這是單一出口設(shè)計(jì)的價(jià)值所在四類關(guān)鍵消費(fèi)方對(duì)手機(jī)報(bào)數(shù)ServiceDiscoveryResponse.kt 在服務(wù)發(fā)現(xiàn)階段把協(xié)商分辨率、寬高邊距、DPI、像素比一次性發(fā)給 Android Auto 手機(jī)?渲染與觸摸AapProjectionActivity.kt 在表面尺寸變化時(shí)調(diào)用updateSurfaceDimensions()修正錨點(diǎn)并據(jù)此映射觸摸坐標(biāo)?視頻解碼VideoDecoder.kt 用getNegotiatedWidth/Height()配置解碼尺寸保證解出的幀和手機(jī)發(fā)來(lái)的幀嚴(yán)絲合縫連接管理CommManager.kt 在斷連時(shí)unlockResolution()下次連接重新協(xié)商設(shè)置變化時(shí)發(fā)生了什么computeSettingsHash()把分辨率、DPI、內(nèi)邊距、屏幕方向、全屏模式、填充模式等十余項(xiàng)設(shè)置算成一個(gè)哈希。任何一項(xiàng)變化都會(huì)解鎖舊分辨率 → 重新選畫布 → 重新協(xié)商 → 重新縮放。用戶在設(shè)置頁(yè)見 Settings.kt 中的resolutionId、videoFitMode、dpiPixelDensity等字段每次點(diǎn)應(yīng)用背后走的都是同一條流水線。邊距到底長(zhǎng)什么樣下面這張測(cè)試圖直觀展示了最終效果粉色是協(xié)商出來(lái)的邊距區(qū)域藍(lán)色中間矩形才是 Android Auto 畫面的實(shí)際落點(diǎn)——這正是getWidthMargin()/getHeightMargin()計(jì)算并告知手機(jī)的結(jié)果。小結(jié)值得學(xué)習(xí)的配置模型設(shè)計(jì)HeadUnitScreenConfig 給多參數(shù)聯(lián)動(dòng)類需求提供了一個(gè)教科書式答案?單一寫入點(diǎn)所有參數(shù)只由init()recalculate()計(jì)算?優(yōu)先級(jí)錨點(diǎn)真實(shí)測(cè)量 窗口 緩存 系統(tǒng)指標(biāo)?哈希失效機(jī)制設(shè)置一變舊數(shù)據(jù)整體作廢不做局部修補(bǔ)?只降不升的封頂策略面板能力、無(wú)線帶寬兩層 cap尊重用戶低配選擇?對(duì)外只讀 API調(diào)用方永遠(yuǎn)拿到一致的一組數(shù)值相關(guān)模塊路徑速查配置中樞app/src/main/java/com/andrerinas/openheadunit/utils/HeadUnitScreenConfig.kt畫布選擇策略app/src/main/java/com/andrerinas/openheadunit/utils/ProjectionCanvasPolicy.kt分辨率協(xié)商app/src/main/java/com/andrerinas/openheadunit/utils/NegotiatedResolutionPolicy.kt設(shè)置存儲(chǔ)app/src/main/java/com/andrerinas/openheadunit/utils/Settings.kt屏幕方向策略app/src/main/java/com/andrerinas/openheadunit/utils/ScreenOrientationPolicy.kt單元測(cè)試app/src/test/java/com/andrerinas/openheadunit/utils/ScreenSettingsHashTest.kt理解了這套一套配置管所有顯示參數(shù)的模型無(wú)論是調(diào)試投屏比例還是給項(xiàng)目提 PR你都能快速定位問(wèn)題出在畫布、邊距還是協(xié)商環(huán)節(jié)?!久赓M(fèi)下載鏈接】open-headunitHeadunit App for displaying Android Auto項(xiàng)目地址: https://gitcode.com/GitHub_Trending/he/open-headunit創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考