android获取键盘状态
① 如何检查Android中的软件键盘的可见性
在Android开发中,经常会有一个需求,做完某项操作后,隐藏键盘,也即让Android中的软键盘不显示。今天,和大家分享如何利用代码来实现对Android的软件盘的隐藏、显示的操作。
1、方法一(如果输入法在窗口上已经显示,则隐藏,反之则显示)
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
2、方法二(view为接受软键盘输入的视图,SHOW_FORCED表示强制显示)
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view,InputMethodManager.SHOW_FORCED);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0); //强制隐藏键盘
3、调用隐藏系统默认的输入法
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow
4、获取输入法打开的状态
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen=imm.isActive();//isOpen若返回true,则表示输入法打开
② Android键盘处理-监听键盘状态并实现QQ拉出式弹出回复框。
** 本文将一步一步讲解实现上述三种设计 **
获取键盘显示状态的原理是:首先利用getRootView().getHeight() 获取屏幕高度,在利用getWindowVisibleDisplayFrame 获取应用显示区域,但是这个区域不包含虚拟按键的区域(虚拟键盘、手机底部虚拟按键),我们根据前者与后者之差与状态栏高度的比较来判断键盘的显示与隐藏状态。
** 需要特别指出的是,在某些手机上,比如华为mate8,底部会出现一个可以随时隐藏与显示的一行虚拟按键(Android杂乱生态的无奈🙂),所以我们要定义一个最小键盘高度。 **
这样根据ShowKeyboard值的变化 就能判断键盘的显示与隐藏了。
这里利用的就是焦点,点击其他区域,键盘会失去焦点,这个时候我们可以强制隐藏键盘,因为EditText 焦点已经缺失,某些隐藏键盘的方法可能失效。
这里主要实现方法是监听用户手势,同时判断键盘状态,判断webView是否滑动到底部了。
注意手势监听,不要遗忘以下操作:
最后看一下实现的效果图:
③ 如何获取android的软键盘的显示状态
最近项目中有一个编辑框,下面是个ListView。在触发编辑框弹出软键盘后,ListView还能滑动,并且ListView的item还能响应单击。这样的体验效果很不好。于是便想在滑动或单击item时判断键盘是否弹出,若弹出,则把它隐藏。
网上一搜,发现Android并没有直接提供软键盘的弹出与隐藏判断,一些解决方案诸如判断父控件的高度或者判断
12
if(getWindow().getAttributes().softInputMode==WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) 隐藏键盘;
的方法并没有用,于是便从官方文档着手。
发现InputMethodManager有一个方法isActive(View view):如果view是输入法的活动view,则返回true。也就是说,如果是由view触发弹出软键盘,则返回true。哇,那问题就好办了
12
if(isActive(edittext)) 隐藏键盘
接着让另一个view强制获取焦点,这样isActivite(ediitext)就为false.
这个方法比较简单,代码比较短,也很好理解,希望能够帮助有需要的人,也不枉费我调试几个小时的功夫。
附上代码:
12345678
InputMethodManager inputMethodManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);<br>private boolean hideKeyboard(){ if(inputMethodManager.isActive(searchEditText)){<br>//因为是在fragment下,所以用了getView()获取view,也可以用findViewById()来获取父控件 getView().requestFocus();//使其它view获取焦点.这里因为是在fragment下,所以便用了getView(),可以指定任意其它view inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); return true; } return false; }
ps:如果是手动弹出键盘,getActivity().getCurrentFocus()改成searchEditText.并且手动弹出的键盘isActivie()失效,可用标记来判断.
④ 如何捕获android系统按键事件
下面是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())+"
";
msg +="按键代码:" + String.valueOf(keyCode)+"
";
msg +="按键字符:" + (char)unicodeChar+"
";
msg +="UNICODE:" + String.valueOf(unicodeChar)+"
";
msg +="重复次数:"+ String.valueOf(keyEvent.getRepeatCount())+"
";
msg +="功能键状态:" + String.valueOf(metaState)+"
";
msg +="硬件编码:" + String.valueOf(keyEvent.getScanCode())+"
";
msg +="按键标志:" + String.valueOf(keyEvent.getFlags())+"
";
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行获取了按键事件的标志符。
⑤ android 检测是否有键盘
Android 检测是否有键盘,主要根据根View的位置是不会变化的,假如发生了变化,那么就可能是键盘弹起了,所以我们通过判断他的位置变化去判断键盘是否弹起。如下代码进行检测:
java">finalintheigh=getWindowManager().getDefaultDisplay().getHeight()/3;
root.addOnLayoutChangeListener(newView.OnLayoutChangeListener(){
@Override
publicvoidonLayoutChange(Viewv,intleft,inttop,intright,intbottom,intoldLeft,intoldTop,intoldRight,intoldBottom){
//弹起事件
if(bottom!=0&&oldBottom!=0&&oldBottom-bottom>heigh){
if(mListView.getLastVisiblePosition()!=mDateArrays.size()-1){
mListView.smoothScrollToPosition(mDateArrays.size()-1);
}
}
elseif(oldBottom!=0&&bottom!=0&&(bottom-oldBottom>keyHeight)){
Toast.makeText(MainActivity.this,"监听到软件盘关闭...",Toast.LENGTH_SHORT).show();}
}
});
⑥ 如何在Android中判断软键盘是否弹出或隐藏
Android是一个针对触摸屏专门设计的操作系统,当点击编辑框,系统自动为用户弹出软键盘,以便用户进行输入。
那么,弹出软键盘后必然会造成原有布局高度的减少,那么系统应该如何来处理布局的减少?我们能否在应用程序中进行自定义的控制?这些是本文要讨论的重点。
一、软键盘显示的原理
软件盘的本质是什么?软键盘其实是一个Dialog!
InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统对活动主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示。
二、活动主窗口调整
android定义了一个属性,名字为windowSoftInputMode, 用它可以让程序可以控制活动主窗口调整的方式。我们可以在AndroidManifet.xml中对Activity进行设置。如:android:windowSoftInputMode="stateUnchanged|adjustPan"
该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。前一部分本文不做讨论,请读者自行查阅android文档。
模式一,压缩模式
windowSoftInputMode的值如果设置为adjustResize,那么该Activity主窗口总是被调整大小以便留出软键盘的空间。
我们通过一段代码来测试一下,当我们设置了该属性后,弹出输入法时,系统做了什么。
重写Layout布局:
public class ResizeLayout extends LinearLayout{
private static int count = 0;
public ResizeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.e("onSizeChanged " + count++, "=>onResize called! w="+w + ",h="+h+",oldw="+oldw+",oldh="+oldh);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t=" + t + ",r=" + r + ",b="+b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec=" + widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec);
}
AndroidManifest.xml的Activity设置属性:android:windowSoftInputMode = "adjustResize"
运行程序,点击文本框,查看调试信息:
E/onMeasure 6(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742024
E/onMeasure 7(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742025
E/onSizeChanged 8(7960): =>onSizeChanged called! w=320,h=201,oldw=320,oldh=377
E/onLayout 9(7960): =>OnLayout called! l=0, t=0,r=320,b=201
从调试结果我们可以看出,当我们点击文本框后,根布局调用了onMeasure,onSizeChanged和onLayout。
实际上,当设置为adjustResize后,软键盘弹出时,要对主窗口布局重新进行measure和layout,而在layout时,发现窗口的大小发生的变化,因此调用了onSizeChanged。
从下图的运行结果我们也可以看出,原本在下方的TextView被顶到了输入法的上方。
模式二,平移模式
windowSoftInputMode的值如果设置为adjustPan,那么该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
上面的例子中,我们将AndroidManifest.xml的属性进行更改:android: windowSoftInputMode = "adjustPan"
重新运行,并点击文本框,查看调试信息:
E/onMeasure 6(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742200
E/onMeasure 7(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742201
E/onLayout 8(8378): =>OnLayout called! l=0, t=0,r=320,b=377
我们看到:系统也重新进行了measrue和layout,但是我们发现,layout过程中onSizeChanged并没有调用,这说明输入法弹出前后并没有改变原有布局的大小。
从下图的运行结果我们可以看到,下方的TextView并没有被顶到输入法上方。
事实上,当输入框不会被遮挡时,该模式没有对布局进行调整,然而当输入框将要被遮挡时,窗口就会进行平移。也就是说,该模式始终是保持输入框为可见。如下图,整个窗口,包括标题栏均被上移,以保证文本框可见。
模式三 自动模式
当属性windowSoftInputMode被设置为adjustUspecified时,它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。
也就是说,系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动。
三、侦听软键盘的显示隐藏
有时候,借助系统本身的机制来实现主窗口的调整并非我们想要的结果,我们可能希望在软键盘显示隐藏的时候,手动的对布局进行修改,以便使软键盘弹出时更加美观。这时就需要对软键盘的显示隐藏进行侦听。
直接对软键盘的显示隐藏侦听的方法本人没有找到,如果哪位找到的方法请务必告诉本人一声。还有本方法针对压缩模式,平移模式不一定有效。
我们可以借助软键盘显示和隐藏时,对主窗口进行了重新布局这个特性来进行侦听。如果我们设置的模式为压缩模式,那么我们可以对布局的onSizeChanged函数进行跟踪,如果为平移模式,那么该函数可能不会被调用。
我们可以重写根布局,因为根布局的高度一般情况下是不发生变化的。
假设跟布局为线性布局,模式为压缩模式,我们写一个例子,当输入法弹出时隐藏某个view,输入法隐藏时显示某个view。
⑦ Android 手机软键盘的弹起和关闭的监听
在很多Android App 开发的过程中,需要对Activity 中 软键盘的弹起和关闭进项监听,但是Andoid中并没有提供相对应的api进行监听, 我有一个简单的方法。
首先需要知道一些基础知识
在manifest文件中可以设置Activity的android:windowSoftInputMode属性,这个属性值常见的设置如下:android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
那么这里值的含义列表如下:
1、stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
2、stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
3、stateHidden:用户选择activity时,软键盘总是被隐藏
4、stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
5、stateVisible:软键盘通常是可见的
6、stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
7、adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
8、adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
9、adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分
案例:
1.我们需要将监听所在的Activity在Manifest文件中的设置为如下形式:
<activity
android:name="com.zy.project.MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN/>
<category android:name="android.intent.category.LAUNCHER/>
</intent-filter>
</activity>
当有软键盘弹起时,Activity的布局大小会被滚动上去,但是你仍然可以通过滑动浏览所有。
2 需要在外层布局文件设置一个id,并在activity 中设置监听
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnLayoutChangeListener{
//Activity最外层的Layout视图
private View rootView;
//屏幕高度
private int screenHeight = 0;
//软件盘弹起后所占高度阀值 一般是占用屏幕的1/3
private int keyHeight = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootView = findViewById(R.id.root_layout);
//获取屏幕高度
screenHeight = this.getWindowManager().getDefaultDisplay().getHeight();
//阀值设置为屏幕高度的1/3
keyHeight = screenHeight/3;
}
@Override
protected void onResume() {
super.onResume();
//添加layout大小发生改变监听器
rootView.addOnLayoutChangeListener(this);
}
@Override
public void onLayoutChange(View v, int left, int top, int right,int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
//old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值
// System.out.println(oldLeft + " " + oldTop +" " + oldRight + " " + oldBottom);
// System.out.println(left + " " + top +" " + right + " " + bottom);
//现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起
if(oldBottom != 0 && bottom != 0 &&(oldBottom - bottom > keyHeight)){
Toast.makeText(MainActivity.this, "监听到软键盘弹起...", Toast.LENGTH_SHORT).show();
}else if(oldBottom != 0 && bottom != 0 &&(bottom - oldBottom > keyHeight)){
Toast.makeText(MainActivity.this, "监听到软件盘关闭...", Toast.LENGTH_SHORT).show();
}
}
本文来自:http://m.blog.csdn.net/bear_huangzhen/article/details/45896333