公司需要,定制化开发一机双屏且两块屏幕显示不同信息、可进行不同操作的app。说直白一点,就是一个运行Android系统的主机连接了两块屏幕,运行一个app但是两块屏幕各自操作各自的互不干扰;
通常情况下,两块屏幕有主副的区别,主屏幕的实现和以往是一样的,副屏会有区别;
Presentation:
android 中常用来实现副屏的API,主板可以有多个硬件显卡输出的接口,presentation 可以指定在哪个输出接口显示哪个页面,或者理解为,把哪个页面送到哪个输出接口去显示,这样就可以在两块或多个屏幕上显示不同的内容。这种情况下,副屏的实现类似一个特殊弹窗,这个弹窗覆盖在activity上,但是只在指定屏幕显示,这样主屏显示activity副屏显示弹窗就实现了双屏异显。
问题:
主副屏:一主机带两块屏幕的情况,一般会默认区分主副屏,不需要presentation再去设定了;
显示:主屏无特殊情况,但是副屏会比较特殊,由于副屏是一个特殊的弹窗,那在弹窗上展示弹窗就会出现问题,副屏无法展示弹窗例如dialog和toast,目前没有找到办法实现,都是自己模拟的弹窗;
键盘:副屏无法调用键盘获得输入,网上信息据说有支持副屏录入的键盘,但是我没有找到,目前只能 模拟数字、字母和特殊符号的键盘,汉字很麻烦没有实现,但是车牌号这种限定范围的汉字键盘是有的;
闪屏:副屏不同界面在切换的时候可能会出现闪屏,副屏的界面切换是关掉副屏A打开副屏B,猜测测试,副屏的生命周期比较简单,特殊弹窗也是弹窗,弹窗关闭后会先去显示activity然后再打开另外一个弹窗,建议自己维护一个副屏的实例list,始终保持有一个副屏不被关闭,这样在切换过成中就不会闪屏了,当然记得关闭副屏的时候清空list;
持久:副屏是一个特殊弹窗,弹窗就要有所依凭,如果依赖activity,那关闭这个activity就会关闭副屏,建议使用aplicationcontext,这样切换activity就不会影响到副屏了;
尺寸:副屏的尺寸和主屏不太一样,同一个控件设定一样的宽高尺寸显示效果是不同的,在开发过程中需要单独调试;
示例:
private lateinit var presentationList: ArrayList<Presentation>//防止闪屏所以要保留至少一个副屏
private lateinit var displayM: Display
private lateinit var displayListener: DisplayManager.DisplayListener
/**
* 获取屏幕管理控制器
*/
private fun handlePresentation() {
presentationList = ArrayList()
val mediaRouter = getSystemService(MEDIA_ROUTER_SERVICE) as MediaRouter
val router = mediaRouter.getSelectedRoute(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
val displays = router.presentationDisplay
if (displays != null) {
createDisplay(displays.displayId)
}
}
/**
* 获取屏幕控件
* @param displayId Int
*/
private fun createDisplay(displayId: Int) {
val displayManage = getSystemService(DISPLAY_SERVICE) as DisplayManager
displayM = displayManage.getDisplay(displayId)
}
/**
* 屏幕管理器监听
* 当外接屏幕增加减少时
*/
private fun initDisplayListener() {
displayListener = object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {
createDisplay(displayId)
}
override fun onDisplayRemoved(displayId: Int) {
}
override fun onDisplayChanged(displayId: Int) {
}
}
}
/**
*内存中只留取一个控制闪屏
*
**/
private fun presentationListCacheRemove() {
if (presentationList.size > 1) {
val tempPre = presentationList[0]
tempPre.dismiss()
presentationList.remove(tempPre)
}
}
/**
*添加进入缓存
*
**/
private fun presentationListCacheAdd(tempP: Presentation) {
presentationList.add(tempP)
}
/**
*实现副屏页面切换
*
**/
private fun showPresentation(presentation: BasePresentation) {
presentationListCacheRemove()
presentation.window?.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
presentation.show()
presentationListCacheAdd(presentation)
}
fun aP() {
val ap = Ap(this, displayM)
showPresentation(ap)
}
fun bP() {
val bP= Bp(this, displayM)
showPresentation(bP)
}
/**
*清空所有缓存避免溢出
*
**/
fun pQuit() {
if (presentationList.size > 0) {
val tempPre = presentationList[0]
tempPre.dismiss()
presentationList.remove(tempPre)
}
}