公司需要,定制化开发一机双屏且两块屏幕显示不同信息、可进行不同操作的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) } }