共用方式為


Surface Duo 螢幕管理員

警告

此元件已被取代,不再受到支援。

為了取得顯示區域和折迭功能的相關資訊,您應該使用 [ Jetpack] 視窗管理員

或者,您也可以使用其中一個可自動適應雙螢幕和 foldabe 裝置的 雙螢幕控制項和版面 配置。

SurfaceDuoScreenManager 是兩種不同的螢幕管理員實作的常見通訊協定,一種是使用 Microsoft DisplayMask 程式庫,另一種是使用 Google WindowManager 程式庫。 這個介面會定義應該用來註冊和取消註冊螢幕資訊接聽程式的方法。

若要建立 [螢幕管理員],您應該使用 ScreenManagerProvider.getScreenManager(),這會傳回 SurfaceDuoScreenManager 實作的單一執行個體。 呼叫此方法之前,應先在 Application.onCreate() 內部呼叫 ScreenManagerProvider.init(Application),以初始化 SurfaceDuoScreenManager的單一執行個體。 這是必要的呼叫;否則,將會擲回 IllegalStateException("SurfaceDuoScreenManager must be initialized inside Application#onCreate()") 例外狀況。 當您擁有的實例 SurfaceDuoScreenManager 之後,您可以使用 SurfaceDuoScreenManager.addScreenInfoListener(ScreenInfoListener?) 註冊 ScreenInfoListener 回呼,以便在螢幕模式變更時收到通知。 請記住,您也可以新增多個接聽程式,因此應該使用 SurfaceDuoScreenManager.removeScreenInfoListener(ScreenInfoListener?) 將其取消註冊,以避免記憶體洩漏。

此外,如果您決定要處理設定變更,則您應該從 Activity 呼叫 SurfaceDuoScreenManager.onConfigurationChanged(Configuration) ; 否則,將不會觸發回呼。

class SampleApp : Application() {
    override fun onCreate() {
        super.onCreate()
        ScreenManagerProvider.init(this)
    }
}
class SampleActivity : AppCompatActivity(), ScreenInfoListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)
    }

    override fun onScreenInfoChanged(screenInfo: ScreenInfo) {
        if (screenInfo.isDualMode()) {
            // TODO: Add dual-screen behavior.
        } else {
            // TODO: Add single-screen behavior.
        }
    }

    override fun onResume() {
        super.onResume()
        ScreenManagerProvider.getScreenManager().addScreenInfoListener(this)
    }

    override fun onPause() {
        super.onPause()
        ScreenManagerProvider.getScreenManager().removeScreenInfoListener(this)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        ScreenManagerProvider.getScreenManager().onConfigurationChanged()
    }
}

另一個必須在不需要註冊回呼的情況下擷取 ScreenInfo 物件的選項,就是使用 ScreenInfoProvider.getScreenInfo(Context) 方法。 請記住,將視圖附加至視窗之後,應該呼叫此方法;否則,ScreenInfo 中的某些方法會傳回 null 或擲回例外狀況。

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)

        window?.decorView?.rootView?.let { rootView ->
            if (ViewCompat.isAttachedToWindow(rootView)) {
                val screenInfo = ScreenInfoProvider.getScreenInfo(this)
            } else {
                rootView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
                    override fun onViewAttachedToWindow(view: View) {
                        rootView.removeOnAttachStateChangeListener(this)
                        val screenInfo = ScreenInfoProvider.getScreenInfo(this)
                    }

                    override fun onViewDetachedFromWindow(view: View) {}
                })
            }
        }
    }
}

如果您使用 Core Ktx 程式庫,則:

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)

        window?.decorView?.rootView?.doOnAttach {
            val screenInfo = ScreenInfoProvider.getScreenInfo(this)
        }
    }
}