在開發 Android 應用程式時,特別是需要處理多螢幕顯示的情況,比如外接顯示器或投影機,了解如何管理不同的螢幕(Display)就變得非常重要。今天,我想跟大家分享一些關於如何取得和操作螢幕的 displayId
、Context
、WindowManager
,以及如何在指定的螢幕上啟動 Activity 或添加 View 的方法。
主螢幕的 displayId
通常是 0
。如果你想知道你的應用程式目前在哪個螢幕上運行,可以用 Context
或 WindowManager
來取得:
kotlin
複製程式碼
// 方法一:透過 Context 或 View
val displayId = context.display?.displayId ?: -1
val displayIdFromView = view.display.displayId
// 方法二:透過 WindowManager
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val displayIdFromWindowManager = windowManager.defaultDisplay.displayId
注意:如果 display
是 null
,那可能是因為 View 或 Activity 還沒初始化,或者還沒被加入到 ViewGroup 中。
displayId
通常是 0
。displayId
可能是 1
、2
、3
,依此類推。displayId
可能會改變,不一定跟之前一樣。每個螢幕的 displayId
、Context
、WindowManager
都不一樣,所以在操作時要特別小心。例如,當你想在不同的螢幕上做些事情,可以這樣取得對應的 Context
和 WindowManager
:
val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
for (display in displayManager.displays) {
val displayId = display.displayId
val displayContext = context.createDisplayContext(display)
val displayWindowManager = displayContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
// 你可以在這裡用 displayContext 和 displayWindowManager 做你想做的事
}
如果你想知道裝置上所有螢幕的資訊,包括它們的解析度,可以這樣做:
val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
for (display in displayManager.displays) {
val metrics = DisplayMetrics()
display.getRealMetrics(metrics)
Timber.d("Display ID: ${display.displayId}, 解析度: ${metrics.widthPixels}x${metrics.heightPixels}")
}
這段程式碼會把所有螢幕的 displayId
和解析度都列出來。
一般來說,當你啟動一個 Activity,它會在你應用程式當前所在的螢幕顯示。但如果你想讓它在指定的螢幕上出現,可以這樣做:
val options = ActivityOptions.makeBasic()
options.launchDisplayId = 2 // 這裡填你想指定的 DisplayId
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent, options.toBundle())
注意:要確保你指定的 displayId
是存在的,否則可能會啟動失敗哦。
有時候,你可能想在特定的螢幕上添加一些 View。你可以這樣做:
val displayId = 2 // 指定你想要的 DisplayId
val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val display = displayManager.getDisplay(displayId)
val displayContext = context.createDisplayContext(display)
val displayWindowManager = displayContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
// 創建你想要添加的 View
val myView = View(displayContext)
// 設定 LayoutParams
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT
)
// 在指定的螢幕上添加 View
displayWindowManager.addView(myView, params)
有時候,我們需要知道應用程式實際佔用了多少螢幕空間。可以用以下方法取得:
fun Context.getCurrentScreenSize(): Size {
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Android 11 以上
val windowMetrics = windowManager.currentWindowMetrics
val bounds = windowMetrics.bounds
Size(bounds.width(), bounds.height())
} else {
// Android 11 以下
val display = windowManager.defaultDisplay
val displayMetrics = DisplayMetrics()
display.getMetrics(displayMetrics)
Size(displayMetrics.widthPixels, displayMetrics.heightPixels)
}
}
如果你需要取得整個螢幕的實際解析度,包括狀態列和導航列,可以這樣做:
fun Context.getRealScreenSize(): Size {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && this is Activity) {
// Android 11 以上
val windowMetrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
val bounds = windowMetrics.bounds
Size(bounds.width(), bounds.height())
} else {
// Android 11 以下
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val display = windowManager.defaultDisplay
val displayMetrics = DisplayMetrics()
display.getRealMetrics(displayMetrics)
Size(displayMetrics.widthPixels, displayMetrics.heightPixels)
}
}
在多螢幕的環境下開發 Android 應用程式,需要特別注意不同螢幕的 displayId
、Context
、WindowManager
等資源。希望透過這些小技巧,你能更輕鬆地:
displayId
。displayId
是如何分配的。Context
和 WindowManager
。希望這些內容對你有幫助,讓你在開發多螢幕應用程式時更得心應手!
參考資料: