Android之 双屏异显控制
一 简介
1 我们用的手机基本上只有一个屏幕,那这里的双屏指的什么呢?其实现在手机都是支持双屏的,我们可以在开发者选项里面来打开这个控制,来看下什么是双屏。
可以打开设置 -> 开发者选项 -> 模拟辅助显示设备来开启副屏显示,还可以选择显示尺寸
1.2 不过手机上使用双屏场景比较少,更多的用在一些人脸识别支付,或者扫码,刷卡支付这些设备设备上。
主屏用于人脸,扫码,刷卡。
副屏有键盘输入,用于输入金额,查询交易记录这些工作。
比如下面这种团餐机就是典型的双屏支持
二,双屏程序的实现
1 主屏,即扫码屏不用多说,正常的Activity页面。副屏(带键盘)需要借助原生API中的Presentation类
2 Presentation是一个特殊的 dialog ,主要的目的是在辅助显示屏上显示内容,Presentation 在创建的时候需要和特定的 Display 相关联。既是Dialog所以在构造函数中传递的 context 必须是一个 activity 的 context。
如下源码可以看出是继承于Dialog的
2.3 理解了Presentation,那后面开发就容易了,只需要用Activity控制Dialog就可以了。
但到后面你会发现还是想简单了,因为副屏是不能触摸的,这也就造成输入框不能获取焦点,软键盘不能弹出,包括返回键这些都需要通过外设设备来控制。
那这个外设设备就是小数字键盘,其实就是普通键盘的数字区域
4 那怎样来监听数字键盘区域的输入呢,这个时候就需要一个key的映射关系。键盘上的按键都是由标准协议的,所以我们只需要找个找个标准的映射关系就可以了。如下图
android原生api提供有键盘事件的类KeyEvent.java,里面是全部的键盘点击事件
然后我们可以在事件分发里面来监听点击的键盘哪个按键
再对照下面的code和key关系映射,就可以知道我们按的哪个键了
三,源码示例
1 设置权限,也可以不设置。如果想要Presentation不随主Activity退出,必须加上系统弹框权限
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 在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;}}}}
4 监听键盘输入,注意这个也只能在Activity里面才能监听到
只需要监听我们需要的按键即可
@Overridepublic 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);}
5 SecondLoginPresentation处理键盘事件
@Overridepublic void textChange(String text) { //数字输入addTextValue(text);}@Overridepublic void textSure(String value) { //除数字之外按键switch (value) {case "功能":break;case "设置":break;case "删除":popTextValue();break;case "取消": break;case "确认": //开始支付逻辑//....................................break;case "上箭头":break;case "下箭头":break;}}//输入键盘监听-添加private Stack 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();}
四 总结
1 Presentation是一个不能触摸的Dialog,所以所有事件要监听外部设备来处理
2 Presentation正常情况是随Activity退出的,想要不随Activity退出,需要添加系统弹框权限
3 大多情况跟dialog用法没什么区别,主要能了解键盘的映射关系即可,用键盘俩操作页面
来源地址:https://blog.csdn.net/qq_29848853/article/details/130362129
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341