一 简介

1.1 我们用的手机基本上只有一个屏幕,那这里的双屏指的什么呢?其实现在手机都是支持双屏的,我们可以在开发者选项里面来打开这个控制,来看下什么是双屏。

可以打开设置 -> 开发者选项 -> 模拟辅助显示设备来开启副屏显示,还可以选择显示尺寸

1.2 不过手机上使用双屏场景比较少,更多的用在一些人脸识别支付,或者扫码,刷卡支付这些设备设备上。

主屏用于人脸,扫码,刷卡。

副屏有键盘输入,用于输入金额,查询交易记录这些工作。

比如下面这种团餐机就是典型的双屏支持

 二,双屏程序的实现

2.1 主屏,即扫码屏不用多说,正常的Activity页面。副屏(带键盘)需要借助原生API中的Presentation类

2.2 Presentation是一个特殊的 dialog ,主要的目的是在辅助显示屏上显示内容,Presentation 在创建的时候需要和特定的 Display 相关联。既是Dialog所以在构造函数中传递的 context 必须是一个 activity 的 context。

如下源码可以看出是继承于Dialog的

2.3 理解了Presentation,那后面开发就容易了,只需要用Activity控制Dialog就可以了。

但到后面你会发现还是想简单了,因为副屏是不能触摸的,这也就造成输入框不能获取焦点,软键盘不能弹出,包括返回键这些都需要通过外设设备来控制。

那这个外设设备就是小数字键盘,其实就是普通键盘的数字区域

2.4 那怎样来监听数字键盘区域的输入呢,这个时候就需要一个key的映射关系。键盘上的按键都是由标准协议的,所以我们只需要找个找个标准的映射关系就可以了。如下图

android原生api提供有键盘事件的类KeyEvent.java,里面是全部的键盘点击事件

然后我们可以在事件分发里面来监听点击的键盘哪个按键

再对照下面的code和key关系映射,就可以知道我们按的哪个键了

 三,源码示例

3.1 设置权限,也可以不设置。如果想要Presentation不随主Activity退出,必须加上系统弹框权限

<!--显示系统窗口权限--><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/><!--在屏幕最顶部显示addview-->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

3.2 自定义Presentation

public class SecondLoginPresentation extends Presentation {public SecondLoginPresentation(Context outerContext, Display display) {super(outerContext,display);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second_screen);}
}

3.3 在Acitivty里面显示这个副屏,注意这个地方要先判断是否有副屏

//显示副屏幕
SecondLoginPresentation mPresentation;private void showDisplay() {DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);if (presentationDisplays.length > 0) {//判断是否有双屏// displays[0] 主屏// displays[1] 副屏Display display = presentationDisplays[0];if (mPresentation == null) {mPresentation = new SecondLoginPresentation(this, display);try {mPresentation.show();} catch (WindowManager.InvalidDisplayException e) {mPresentation = null;}}}
}

3.4 监听键盘输入,注意这个也只能在Activity里面才能监听到

只需要监听我们需要的按键即可

@Override
public boolean dispatchKeyEvent(KeyEvent event) {if (keyListener != null) {int action = event.getAction();switch (action) {case KeyEvent.ACTION_DOWN:if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_HOME) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {return super.dispatchKeyEvent(event);}if (event.getKeyCode() == KeyEvent.KEYCODE_F1) {keyListener.textSure("功能");return true;} else if (event.getKeyCode() == KeyEvent.KEYCODE_F2) {keyListener.textSure("设置");return true;} else if (event.getKeyCode() == 111 || event.getKeyCode() == 4) {keyListener.textSure("取消");return true;} else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {keyListener.textSure("删除");return true;} else if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {keyListener.textSure("确认");return true;} else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {keyListener.textSure("上箭头");return true;} else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {keyListener.textSure("下箭头");return true;} else {int unicodeChar = event.getUnicodeChar();keyListener.textChange(String.valueOf((char) unicodeChar));return true;}}}return super.dispatchKeyEvent(event);
}

3.5 SecondLoginPresentation处理键盘事件

@Override
public void textChange(String text) {//数字输入addTextValue(text);
}@Override
public void textSure(String value) {//除数字之外按键switch (value) {case "功能":break;case "设置":break;case "删除":popTextValue();break;case "取消":break;case "确认"://开始支付逻辑//....................................break;case "上箭头":break;case "下箭头":break;}
}//输入键盘监听-添加
private Stack<String> mNumberStack = new Stack<>();public void addTextValue(String value) {//限制输入数字或者小数点if (!Utils.isNumeric(value)) {return;}String moneyString = etInputContent.getText().toString();//确保第一位不是.和+if ((value.equals(".") || value.equals("+")) && moneyString.length() <= 0) {return;}//确保不输入连续的+if (value.equals("+") && moneyString.endsWith("+")) {return;}//确保不是连续小数点if (value.equals(".") && moneyString.endsWith(".")) {return;}//确保一个小数点,后面两位//获取最后一个加号的索引String lastPartString="";if (moneyString.length() > 0 && moneyString.contains("+")) {lastPartString = moneyString.substring(moneyString.lastIndexOf("+"));}else {//如果长度小于0表示还没输入过加号,那最后一段就是完整内容lastPartString = moneyString;}if (!value.equals("+") && lastPartString.contains(".") && lastPartString.substring(lastPartString.indexOf(".")).length() > 2) {return;}//确保当前段不包含两个小数点if (value.equals(".") && lastPartString.contains(".")) {return;}//限制最大金额-7位
//        if (!TextUtils.isEmpty(moneyString) && moneyString.length() >= 7) {
//            return;
//        }//确保第一位不为0if (moneyString.length() == 1 && moneyString.startsWith("0") && !value.equals(".")) {mNumberStack.clear();}mNumberStack.push(value);showTextValue();
}//输入键盘监听-删除
public void popTextValue() {if (mNumberStack.empty()) {return;}mNumberStack.pop();showTextValue();
}//显示输入内容
public void showTextValue() {StringBuilder codeBuilder = new StringBuilder();for (String value : mNumberStack) {codeBuilder.append(value);}etInputContent.setText(codeBuilder.toString());moneyInputResult();
}//计算总金额
public void moneyInputResult() {String inputString = etInputContent.getText().toString();String moneyResult = "";if (!TextUtils.isEmpty(inputString)) {if (inputString.contains("+")) {String[] stringsArray = inputString.split("\\+");for (String ss : stringsArray) {moneyResult = add(TextUtils.isEmpty(moneyResult) ? "0" : moneyResult, ss);}} else {moneyResult = inputString;}}etMoney.setText(moneyResult);
}/*** 加减法精确计算类*//*** 加法*/
public static String add(String parms1, String param2) {return new BigDecimal(parms1).add(new BigDecimal(param2)).toString();
}

四 总结

4.1 Presentation是一个不能触摸的Dialog,所以所有事件要监听外部设备来处理

4.2 Presentation正常情况是随Activity退出的,想要不随Activity退出,需要添加系统弹框权限

4.3 大多情况跟dialog用法没什么区别,主要能了解键盘的映射关系即可,用键盘俩操作页面

Android之 双屏异显控制相关推荐

  1. Android Q 双屏异显

    Android Q 双屏异显 现在很多AR场景,需要扩展屏或者虚拟屏VD 进行展示3D画面,并通过手柄或者手机模拟的触摸板进行交互控制.从android官网多屏幕支持了解其android Q 已经有多 ...

  2. android实现双屏异显,双触摸输入

    深圳市灵动高科的ST-H8-01S安卓主板具有双屏同显.异显功能,并且支持双触摸屏输入,一个操作主屏,另外操作副屏.板载了可以支持3.3V/5V电平的串口,适用于POS机以及广告系统显示等行业. 双路 ...

  3. android studio 双屏,Android Presentation双屏异显,副屏的操作

    最近有一个双屏显示的需求,当时一脸蒙逼完全不知如何着手,不负众望找到解决办法,在Android4.2版本以后提供了Presentation类,可以轻松实现在两块屏幕上同时显示不同的内容.做一下笔记. ...

  4. Android双屏异显的实现

    概述 Android实现双屏异显的实现方式有2种. 方式一:在Android4.2及以上平台上,按照标准Android SDK提供的API,使用Presentation类,将一个APP的相关内容显示到 ...

  5. Android 双屏异显

    背景: 日常生活中,有时候会遇到 Android 设备连接两个屏幕进行显示的问题,比如酒店登记信息时,一个屏幕用于员工操作,一个屏幕显示相关信息供顾客查看.这里就涉及到 Android 的双屏异显的问 ...

  6. Android 双屏异显(Presentation) 开发,将第二个页面投屏到副屏上

    1. 背景 最近开发的一个项目,有两个屏幕,需要将第二个页面投屏到副屏上, 这就需要用到Android的双屏异显(Presentation)技术了,研究了一下,这里做下笔记. 我们那个副屏是一块汽车的 ...

  7. 【Android双屏异显】如何真正的实现Android双屏异显

    最近在做一个Android双屏异显的项目,要实现一台Android设备通过HDMI连接两个显示器,然后在一个App中同时显示两个不同的画面. 标题实际上Android并不存在真正的像Windows一样 ...

  8. 【转载】Android 双屏异显方案

    一.技术的背景 随着电梯广告传媒行业的飞速发展,双屏广告机应运而生,客户可以根据自己的需求,制作两个屏幕的内容,分别播放适合屏幕显示方式播放的内容,如上面播放视频,下面播放图片,使得宣传的效果多样化. ...

  9. java 双屏显示_Android双屏异显的实现

    概述 Android实现双屏异显的实现方式有2种. 方式一:在Android4.2及以上平台上,按照标准Android SDK提供的API,使用Presentation类,将一个APP的相关内容显示到 ...

最新文章

  1. 从面试角度分析ArrayList源码
  2. 最新网众 2490(XP) 客户端 去百度 去劫持 去快车
  3. Matplotlib实例教程(一):柱状图(条形统计图)plt.bar()
  4. 【黑马程序员】————预处理指令1-宏定义
  5. [css] 你有用过vw布局吗?和使用rem有什么区别?
  6. Hadoop日志分析工具——White Elephant
  7. 编程不需要天赋和激情
  8. IPsec ***路由配置
  9. React Ant Design UI 图片上传组件 代码片段
  10. 【数字信号调制】基于matlab GUI数字信号调制系统【含Matlab源码 258期】
  11. 记录贴,使用PDFviewer时遇到的导入问题
  12. 对称密钥加密、非对称密钥加密、混合加密机制
  13. js实现-别踩白块儿-类
  14. 计算机自动开机关机设置在哪里设置密码,怎样设置开关机密码
  15. 聊聊那些我们不应该被百度惯坏的搜索技巧
  16. Fips模式下应用连接Oracle SSL
  17. 纯CSS3模拟iPhone X背景切换动画
  18. 解决C#调用Excel接口时报错,提示:Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Offi
  19. 爬虫之scrapy框架的数据持久化存储/保存为scv,json文件
  20. 案例:后台管理案例(VUE路由案例)

热门文章

  1. 7-4 打印倒直角三角形图形(10 分)
  2. 对于CRITICAL_SECTION用法的介绍和理解
  3. 如何用C语言编写暴力破解压缩文件解压密码的程序
  4. C++ --虚析构和纯虚析构
  5. Android Studio CMake使用笔记
  6. nc63,nc65,ncc1811,ncc1903,ncc1909,ncc2005,ncc202111勒索病毒安全补丁
  7. Java异常基础+原理解析+自定义异常
  8. 手机学python用什么浏览器_Python+Appium学习之启动手机浏览器
  9. 【RS】报文的分类和标记
  10. 美标C95400铝青铜套C95400耐磨性能