android 软件盘未弹出如何获取高度,Android 软键盘的那些坑,一招搞定!
3
软键盘高度获取
对于上面的问题1,既然想要EditText单独顶上去,那么就需要知道当前键盘弹出的高度,再设置EditText坐标即可。
问题的关键转变为如何获取键盘的高度。
Activity窗口的构成
通常来说,手机由状态栏、内容区域、导航栏组成。
一般情况下(除去导航栏隐藏,状态栏沉浸)对于我们来说,写的布局文件都会展示在内容区域,这部分是"能看到的"。
当键盘弹出的时候,会遮盖部分内容区域:
因此,需要将被遮住的部分往上移动,移动多少呢?
通过调用方法:
#View.java
publicvoidgetWindowVisibleDisplayFrame( Rect outRect){
...
}
可见区域的位置记录在outRect里,而整个屏幕高度是已知的,因此就可以计算出被遮挡的区域需要顶上去的偏移量。
一个通用的计算方式
根据上面的分析,将计算方法封装一下:
publicclassSoftInputUtil{
privateintsoftInputHeight = 0;
privatebooleansoftInputHeightChanged = false;
privatebooleanisNavigationBarShow = false;
privateintnavigationHeight = 0;
privateView anyView;
privateISoftInputChanged listener;
privatebooleanisSoftInputShowing = false;
publicinterfaceISoftInputChanged{
voidonChanged( booleanisSoftInputShow, intsoftInputHeight, intviewOffset);
}
publicvoidattachSoftInput( finalView anyView, finalISoftInputChanged listener){
if(anyView == null|| listener == null)
return;
//根View
finalView rootView = anyView.getRootView;
if(rootView == null)
return;
navigationHeight = getNavigationBarHeight(anyView.getContext);
//anyView为需要调整高度的View,理论上来说可以是任意的View
this.anyView = anyView;
this.listener = listener;
rootView.addOnLayoutChangeListener( newView.OnLayoutChangeListener {
@Override
publicvoidonLayoutChange(View v, intleft, inttop, intright, intbottom, intoldLeft, intoldTop, intoldRight, intoldBottom){
//对于Activity来说,该高度即为屏幕高度
introotHeight = rootView.getHeight;
Rect rect = newRect;
//获取当前可见部分,默认可见部分是除了状态栏和导航栏剩下的部分
rootView.getWindowVisibleDisplayFrame(rect);
if(rootHeight - rect.bottom == navigationHeight) {
//如果可见部分底部与屏幕底部刚好相差导航栏的高度,则认为有导航栏
isNavigationBarShow = true;
} elseif(rootHeight - rect.bottom == 0) {
//如果可见部分底部与屏幕底部平齐,说明没有导航栏
isNavigationBarShow = false;
}
//cal softInput height
booleanisSoftInputShow = false;
intsoftInputHeight = 0;
//如果有导航栏,则要去除导航栏的高度
intmutableHeight = isNavigationBarShow == true? navigationHeight : 0;
if(rootHeight - mutableHeight > rect.bottom) {
//除去导航栏高度后,可见区域仍然小于屏幕高度,则说明键盘弹起了
isSoftInputShow = true;
//键盘高度
softInputHeight = rootHeight - mutableHeight - rect.bottom;
if(SoftInputUtils. this.softInputHeight != softInputHeight) {
softInputHeightChanged = true;
SoftInputUtils. this.softInputHeight = softInputHeight;
} else{
softInputHeightChanged = false;
}
}
//获取目标View的位置坐标
int[] location = newint[ 2];
anyView.getLocationOnScreen(location);
//条件1减少不必要的回调,只关心前后发生变化的
//条件2针对软键盘切换手写、拼音键等键盘高度发生变化
if(isSoftInputShowing != isSoftInputShow || (isSoftInputShow && softInputHeightChanged)) {
if(listener != null) {
//第三个参数为该View需要调整的偏移量
//此处的坐标都是相对屏幕左上角(0,0)为基准的
listener.onChanged(isSoftInputShow, softInputHeight, location[ 1] + anyView.getHeight - rect.bottom);
}
isSoftInputShowing = isSoftInputShow;
}
}
});
}
//***************STATIC METHOD******************
publicstaticintgetNavigationBarHeight(Context context){
if(context == null)
return0;
Resources resources = context.getResources;
intresourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "android");
intheight = resources.getDimensionPixelSize(resourceId);
returnheight;
}
publicstaticvoidshowSoftInput(View view){
if(view == null)
return;
InputMethodManager inputMethodManager = (InputMethodManager)view.getContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if(inputMethodManager != null) {
inputMethodManager.showSoftInput(view, 0);
}
}
publicstaticvoidhideSoftInput(View view){
if(view == null)
return;
InputMethodManager inputMethodManager = (InputMethodManager)view.getContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if(inputMethodManager != null) {
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken, 0);
}
}
}
使用方式如下:
在 Activity里加如下代码:
privatevoidattachView{
//editText2为需要调整的View
editText2 = findViewById(R.id.et2);
SoftInputUtil softInputUtil = newSoftInputUtil;
softInputUtil.attachSoftInput(editText2, newSoftInputUtil.ISoftInputChanged {
@Override
publicvoidonChanged( booleanisSoftInputShow, intsoftInputHeight, intviewOffset){
if(isSoftInputShow) {
editText2.setTranslationY(et2.getTranslationY - viewOffset);
} else{
editText2.setTranslationY( 0);
}
}
});
}
并且将windowSoftInputMode设置为SOFT_INPUT_ADJUST_RESIZE。
android:windowSoftInputMode= "adjustResize|stateAlwaysHidden"
stateAlwaysHidden为默认不显示键盘。
再来看Activity的布局文件:
< LinearLayoutxmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:tools= "http://schemas.android.com/tools"
android:id= "@+id/myviewgroup"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical"
android:layout_gravity= "center_vertical"
tools:context= ".MainActivity">
< ImageView
android:id= "@+id/iv"
android:src= "@drawable/test"
android:background= "@color/colorGreen"
android:layout_marginTop= "20dp"
android:layout_marginBottom= "20dp"
android:layout_width= "match_parent"
android:layout_height= "300dp">
ImageView>
< EditText
android:hint= "输入框2"
android:id= "@+id/et2"
android:layout_marginTop= "100dp"
android:background= "@drawable/bg"
android:layout_gravity= "bottom"
android:layout_marginHorizontal= "10dp"
android:layout_width= "match_parent"
android:layout_height= "40dp">
EditText>
LinearLayout>
最终效果如下:
可以看出,EditText被顶上去了,其它布局没有变化。在动态切换导航栏是否展示之间EeditText也能正常显示。
这就回答了上面的问题1:当键盘弹出时,只想EditText顶上去,ImageView保持不动。
当然对于问题1的还有其它更简单的解决方式,在下一篇会分析。
以上是关于软键盘弹出、关闭、是否展示、软键盘高度、软键盘模式等效果的解析。
你可能还有如下疑惑:
SOFT_INPUT_ADJUST_PAN为什么能够将布局顶上去?
SOFT_INPUT_ADJUST_RESIZE为什么能够重新设置布局区域?
SOFT_INPUT_ADJUST_UNSPECIFIED内部逻辑如何判断?
键盘弹起为什么会执行 onLayout?
...
由于篇幅所限,这些问题将在后续推送:Android 软键盘一招搞定(原理篇)分析。
本文基于 Android 10.0。
如果您有需求,请直接拷贝文章里的SoftInputUtil.java 尝试控制键盘。若有问题,请留言,谢谢!返回搜狐,查看更多
android 软件盘未弹出如何获取高度,Android 软键盘的那些坑,一招搞定!相关推荐
- python监控桌面捕捉_想要远程获取对方的桌面?Python教你一招搞定!
申明 本文章仅供学习使用 先说一下功能的实现方式: 让对方的电脑自动截图,并且通过邮件的方式发给指定邮箱 再说一下需要的包:需要下载pyautogui以及email包,下载方式为在cmd命令行下输入p ...
- android终端模拟器黑屏,BlueStacks 蓝叠模拟器常见问题汇总,教你如何一招搞定
说到现在比较流行的安卓模拟器,BlueStacks 绝对是榜上有名,它的出现让广大玩家可以在电脑中成功体验各种手游.即使如此好用的模拟器,也存在着很多问题,让很多玩家为此头疼不已.今天小编整理了一些关 ...
- Android 软件盘弹出点击空白处键盘消失的方案
Android 软件盘弹出点击空白处键盘消失的方法,代码如下: public void HideInput() {if (null != this.getCurrentFocus()) {/*** 点 ...
- android 输入法更换_一种动态切换Android系统输入法的弹出模式的方法与流程
本发明涉及一种Android系统利用动态切换输入法的弹出模式解决输入法跳闪抖动问题的方法,属于安卓系统技术领域. 背景技术: 随着Android系统的快速发展以及安卓手机的不断普及,基于Android ...
- WindowManager解析(二)Android悬浮框无法弹出输入法的原因和无需权限显示悬浮窗
Android悬浮框无法弹出输入法 最近要研究悬浮窗方面的东西,遇到一个问题,我的悬浮窗里面有一个输入框,但是不弹出输入法,后来找到一个方法: 在WindowManager的实例获取方式不对,之前是这 ...
- android系统动态切换输入法,一种动态切换Android系统输入法的弹出模式的方法与流程...
技术特征: 1.一种动态切换Android系统输入法的弹出模式的方法,其特征在于,包括步骤如下: (1)初始状态下,即软键盘和表情面板都未展开时,为表情面板设置一个默认高度,默认高度的取值范围是230 ...
- android自动切换输入法,一种动态切换Android系统输入法的弹出模式的方法
主权项: 1.一种动态切换Android系统输入法的弹出模式的方法,其特征在于,包括步骤如下:(1)初始状态下,即软键盘和表情面板都未展开时,为表情面板设置一个默认高度,默认高度的取值范围是230dp ...
- U盘无法弹出怎么办直接拔了数据丢失怎么恢复
U盘在准备拔出时,提示"无法停止通用卷设备",如果直接拔走U盘,很可能会导致U盘里面的数据发生破坏.那么,U盘无法弹出怎么办?教你三招. 1.清空剪切板,在电脑上随便复制一个文件, ...
- 关于U盘无法弹出的几种解决方法
U盘无法弹出的N种解决方法 [转自PChome.net] 大家是不是经常遇见"现在无法停止'通用卷'设备.请稍候再停止该设备."的问题?经常插上u盘,mp3,移动硬盘等设备,想要安 ...
最新文章
- 手把手教你使用Gene6FTP远程管理
- Heinz College of Information Systems and Public Policy Carnegie Mellon University
- eclipse远程连接hadoop_1个文件,3个类,mapreduce就是这么简单,动手搭建Hadoop(8)...
- 2017\National _C_C++_C\1.哥德巴赫分解
- 如何安装MiniGUI 3.0在Linux PC
- 关于计算机英语阅读,一篇摘选的关于计算机的英语阅读材料,对大家的英语也许会有提高!...
- 天猫研发Java团队(4面全题目):并发压测+Mina+事务+集群+秒杀架构
- android选择本地图片并裁剪
- c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)
- JAVA 微信支付 native方式
- SQLsever --数据库置疑
- 华为鸿蒙主题设计,2020华为全球主题设计大赛,简直就是神仙打架啊!
- cad填充图案乱理石_cad采矿制图时遇到问题的完美解决方法
- PDM系统与PLM系统
- 【NRF51822】DFU过程梳理
- SpringBoot 实战:加载和读取资源文件
- matlab读取TXT文件数据,二进制文件数据
- PostgreSQL中uuid的使用,uuid_generate_v4()
- Windows Setup could not set the display language
- 北大暑期学校学习总结