android PopupWindow关于返回按键的判断
来源:互联网 发布:淘宝客推广链接生成 编辑:程序博客网 时间:2024/04/29 20:44
1、首先讲解下业务需求,在一个activity中弹出PopupWindow,要求点击外部区域pop不消失,并且点击返回按键pop消失并且需要关闭当前activity。
第一步:点击外部区域不消失
第一想法是setOutsideTouchable(false); // 设置popupwindow外部可点击
然后并没有达到我想要的效果
最终的设置包括popupWindow的软键盘在内
//此popup需要软键盘 this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); //软键盘弹出时不会覆盖popuwindow this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); this.setTouchable(true); // 设置popupwindow可点击 this.setOutsideTouchable(false); // 设置popupwindow外部可点击 this.setFocusable(true); // 获取焦点
后来看了很多博客发现好像都一样,说什么设置背景 就能生成一个 跟布局给你写了N多代码
接下来分析一下源码吧 因为自己也找不到问题在哪里!
步骤1、
public void setBackgroundDrawable(Drawable background) { mBackground = background;}我删了部分代码,关键是mBackground;
步骤2、
private void preparePopup(WindowManager.LayoutParams p) { if (mDecorView != null) { mDecorView.cancelTransitions(); } if (mBackground != null) { mBackgroundView = createBackgroundView(mContentView); mBackgroundView.setBackground(mBackground); } else { mBackgroundView = mContentView; } ***mDecorView = createDecorView(mBackgroundView);***}我删掉了部分代码自己可以去popupWindow去看源码 反正网上讲的设置mBackground目前已经过时了吧,因为不管设置没有肯定跟布局是createDecorView(mBackgroundView)生成的
步骤3、
private PopupDecorView createDecorView(View contentView) { final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); final int height; if (layoutParams != null && layoutParams.height == WRAP_CONTENT) { height = WRAP_CONTENT; } else { height = MATCH_PARENT; } final PopupDecorView decorView = new PopupDecorView(mContext); decorView.addView(contentView, MATCH_PARENT, height); decorView.setClipChildren(false); decorView.setClipToPadding(false); return decorView; }
生成一个PopupDecorView作为根布局
步骤4、看看这个类咯 PopupDecorView
private class PopupDecorView extends FrameLayout { private TransitionListenerAdapter mPendingExitListener; public PopupDecorView(Context context) { super(context); } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { if (getKeyDispatcherState() == null) { return super.dispatchKeyEvent(event); } if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { final KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.startTracking(event, this); } return true; } else if (event.getAction() == KeyEvent.ACTION_UP) { final KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null && state.isTracking(event) && !event.isCanceled()) { dismiss(); return true; } } return super.dispatchKeyEvent(event); } else { return super.dispatchKeyEvent(event); } } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { return true; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); if ((event.getAction() == MotionEvent.ACTION_DOWN) && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { dismiss(); return true; } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { dismiss(); return true; } else { return super.onTouchEvent(event); } }
然后跟布局一个FrameLayout 里面按键分发把物理返回键写死了。
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
} else if (event.getAction() == KeyEvent.ACTION_UP) {
dismiss();
这样下来大概逻辑 物理返回键 松开我给你关了这个popupWindow
天呐!!!为什么会这样 那不是返回按键我永远也获取不到了么
绝望ing
我提出的第二个问题已经看到结局了 就是物理返回键别人帮你做掉了,控件dismiss
那我们来看看第一个问题: 点击外部控件不消失 很显然这是一个TouchEvent
看看onTouchEvent发现 他又干了一些事情
if ((event.getAction() == MotionEvent.ACTION_DOWN)
&& ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
dismiss();
return true;
} else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
dismiss();
return true;
}
解析一下就是 超出 控件大小范围的事件 我会把控件给消失掉。
但是虽然这么写了还是有救命的方法的 dispatchTouchEvent()方法有一个接口mTouchInterceptor
机智的我立马 写了 this就是自己的自定义popup
private void addTouchListener(){ this.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); if ((event.getAction() == MotionEvent.ACTION_DOWN) && ((y < 0) || (y >= getHeight()))) { return true; } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { return true; } return false; } }); }
问题1点击外部区域不消失迎刃而解 这里有个坑,你定义Pop宽高有match_parent或者wrap_content的时候拿出来的的实际高度有可能是-1 -2 的枚举值 反正我一路被坑过来,我这边设置的话宽度match_prarent 高度自己定义的
所以写 setTouchInterceptor的时候只判断高度就OK
写了这么多问题2 困扰我很久有想过PopupWindow自己写一个或者添加什么onKeyListener 都不行 然后很绝望 最后都想用Dialog来实现了 反正浪费了很多时间
最后问了大神 怎么解决这个问题 大神说你加个标志位 判断一下不就行了 然后我就解决了问题2。
反正都是消失连带关闭activity 那我就一个正常消失不关闭的途径,添加个标志位 完美解决,
反正最后是哭了,一大波弯路和坑 写了一堆有的没的 ,结果干不过经验老道的大神的一个标志位
写的是有点乱。 记录一下 下次用的话给自己提个醒
- android PopupWindow关于返回按键的判断
- 关于Android的PopupWindow用法
- android的popupwindow点击返回按钮关闭
- android的popupwindow点击返回按钮关闭
- android监听返回按键
- Android中关于PopupWindow的使用简介
- Android关于PopupWindow控件的使用
- 关于android中PopupWindow的基本使用
- android虚拟按键NavigationBar的判断
- Android popupWindow响应back按键并关闭
- Android popupWindow响应back按键并关闭
- Android popupWindow响应back按键并关闭
- Android popupWindow响应back按键并关闭
- Android popupWindow响应back按键并关闭
- Android popupWindow响应back按键并关闭
- Android虚拟按键适配Popupwindow
- android PopupWindow 监听返回键,
- 7.25关于PopupWindow android.
- 20170807-20170813
- FPGA全局时钟处理
- Spring Boot缓存实战 EhCache
- vue项目打包之后js文件过大怎么办?
- vux2代码解析
- android PopupWindow关于返回按键的判断
- Android蓝牙BLE开发详解
- 改造U盘成mac启动盘的方法
- 以map接收数据库中查询到的多行结果
- Android Service 创建,配置
- Hbase1.2.6安装
- 一直碰到虚拟机连接不上网络的问题,如今做个笔录
- 浅谈Shiro框架中的加密算法,以及校验
- 简单实用的图表技巧,你会吗?