android实现底部弹出框与软键盘冲突(全面屏虚拟键适配)
普通的底部弹出框大家都可以很熟练的使用了,无非是一个diaolog的事情,但是当dialog中含有输入框之后,软键盘与dialog的冲突可以说是十分坑了。。。更别说加上底部虚拟键了,这么一个小功能磨得我简直吐血。。。下面就是我的血泪史。
第一阶段:
首先是底部dialog与软键盘的冲突:
View myView = LayoutInflater.from(MainActivity.this).inflate(R.layout.pop,null);
myView.setPadding(0, 0, 0, 0);
Dialog dialog = new AlertDialog.Builder(MainActivity.this)
.setView(myView).create();
//设置点击Dialog外部任意区域关闭Dialog
dialog.setCanceledOnTouchOutside(true);
dialog.show();
Window window = dialog.getWindow();
win.getDecorView().setPadding(0, 0, 0, ScreenUtils.getNavigationBarHeight(this));
WindowManager.LayoutParams lp = win.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.BOTTOM;//设置对话框置底部显示
win.setAttributes(lp);
这时候dialog中的布局文件即R.layout.pop中含有edittext,每次我输入后想关闭软键盘,就顺手点击diaolog外部区域,这下好了。。。不仅软键盘关闭了,dialog也一起dimiss了。。。然后想着那就不让点击Dialog外部任意区域关闭Dialog生效呗,就把 dialog.setCanceledOnTouchOutside(true);这行代码注释掉,再运行,ok,我点即外部区域果然不会让dialog消失,但问题是软键盘也坚挺如初,毫不动摇,我手机自带的输入法当输入中文时候没有点击收起的小箭头。。。这下怎么搞。。。我想要点击外部diaolog不消失,只让软键盘消失啊!!!然后疯狂百度,得到解决方法如下:
不使用dialog而是使用dialogActivity,嘿嘿,这样软键盘总不会和dialog纠缠不清,同上同下了吧。
setContentView(R.layout.activity_main);
//设置窗口对齐屏幕宽度
Window win = this.getWindow();
win.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams lp = win.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.BOTTOM;//设置对话框置顶显示
win.setAttributes(lp);
//设置点击外部空白处可以关闭Activity,但我们不需要
//this.setFinishOnTouchOutside(true);
当前activity要继承自AppCompatActivity,然后重写
@Override public boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stub if(event.getAction() == MotionEvent.ACTION_DOWN){if(getCurrentFocus()!=null && getCurrentFocus().getWindowToken()!=null){InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); }}return super.onTouchEvent(event); }
这样,点击外部,就会让软键盘收起,且dialog不消失了(毕竟是activity了)
当然,要在表单中注册这个activity
<activity android:name=".MainActivity" android:theme="@style/Base.V7.Theme.AppCompat.Light.Dialog"></activity>
但是!!又双叒叕出问题了。。。activity撑不满屏宽啊,这肯定是样式问题了,我们看看这个dialog样式是怎样的吧
<style name="Base.V7.Theme.AppCompat.Light.Dialog" parent="Base.Theme.AppCompat.Light"> <item name="android:colorBackground">?attr/colorBackgroundFloating</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowFrame">@null</item> <item name="android:windowTitleStyle">@style/RtlOverlay.DialogWindowTitle.AppCompat</item> <item name="android:windowTitleBackgroundStyle">@style/Base.DialogWindowTitleBackground.AppCompat</item> <item name="android:windowBackground">@drawable/abc_dialog_material_background</item> <item name="android:windowIsFloating">true</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowAnimationStyle">@style/Animation.AppCompat.Dialog</item> <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item> <item name="windowActionBar">false</item> <item name="windowActionModeOverlay">true</item> <item name="listPreferredItemPaddingLeft">24dip</item> <item name="listPreferredItemPaddingRight">24dip</item> <item name="android:listDivider">@null</item> </style>
这么多属性啊。。。好烦啊,一个个试,是哪个属性影响了全屏,结果发现了这个妖艳贱货
<item name="android:windowBackground">@drawable/abc_dialog_material_background</item>
<style name="noTitleDialogActivity" parent="Base.Theme.AppCompat.Light"> <item name="android:colorBackground">?attr/colorBackgroundFloating</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowFrame">@null</item> <item name="android:windowTitleStyle">@style/RtlOverlay.DialogWindowTitle.AppCompat</item> <item name="android:windowTitleBackgroundStyle">@style/Base.DialogWindowTitleBackground.AppCompat</item>
<!--<item name="android:windowBackground">@drawable/abc_dialog_material_background</item>--> //这个布局会让activity无法占满屏幕
<item name= "android:windowIsFloating" >true </item> <item name= "android:backgroundDimEnabled" >true </item> <item name= "android:windowContentOverlay" >@null </item> <item name= "android:windowAnimationStyle" >@style/Animation.AppCompat.Dialog </item> <item name= "android:windowSoftInputMode" >stateUnspecified|adjustPan </item> <item name= "windowActionBar" >false </item> <item name= "windowActionModeOverlay" >true </item> <item name= "listPreferredItemPaddingLeft" >24dip </item> <item name= "listPreferredItemPaddingRight" >24dip </item> <item name= "android:listDivider" >@null </item> </style>
theme中使用自己的样式,注释掉他!完美!全屏了!
第二阶段:
美滋滋的给测试测了,结果新问题穿线在全面屏手机虚拟键上,由于我的activity(包括dialogactivity都是使用沉浸样式)虚拟键区域在弹出框中会覆盖我的diaolog布局,而我的布局在地段有个提交按钮。。。你倒是给我浮起来一点啊!好吧,你赢了,我去获取你虚拟区域的高度可以吧,来给我的activity加个内增高,于是
Window win;//全局变量
win = this.getWindow(); win.getDecorView().setPadding(0, 0, 0, ScreenUtils.getNavigationBarHeight(this)); WindowManager.LayoutParams lp = win.getAttributes(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; lp.gravity = Gravity.BOTTOM;//设置对话框置底部显示 win.setAttributes(lp);
但是,软键盘遮挡我的输入框又出现了,好吧,我监听你的软键盘弹出收起,然后一样给我的activity加个可活动的内增高,这下可行了吧,在activity中加个监听,另外新建一个帮助类
SoftKeyBoardListener.setListener(CheckDialogActivity.this, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {@Override public void keyBoardShow(int height) {win.getDecorView().setPadding(0, 0, 0, height); WindowManager.LayoutParams lp = win.getAttributes(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; lp.gravity = Gravity.BOTTOM;//设置对话框置底部显示 win.setAttributes(lp); }@Override public void keyBoardHide(int height) {win.getDecorView().setPadding(0, 0, 0, ScreenUtils.getNavigationBarHeight(CheckDialogActivity.this)); WindowManager.LayoutParams lp = win.getAttributes(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; lp.gravity = Gravity.BOTTOM;//设置对话框置底部显示 win.setAttributes(lp); } });
public class SoftKeyBoardListener {private View rootView;//activity的根视图 int rootViewVisibleHeight;//纪录根视图的显示高度 private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener; public SoftKeyBoardListener(Activity activity) {//获取activity的根视图 rootView = activity.getWindow().getDecorView(); //监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变 rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Override public void onGlobalLayout() {//获取当前根视图在屏幕上显示的大小 Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); int visibleHeight = r.height(); System.out.println(""+visibleHeight); if (rootViewVisibleHeight == 0) {rootViewVisibleHeight = visibleHeight; return; }//根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变 if (rootViewVisibleHeight == visibleHeight) {return; }//根视图显示高度变小超过200,可以看作软键盘显示了 if (rootViewVisibleHeight - visibleHeight > 200) {if (onSoftKeyBoardChangeListener != null) {onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight); }rootViewVisibleHeight = visibleHeight; return; }//根视图显示高度变大超过200,可以看作软键盘隐藏了 if (visibleHeight - rootViewVisibleHeight > 200) {if (onSoftKeyBoardChangeListener != null) {onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight); }rootViewVisibleHeight = visibleHeight; return; }}}); }private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener; }public interface OnSoftKeyBoardChangeListener {void keyBoardShow(int height); void keyBoardHide(int height); }public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity); softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener); } }
当你弹起多少,我就给activity上移多少,你收起,我就设置高度为虚拟栏高度,这下,总算搞定你这个磨人的小妖精了。。。
第一次写这么多,大家点个赞可好!
android实现底部弹出框与软键盘冲突(全面屏虚拟键适配)相关推荐
- android的底部弹出框炫酷的样式,Android自定义底部弹出框ButtomDialog
本文实例为大家分享了Android自定义底部弹出框的具体代码,供大家参考,具体内容如下 先看看效果和你要的是否一样 一 .先来配置自定义控件需要的资源 1.在res文件夹下创建一个anim文件夹并创建 ...
- 仿抖音评论底部弹出框(列表框+发表框)
BottomSheetDialogFragment高仿抖音评论底部弹出框 先看效果图: 这个弹窗的效果是使用BottomSheetDialogFragment做的,第一个弹出的对话框为CommentL ...
- flutter实现底部弹出框以及特色功能
今天项目中要实现底部弹出框并且实现圆角功能,先来预览一下 可以看出实现的公告有 底部圆角,以及朋友圈,微信转发等 实现逻辑我直接代码列出 定义 List<String> nameItems ...
- c语言获取安卓弹窗,Android实现信息弹出框
本文实例为大家分享了Android实现信息弹出框的具体代码,供大家参考,具体内容如下 layout下的dialog_common_layout.xml android:layout_width=&qu ...
- html自定义js程序,JS中微信小程序自定义底部弹出框
实现微信小程序底部弹出框效果,代码分为html,css和js两部分,具体代码详情大家参考下本文. html CSS .commodity_screen { width: 100%; height: 1 ...
- 微信小程序商品详情页底部弹出框(点击加入购物车或立即购买弹出)
项目实现效果如图 项目效果实现思路: wxml页面设计好底部栏<加入购物车,立即购买> 绑定点击触发弹出层函数 写好弹出窗效果 写好原始页面暗化效果 项目实现代码 1.wxml代码 (其中 ...
- Android自定义底部弹出窗-dialog(2种实现分析+源码)
Android自定义底部弹出窗-dialog(2种实现分析+源码) 上线项目功能抽取,在项目开发中,我们会在许多地方会用到底部自定义弹窗,比如设置:个人账户退出,切换,照片的拍照或者相册的调出,或者一 ...
- 【微信小程序封装底部弹出框二】
[微信小程序封装底部弹出框二] <!--index.wxml--> <view><button style="margin-top: 300px;" ...
- 微信小程序 -- 自定义底部弹出框(带动画--滑入滑出)
实现这么一个功能,点击选项进行选择,效果是从底部弹出选项框(带滑出动画),选择了某项或者点击其他地方,隐藏(带滑出动画).效果图如下: 可适用于任何场景,如普通选项(如图)或者类似商城小程序选择商品属 ...
最新文章
- C++11中shared_ptr的使用
- Linux文件目录结构2
- 模拟电路技术之基础知识(十)
- VS2010集成Qt5.2环境搭建
- Tensorflow相关面试题
- Flex弹性布局_思维导图
- [转载] 全本张广泰——第八回 广泰欲悬梁 老侠三救徒
- RK3288 制作内核开机logo
- 搭建MySQL可视化Web界面服务器
- Javaweb 九大内置对象
- 计算机网络重置,怎么重置电脑网络连接
- 重新制定了目标 这样才知道为啥活着 重新起航 星辰大海
- 苹果CMS海螺模板4.0修复版带后台 附安装教程
- 电脑k歌,电脑K歌软件有哪些 5款热门K软件推荐
- excel批量重命名工作表
- [搞笑]后舍男生视频
- kaggle经典题--“泰坦尼克号”--0.8275准确率--东北大学20级python大作业开源(附详细解法与全部代码以及实验报告)
- 切换窗口时改变页面title标题
- html怎么设置视频不能快进,【浏览器插件】Video Speed Controller – 网页视频倍速、快进、回放功能0.07~16 倍...
- 使用Visio 2013 画跨职能流程图
热门文章
- 3DMAX和MAYA到底哪个强—转载
- Oracle10R2新特性之Transparent Data Encryption
- php 百度竞价跳转代码,百度搜索关键词进网站的跳转到另外一个网站的实现方案...
- Move to totally PBR
- 销售人员精细化人员管理系统--业务通
- 201412-3 集合竞价
- 有了这个神器 再也不怕莫名其妙断网了
- 面了几家大厂前端开发,整理了55道框架真题(免费领)
- fuser 命令小结
- 【论文阅读】(2009)A dynamic programming based heuristic for the assembly line balancing problem