Android简单沉浸式弹出输入框

Android简单沉浸式弹出输入框

2023年7月15日发(作者:)

Android简单沉浸式弹出输⼊框前⾔最近公司项⽬在写IM聊天室功能,刚开始使⽤dialog⽅式,让dialog居底部显⽰,但是项⽬中需要⽂本和表情切换发送消息,但是因为软键盘本来就是⼀种特殊的dialog,dialog具有优先级,软键盘的优先级总是⾼于我们平时⽤到的dialog,所以出现显⽰消失的时候,因为软键盘与⾃定义的输⼊弹出框消失显⽰时机问题,导致闪烁问题。⽹上还有⼀种⽅式是在activity的底部直接添加⼀个view的⽅式,通过约束其上的布局来解决闪烁问题,但是这种情况输⼊弹窗会把整个布局顶上去,感觉体验不是特别好。所以决定去看看其他APP的效果,发现头条和简书的弹出输⼊框都是都不错,如下图所⽰:但是头条的弹出输⼊框在弹出时,系统状态栏会变⾊,感觉影响体验,简书的弹出输⼊框是在底部直接添加view的⽅式,只不过是增加了遮罩层。如何做到效果和dialog⼀致,点击外部和返回键收起,然后还能切换⽂本和表情输⼊,另外不会引起系统状态栏变⾊,。头条.png简书输⼊框.png布局添加View因为要实现当输⼊框弹出的时候⼀是不能让原来的内容顶上去,⼆是输⼊框内容要覆盖在当前内容的上层。所以不能采取直接在activity的布局底部直接填加view的⽅式,也不能是dialog的形式,所以只能添加到activity的顶层布局,activity的顶层布局是decorView,然后添加到底部,操作软键盘的隐藏显⽰来调取弹出输⼊框,显⽰软键盘的时候添加,弹出框消失的时候移除。添加到DecorView/*** 添加*/if (mContext instanceof Activity) { Activity activity = (Activity) mContext; final ViewGroup decorView = (ViewGroup) dow().getDecorView(); final ViewGroup content = (ViewGroup) ewById(t); if (getParent() == null) { w(this); }}从DecorView移除//移除掉当前的view ViewParent parent = getParent(); if (parent != null) { ((ViewGroup) parent).removeView(this); }注意事项:因为弹出框是在下⽅显⽰,所以添加到DecorView的顶级View要位于DecorView底部点击外部消失如果点击输⼊框外⾯,取消输出框体验更好。为此我们监听当前弹出框的onTouchEvent事件:/** * 处理点击范围,如果在不在就取消 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { Rect rect = new Rect(); getInputView().getGlobalVisibleRect(rect); if (!sInRect((), (), rect)) { switch (ion()) { case _DOWN: downX = (); downY = (); downTime = tTimeMillis(); break; case _UP: float dx = () - downX; float dy = () - downY; float distance = (float) ((dx, 2) + (dy, 2)); if (distance < touchSlop && (tTimeMillis() - downTime) < isClickTime) { //点击外部就消失 eledOnTouchOutside(); } downX = 0; downY = 0; downTime = 0; break; } } return true; }触点说明:1、sInRect((), (), rect) 检测当前触点是否在弹出框之中2、onTouchEvent返回值设置为true,响应事件点击返回键消失 getInputView().setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == E_BACK && ion() == _UP) { if (onInputListener != null) { Pressed(); } return true; } return false; } });返回值⼀定要为true,否则失效如果你设置了这个⽅法,但是发现没有响应,是因为其他地⽅抢占了焦点,可能是edittext或者是软键盘,这⾥说明⼀下软键盘也是⼀种dialog,dialog默认抢占焦点,所有添加如下⽅法:View inputView = getInputView(); tFocus(); usable(true); usableInTouchMode(true);当前弹出框抢占焦点之后,点击back键就会取消软键盘,由于软键盘消失有动画,需要时间,所以有两种⽅式可以取消弹出框,第⼀种发送延迟消息的⽅式,这种⽅式由于软键盘弹出时间不确定并且如果多次主动弹出会造成消息冲突,如果采⽤这种⽅式,尽量去使⽤防⽌重复点击监听,第⼆种是定义中间变量,再监听软键盘消失赋值为消失状态,这时候是消失状态但不是销毁状态。/** * 输⼊框的四种状态 */public static final int INITIALIZE = 0;public static final int SHOWING = 1;public static final int DISMISSED= 2;public static final int DISMISS_OUTSIDE = 100;public static final int DISMISS_BACKKEY = 101;public static final int DISMISS_KEYBOARD = 103;private int currentState = INITIALIZE;说明:因为之前为了响应返回键和touch事件,强制获取焦点,当弹出框消失的时候主动把焦点返回给当前页⾯,如果不这么做,可能会遇到其他问题,⽐如RecyclerView滚动事件等。 clearFocus(); View contentView = ((Activity) getContext()).findViewById(t); usable(true); usableInTouchMode(true);模式切换查看其它APP,有时候会切换到表情页⾯,有些APP的软键盘表情页⾯跟软键盘⾼度不⼀致导致有错位的感觉,如果表情页⾯跟软键盘⾼度⼀致体验会好很多,所以我在初始化的时候设置表情页⾯的⾼度。 ibility(INVISIBLE); Params linearParams = (Params) outParams(); int lastHeight = ; if (bottomHeight != lastHeight) { //不重复设置 = bottomHeight; outParams(linearParams); }说明:布局中关于表情页⾯设置Gone,减少绘制,但是显⽰弹出框的时候⼀定要给表情页⾯占位ibility(INVISIBLE);并且之后切换的过程中也是如此,不能设置为Gone,否则有闪动错位效果,影响体验。其他由于本⼈⽐较懒,个⼈觉得如果弹出框加上动画可能更好⼀些,不过毕竟动画⾮常消耗资源,暂且就没加,可以⾃⾏添加,由于软键盘⽅式和各个⼿机⼚商对于Rom的修改,不知道在其他型号⼿机上是否会出现未知问题,⼤家如果遇到问题,及时反馈给我,在此感谢⼤家阅读本⽂。最后附上代码简单沉浸式弹出输⼊框

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689430195a246945.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信