我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android之 双屏异显控制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

Android之 双屏异显控制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android Presentation实现双屏异显

一、概述 现在越来越多的Android设备有多个屏幕,双屏异显应用场景最多的应该就是类似于收银平台那种设备,在主屏上店员能够对点商品进行选择录入,副屏则是展示给我们的账单详情,但是它只通过了一个软件系统就实现了双屏异显这个功能,而Prese
2022-06-06

Android三种双屏异显实现方法介绍

现在越来越多的Android设备有多个屏幕,双屏异显应用场景最多的应该就是类似于收银平台那种设备,在主屏上店员能够对点商品进行选择录入,副屏则是展示给我们的账单详情,但是它只通过了一个软件系统就实现了双屏异显这个功能,而Presentation正是这其中的关键
2023-01-31

RK3288如何增加双屏异显 eDP+LVDS

这期内容当中小编将会给大家带来有关RK3288如何增加双屏异显 eDP+LVDS,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。CPU:RK3288系统:Android 5.1下面是官方文档中的信息。1、r
2023-06-05

AndroidPresentation双屏异显开发流程详细讲解

最近开发的一个项目,有两个屏幕,需要将第二个页面投屏到副屏上,这就需要用到Android的双屏异显(Presentation)技术了,研究了一下,这里做下笔记
2023-01-31

Android亮屏和熄屏控制实例详解

本文实例讲述了Android亮屏和熄屏控制实现方法。分享给大家供大家参考,具体如下: 一、概述 我们的Android应用程序很多需要和亮屏和熄屏打交道,比如闹钟的时候,需要保持亮屏,之后又需要熄屏。那么今天,我们来分析下这方面的功能。 二.
2022-06-06

浅谈Node.js之异步流控制

前言 在没有深度使用函数回调的经验的时候,去看这些内容还是有一点吃力的。由于Node.js独特的异步特性,才出现了“回调地狱”的问题,这篇文章中,我比较详细的记录了如何解决异步流问题。 文章会很长,而且这篇是对异步流模式的解释。文中会使用一
2022-06-04

Android实现原生锁屏页面音乐控制

Android5.0 提出了全新的MediaSession概念用于播放器与控制器之间进行交互,它取代之前的RemoteControlClient,并提供了更为灵活的客户端受控端模型。 但是MediaSession框架只能在安卓5系统上使用,
2022-06-06

Golang异常处理之优雅地控制和处理异常

在Golang中,异常处理是非常重要的一部分,能够有效地控制和处理代码中的异常情况。通过Golang的异常处理机制,可以优雅地捕获和处理异常,保障代码的可靠性和稳定性。同时,Golang还提供了丰富的工具和API,帮助开发者更加轻松地进行异常处理
2023-05-16

Android系统状态栏定制图标显示逻辑控制

这篇文章主要为大家介绍了Android系统状态栏定制图标显示逻辑控制,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

云服务器怎么远程控制手机屏幕显示

如果您想远程控制云服务器的屏幕显示,您可以使用以下步骤:打开云存储服务(例如Google云存储或Dropbox)并在电脑上创建一个新连接。在控制面板中启用云存储服务。在电脑上安装所需的应用程序,并在应用程序菜单中选择“管理存储”。在弹出窗口中,选择您想要远程控制云服务器的电脑。选择要控制的云服务器并输入您的账户和密码。请注意,为了安全考虑,在进行远程控制之前,您应该确定云服务器的
2023-10-26

云服务器怎么远程控制电脑屏幕显示

远程控制电脑屏幕显示可以通过以下方式实现:使用VNC远程控制软件(VNCControlProvider):VNC远程控制软件可以让您以虚拟用户的身份登录服务器并控制被授权的计算机屏幕。在VNC控制软件中,您可以使用以下代码来远程操作MicrosoftExchangeServer数据库:mkdir/s/a/home/admin使用SSH连接远程服务器:如果您的计算机与Microsof
2023-10-26

Android权限控制之自定义权限

天哪,这篇文章终于说道如何自定义权限了,左盼右盼,其实这个自定义权限相当easy。为了方便叙述,我这边会用到两个app作为例子示范。 Permission App: used to define a new permission 这个作为定
2022-06-06

Android自定义控件制作显示进度的Button

最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的Button直接显示文件的下载进度,通过改变其背景色,从左向右推进,直到填满整个Button时,意味着下载任务的完成。除了这种效果,还看到某酷的视频客户端,
2022-06-06

云服务器怎么远程控制手机屏幕显示器

如果您想远程控制电脑屏幕显示器并在屏幕上显示您的内容,您可以使用以下方法:在手机上安装一个软件,可以使用应用程序控制器。应用程序控制器通常允许您通过应用程序控制手机上的应用程序并在屏幕上显示内容。您可以在控制器中输入应用程序地址或在应用程序中输入应用程序名称(如微信、淘宝等)。下载并安装屏幕截图应用程序。该应用程序可以将您的屏幕截图并显示在控制器中。使用应用程序控制器在电脑上安装相机应用程序,然后打开相...
2023-10-27

云服务器怎么远程控制电脑屏幕显示器

远程控制电脑屏幕显示器需要在浏览器中输入控制命令,以下是一些常用的远程控制命令的示例:Ctrl+Home和Ctrl+Caps+Home是两个常用的远程控制命令,它们可以在本地电脑和云服务器上使用。Ctrl+Esc+Enter或Ctrl+F1+Enter是另一个常用的远程控制命令,它可以在同一台电脑上使用两次。Ctrl+D+Shift+Enter是另一种常用的远程控制命令,它可以使用鼠标右键来快速选择要控制的设备。Ctrl+W+F4是另一个常用的远程控制命令,它可...
2023-10-27

android实现双日期选择控件(可隐藏日,只显示年月)

在安卓开发中,会碰到选开始日期和结束日期的问题。特别是在使用Pad时,如果弹出一个Dialog,能够同时选择开始日期和结束日期,那将是极好的。我在开发中在DatePickerDialog的基础上做了修改,实现了这种Dialog。效果如下:具
2022-06-06

Nodejs爬虫进阶教程之异步并发控制

之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回答才会再加载一部分,所以说如果直接发送一个问题的请求链接,取得的页面是不完整的。
2022-06-04

腾讯云服务器怎样使用手机控制屏幕显示

腾讯云服务器是一种提供在线计算服务的云平台,可以通过手机控制屏幕显示。下面是使用腾讯云服务器控制屏幕显示的方法:下载并安装TencentEye应用程序。打开TencentEye应用程序,在首页上单击“屏幕截图”按钮,在下拉菜单中选择“屏幕截屏”选项。点击“屏幕截图”按钮,然后在弹出的窗口中选择要显示的截图。在截图窗口中,将您的手机放在桌面上,然后在截图区域中右键单击要截取的图像,选择“屏幕截图”。在弹出的窗口中
2023-10-27

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录