Android 软键盘汇总
来源:互联网 发布:销售订单软件 编辑:程序博客网 时间:2024/06/05 17:35
首先扯点别的:我想问一下,如果一个你喜欢的女生如果把你当弟兄们对待,是什么意思?意思是只能做朋友?
今天记录一下如何监听软键盘的弹出和退出。
监听软键盘的弹起
直接上代码
public class MainActivity extends AppCompatActivity implements ViewTreeObserver.OnGlobalLayoutListener { private static final String TAG = "MainActivity"; private View activityRootView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); activityRootView = getWindow().getDecorView().findViewById(android.R.id.content); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { if (isKeyboardShown(activityRootView)) { Log.e(TAG, "软键盘弹起"); } else { Log.e(TAG, "软键盘关闭"); } } private boolean isKeyboardShown(View rootView) { DisplayMetrics dm = rootView.getResources().getDisplayMetrics(); //设定一个认为是软键盘弹起的阈值 final int softKeyboardHeight = 100*dm.density; //得到屏幕可见区域的大小 Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); //rootView 的bottom和当前屏幕可见区域(包括状态栏)bottom的差值 int heightDiff = rootView.getBottom() - r.bottom; return heightDiff > softKeyboardHeight; } @Override protected void onDestroy() { super.onDestroy(); activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this); }}
首先实现ViewTreeObserver.OnGlobalLayoutListener接口,重写onGlobalLayout方法,然后给activityRootView 注册监听addOnGlobalLayoutListener监听
activityRootView = getWindow().getDecorView().findViewById(android.R.id.content); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
然后在 isKeyboardShown方法中进行判断,我们设置软件盘弹起的阈值是100乘以当前设备的密度独立像素单位,比如我的手机,1dp=3px;
private boolean isKeyboardShown(View rootView) { DisplayMetrics dm = rootView.getResources().getDisplayMetrics(); //设定一个认为是软键盘弹起的阈值 final int softKeyboardHeight = 100*dm.density; //得到屏幕可见区域的大小 Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); //rootView 的bottom和当前屏幕可见区域bottom的差值 int heightDiff = rootView.getBottom() - r.bottom; return heightDiff > softKeyboardHeight; }
要记得在Activity的onDestroy取消注册OnGlobalLayoutListener
@Override protected void onDestroy() { super.onDestroy(); activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this); }
注意:上面这个方法有个问题。就是当我们在AndroidManifest.xml文件中给Activity指定软键盘的输入模式为adjustResize的时候,无法判断监听键盘弹起。
<activity android:name=".activity.TestActivity" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>
修改isKeyboardShown方法如下
private boolean isKeyboardShown(View rootView) { DisplayMetrics dm = rootView.getResources().getDisplayMetrics(); //设定一个认为是软键盘弹起的阈值 final int softKeyboardHeight = (int) (100 * dm.density); //得到屏幕可见区域的大小 Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); int heightDiff = dm.heightPixels - r.bottom; return heightDiff > softKeyboardHeight; }
注意现在高度差的计算方式,是使用手机屏幕的高度,减去当前可见区域的高度。
int heightDiff = dm.heightPixels - r.bottom;
我的手机屏幕高度是1920px,键盘弹起的时候可见区域高度是1118px,键盘关闭的时候可见区域的高度恢复到1920px。
监听软键盘的退出。
假设场景:我们屏幕中有一个EditText,用来输入价格,我们要根据输入的价格进行计算。实现方式可以这样。
editPrice.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { //在这里进行计算 } });
但是这种方式有一个缺点,就是每当输入的价格变化的时候就会进行一次价格计算。但是如果能够在软键盘关闭以后再进行价格计算会更好。这样就只会进行一次计算。实现如下。
首先自定义MyEditText
public class MyEditText extends EditText { private OnFinishComposingListener finishComposingListener; public void setFinishComposingListener(OnFinishComposingListener finishComposingListener) { this.finishComposingListener = finishComposingListener; } public MyEditText(Context context) { super(context); } public MyEditText(Context context, AttributeSet attrs) { super(context, attrs); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return new MyInputConnection(super.onCreateInputConnection(outAttrs),false); } /** 自定义一个输入法连接器 */ class MyInputConnection extends InputConnectionWrapper { public MyInputConnection(InputConnection target, boolean mutable) { super(target, mutable); } @Override public boolean finishComposingText() { //在这个方法里可以监听输入完成动作。 if (finishComposingListener != null) { finishComposingListener.finishComposing(); } return super.finishComposingText(); } } //定义一个接口,用来回调进行输入完成时的操作,比如计算价格。 interface OnFinishComposingListener { void finishComposing(); }}
使用,和普通的EditText一样在xml布局文件中使用就可以了。
public class MainActivity extends AppCompatActivity { private MyEditText editPrice; private static final String TAG = "MainActivity"; private TextView textResult; private boolean touchEditPrice; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editPrice = (MyEditText) findViewById(R.id.eidt_price); textResult = (TextView) findViewById(R.id.text_result); editPrice.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { touchEditPrice = true; return false; } }); editPrice.setFinishComposingListener(new MyEditText.OnFinishComposingListener() { @Override public void finishComposing() { if (touchEditPrice) { Log.e(TAG, "editPrice finishComposing: "); textResult.setText(editPrice.getText().toString()); touchEditPrice = false; } } }); }}
需要注意:因为在某些情况下,比如EditText失去焦点,Activity结束等finishComposingText()方法也会调用。所以我们加了一个boolean值touchEditPrice ,我们给editPrice设置touch监听事件,当editPrice被touch的时候touchEditPrice 设为true。然后在输入动作完成的时候如果touchEditPrice为true,我们就进行相应的操作,然后把touchEditPrice设为false。这样就能保证finishComposingText()方法中我们的操作只执行一次。
手动显示软键盘,隐藏软件盘
1 手动显示软键盘
InputMethodManager imm = (InputMethodManager) TestActivity.this.getSystemService(INPUT_METHOD_SERVICE);} imm.showSoftInput(editText, 0);
首先获取 InputMethodManager ,然后调用InputMethodManager 的showSoftInput方法。
showSoftInput(View view, int flags)
方法第一个参数view必须是一个EditText或者EditText的子类。view 必须可见,可以获得焦点并且当前焦点在view上。第二个参数flag随便不用纠结,直接传0就行。(如果想深入了解,可以参看文章结尾的链接3)。
2 手动隐藏软键盘。
InputMethodManager imm = (InputMethodManager) TestActivity.this.getSystemService(INPUT_METHOD_SERVICE);} imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
首先获取 InputMethodManager,然后调用InputMethodManager的hideSoftInputFromWindow方法。
hideSoftInputFromWindow(IBinder windowToken, int flags)
方法的第一个参数是一个view的windowToken,这个可以通过view的getWindowToken()方法获得。这个view可以使当前布局中任意一个控件,即使不可见都行。第二个参数不纠结,直接传0。
参考链接:
【1】http://toughcoder.net/blog/2015/10/09/android-trick-detect-soft-keyboard-show-slash-hide/
【2】http://blog.csdn.net/hmyang314/article/details/43019101
【3】http://blog.csdn.net/ccpat/article/details/46717573
- Android 软键盘汇总
- Android开发软键盘遮挡问题汇总
- 【android】监听编辑EditText时点击软键盘事件 + 隐藏软键盘 + keycode汇总
- Android 打开软键盘 关闭软键盘
- Android收起软键盘,隐藏软键盘
- android 软键盘模式
- Android 软键盘相关
- Android软键盘研究
- android 软键盘 InputMethodManager
- android 软键盘 InputMethodManager
- Android隐藏软键盘
- android 关闭软键盘
- android 软键盘 InputMethodManager
- android 软键盘监听
- android 关闭软键盘
- Android 软键盘 相关
- android 软键盘控制
- Android软键盘
- 关于 MySQL 你可能不知道的 SQL 使用技巧
- dlib, OpenFace and face_recognition
- epoll详解
- 题目1030:毕业bg
- CSU-1830 FarAway
- Android 软键盘汇总
- CSS---使用flex布局做响应式页面
- 解决AndroidStudio添加ProjectLibary后在编译时遇到的各种问题之解决方式索引(finished with non-zero exit value and so on...)
- 廖雪峰Python的研读笔记(二) 函数式编程
- C# 操作EXCEL文件
- Java实现全排列、组合算法
- Spring注入Date类型的数据到Bean中
- SpringMVC分布式架构
- Context#getResources().getDrawable()方法过时后的替代方法