Android(安卓)soft (virtual) keyboard listener
Unfortunately, android api doesn't provide you with the specific tools to listen for a moment, when soft keyboard gets shown, or hidden. But there is a way (dirty hack) to assume that the keyboards state was changed. We can guess it by listening measure changes in layout. To do it, first, we need to make our layout to resize and scale instaed of scroll. Add android:windowSoftInputMode="adjustResize" parameter to your activity in manifest.xml. This way, when soft keyboard is called, content will be resized instead of scrolled.
Next step is to actually listen for this resizing. And again, there is a catch. There is no such thing as OnMeasureChangedListener , so the only way is to extend the container layout and do it inside. As an example I extended LinearLayout, and this is what I've got:
publicclassMyLayoutextendsLinearLayout{
publicMyLayout(finalContextcontext,finalAttributeSetattrs){
super(context,attrs);
}
publicMyLayout(Contextcontext){
super(context);
}
privateOnSoftKeyboardListeneronSoftKeyboardListener;
@Override
protectedvoidonMeasure(finalintwidthMeasureSpec,finalintheightMeasureSpec){
if(onSoftKeyboardListener!=null){
finalintnewSpec=MeasureSpec.getSize(heightMeasureSpec);
finalintoldSpec=getMeasuredHeight();
// If layout became smaller, that means something forced it to resize. Probably soft keyboard :)
if(oldSpec>newSpec){
onSoftKeyboardListener.onShown();
}else{
onSoftKeyboardListener.onHidden();
}
}
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
publicfinalvoidsetOnSoftKeyboardListener(finalOnSoftKeyboardListenerlistener){
this.onSoftKeyboardListener=listener;
}
// Simplest possible listener :)
publicinterfaceOnSoftKeyboardListener{
publicvoidonShown();
publicvoidonHidden();
}
}
That's about it. Of course you need to use your layout (MyLayout) in your code/xml for it to work. And example from activity:
((MyLayout)findViewById(R.id.layout)).setOnSoftKeyboardListener(newOnSoftKeyboardListener(){
@Override
publicvoidonShown(){
// Do something here
}
@Override
publicvoidonHidden(){
// Do something here
}
});
P.S. It works pretty well as it is. But you should check it for different situations. For example screen rotations, or other possible changes in the layout, that might trigger resize of any sort.
=======================================================文二=====================================================
There might be better approaches, but a possibility is to add:android:configChanges="keyboardHidden"
to the manifest. That will fire with any keyboard changes, so the you will need to query theConfiguration
object
static Configuration prevConf = Configuration(); static int ignoreMasks = Configuration.HARDKEYBOARDHIDDEN_NO|Configuration.HARDKEYBOARDHIDDEN_YES; onCreate() { prevConf = setToDefaults(); } // all your code here @Override public void onConfigurationChanged (Configuration newConfig) { int deltas = newConfig.diff (prevConf); // what changed? prevConf = newConfig; if (delta & ignoreMasks) return; // you're not interested in hard keyboards. // your code here }
I suck at bitwise operators, so you might need to work around that.
This is the API documentation:
http://developer.android.com/reference/android/R.attr.html#configChanges
http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged%28android.content.res.Configuration%29
http://developer.android.com/reference/android/content/res/Configuration.html
================================================文三============================================================== Since writing the below answer, someone clued me in to the existence ofViewTreeObserverand friends, APIs which have been lurking in the SDK since version 1. Rather than requiring a custom Layout type, a much simpler solution is to give your activity's root view a known ID, say '@+id/activityRoot', hook a GlobalLayoutListener into the ViewTreeObserver, and from there calculate the size diff between your activity's view root and the window size: Easy! ORIGINAL ANSWER Yes it's possible, but it's far harder than it ought to be. If I need to care about when the keyboard appears and disappears (which is quite often) then what I do is customize my top-level layout class into one which overrides Then in your Activity class... | |||||||||||||||||||||
|
更多相关文章
- 代码中设置drawableleft
- android 3.0 隐藏 系统标题栏
- Android开发中activity切换动画的实现
- Android(安卓)学习 笔记_05. 文件下载
- Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
- 技术博客汇总
- android 2.3 wifi (一)
- AndRoid Notification的清空和修改
- Android中的Chronometer