如何捕获android系统按键事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何捕获android系统按键事件相关的知识,希望对你有一定的参考价值。
参考技术A下面是android学习手册中关于按键的介绍,例子,文档、源码都可以看,360手机助手中下载
在Android系统中,存在多种界面事件,如点击事件、触摸事件、焦点事件和菜单事件等,在这些界面事件发生时,Android界面框架调用界面控件的事件处理方法对事件进行处理。
Android系统界面事件的传递和处理遵循以下规则。
·如果界面控件设置了事件监听器,则事件将先传递给事件监听器。
·如果界面控件没有设置事件监听器,界面事件则会直接传递给界面控件的其他事件处理方法。
·即使界面控件设置了事件监听器,界面事件也可以再次传递给其他事件处理方法。
·是否继续传递事件给其他处理方法是由事件监听器处理方法的返回值决定的。
·如果监听器处理方法的返回值为true,表示该事件已经完成处理过程,不需要其他处理方法参与处理过程,这样事件就不会再继续进行传递。
·如果监听器处理方法的返回值为false,则表示该事件没有完成处理过程,或需要其他处理方法捕获到该事件,事件会被传递给其他的事件处理方法。
在MVC模型中,控制器根据界面事件(UI Event)类型不同,将事件传递给界面控件不同的事件处理方法。
·按键事件(KeyEvent)将传递给onKey()方法进行处理。
·触摸事件(TouchEvent)将传递给onTouch()方法进行处理。
下面以EditText控件中的按键事件为例,说明Android系统界面事件传递和处理过程。
假设EditText控件已经设置了按键事件监听器,当用户按下键盘上的某个按键时,控制器将产生KeyEvent按键事件。Android系统会首先判断EditText控件是否设置了按键事件监听器,因为EditText控件已经设置按键事件监听器OnKeyListener,所以按键事件先传递到监听器的事件处理方法onKey()中,事件能够继续传递给EditText控件的其他事件处理方法,完全根据onKey()方法的返回值来确定:如果onKey()方法返回false,事件将继续传递,这样EditText控件就可以捕获到该事件,将按键的内容显示在EditText控件中;如果onKey()方法返回true,将阻止按键事件的继续传递,这样EditText控件就不能够捕获到按键事件,也就不能够将按键内容显示在EditText控件中。
Android界面框架支持对按键事件的监听,并能够将按键事件的详细信息传递给处理方法。为了处理控件的按键事件,先需要设置按键事件的监听器,并重载onKey()方法,示例代码如代码清单1所示。
代码清单1 设置按键事件的监听器,并重载onKey()方法
entryText.setOnKeyListener(new OnKeyListener()
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent)
//过程代码……
return true/false;
第1行代码是设置控件的按键事件监听器。
第3行代码的onKey ()方法中的参数:第1个参数View表示产生按键事件的界面控件;第2个参数keyCode表示按键代码;第3个参数KeyEvent则包含了事件的详细信息,如按键的重复次数、硬件编码和按键标志等。
第5行代码是onKey()方法的返回值:返回true,阻止事件传递;返回false,允许继续传递按键事件。
KeyEventDemo是一个说明如何处理按键事件的示例。
KeyEventDemo用户界面如图1所示。
图1 KeyEventDemo用户界面
从图5-27中可以看出,最上方的EditText控件是输入字符的区域,中间的CheckBox控件用来控制onKey()方法的返回值,最下方的TextView控件用来显示按键事件的详细信息,包括按键动作、按键代码、按键字符、UNICODE编码、重复次数、功能键状态、硬件编码和按键标志。
界面的XML文件的代码如代码清单2所示
代码清单2 界面XML文件
<EditText android:id="@+id/entry"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
<CheckBox android:id="@+id/block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="返回true,阻止将按键事件传递给界面元素" >
</CheckBox>
<TextView android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按键事件信息" >
</TextView>
在EditText中,当任何一个键按下或抬起时,都会引发按键事件。为了能够使EditText处理按键事件,需要使用setOnKeyListener ()方法在代码中设置按键事件监听器,并在onKey()方法中添加按键事件的处理过程,代码如代码清单3所示。
代码清单3 setOnKeyListener()
entryText.setOnKeyListener(new OnKeyListener()
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent)
int metaState = keyEvent.getMetaState();
int unicodeChar = keyEvent.getUnicodeChar();
String msg = "";
msg +="按键动作:" + String.valueOf(keyEvent.getAction())+"\\n";
msg +="按键代码:" + String.valueOf(keyCode)+"\\n";
msg +="按键字符:" + (char)unicodeChar+"\\n";
msg +="UNICODE:" + String.valueOf(unicodeChar)+"\\n";
msg +="重复次数:"+ String.valueOf(keyEvent.getRepeatCount())+"\\n";
msg +="功能键状态:" + String.valueOf(metaState)+"\\n";
msg +="硬件编码:" + String.valueOf(keyEvent.getScanCode())+"\\n";
msg +="按键标志:" + String.valueOf(keyEvent.getFlags())+"\\n";
labelView.setText(msg);
if (checkBox.isChecked())
return true;
else
return false;
在上述代码中,第4行代码用来获取功能键状态。功能键包括左Alt键、右Alt键和Shift键,当这3个功能键被按下时,功能键代码metaState值分别为18、34和65;但没有功能键被按下时,功能键代码metaState值分别为0。
第5行代码获取了按键的Unicode值,而在第9行中,将Unicode转换为了字符,显示在TextView中。
第7行代码获取了按键动作,0表示按下按键,1表示抬起按键。第7行代码获取按键的重复次数,但当按键被长时间按下时,则会产生这个属性值。
第13行代码获取了按键的硬件编码,各硬件设备的按键硬件编码都不相同,因此该值一般用于调试。
第14行获取了按键事件的标志符。
捕获 DIV 元素上的按键(或 keydown)事件
【中文标题】捕获 DIV 元素上的按键(或 keydown)事件【英文标题】:Capture key press (or keydown) event on DIV element 【发布时间】:2011-03-10 03:02:34 【问题描述】:如何捕获 DIV 元素上的按键或按下事件(使用 jQuery)?
赋予 DIV 元素焦点需要什么?
【问题讨论】:
div 的“焦点”是什么意思? jboyd 有tabindex 时,除了tab 到它,你可以用javascript 找到它并调用它的focus 方法。 @Lalchand ...你能接受我的回答吗? :) 【参考方案1】:(1)设置tabindex
属性:
<div id="mydiv" tabindex="0" />
(2) 绑定到keydown:
$('#mydiv').on('keydown', function(event)
//console.log(event.keyCode);
switch(event.keyCode)
//....your actions for the keys .....
);
将焦点设置在开始:
$(function()
$('#mydiv').focus();
);
要删除 - 如果您不喜欢 - div
焦点边框,请在 CSS 中设置 outline: none
。
查看keycodes 的表格了解更多keyCode
的可能性。
所有代码都假设你使用 jQuery。
#【讨论】:
+1 tabindex 是使 div '可选择'的关键点。 JQuery 不是必需的,同样的事情适用于 Angular 以及(我想)纯 javascript 事件。 浏览器对此的支持是什么? tabindex 是关键部分,但不要设置为“0”以外的任何值。将其设置为高于 0 的值会扰乱视障用户的屏幕阅读器(它将跳过页面上的所有内容并直接转到任何高于 0 的 tabindex)。 tabindex="0" 使其成为“可选项卡”。你可以有无限的元素 tabindex="0" 也适用于!太棒了!我错过了 tabindex 属性,可能是因为 DIV 无法获得焦点,除非它们有 tabindex。谢啦!救了我的命!编辑:也适用于 React【参考方案2】:
tabindex HTML 属性指示其元素是否可以聚焦,以及是否/在哪里参与顺序键盘导航(通常使用Tab
键)。阅读MDN Web Docs 以获得完整参考。
使用 Jquery
$( "#division" ).keydown(function(evt)
evt = evt || window.event;
console.log("keydown: " + evt.keyCode);
);
#division
width: 90px;
height: 30px;
background: lightgrey;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="division" tabindex="0"></div>
使用 JavaScript
var el = document.getElementById("division");
el.onkeydown = function(evt)
evt = evt || window.event;
console.log("keydown: " + evt.keyCode);
;
#division
width: 90px;
height: 30px;
background: lightgrey;
<div id="division" tabindex="0"></div>
【讨论】:
我实际上是在寻找当 div 上的控件失去焦点时触发 focusout 事件的问题,例如单击 div 滚动条,只需将制表位添加到 div 即可解决,所以谢谢你这么多【参考方案3】:这里是纯 JS 的示例:
document.querySelector('#myDiv').addEventListener('keyup', function (e)
console.log(e.key)
)
#myDiv
outline: none;
<div
id="myDiv"
tabindex="0"
>
Press me and start typing
</div>
【讨论】:
以上是关于如何捕获android系统按键事件的主要内容,如果未能解决你的问题,请参考以下文章