popwindow设置偏移部分超出屏幕,保证不超出怎么办

popwindow设置偏移部分超出屏幕,保证不超出怎么办,第1张

1 应该限制popwindow的偏移量,确保不超出屏幕。

2 可以通过计算popwindow的位置和屏幕边缘的距离,然后根据需要调整popwindow的偏移值,以确保不会超出屏幕。

3 可以通过设置popwindow的Gravity属性和偏移量,以及给popwindow的父布局设置clipChildren属性为false,来避免popwindow的偏移部分超出屏幕。

另外,还可以考虑使用PopupWindow的d出框箭头指向屏幕中心的方式,来确保popwindow可以在屏幕内完全显示。

1、含义

Popwindow就是Android上自定义的一个d出窗口,是在当前activity的顶部的,可以在任意的位置显示,在显示的时候会阻塞UI线程。

2、构造

Popwindow可以直接通过构造方法获取

new PopupWindow(View contentView,intwidth,intheight,booleanfocusable)

构造方法有很多,但是要确保contentview ,width,hight的设置,否则Popwindow不会显示任何内容

这些参数也都可以单独进行设置,比如 popwindow.setContentView(contentView)

3、解析

popwindow的难点就在于这几个参数的设置,一般容易使人迷惑。

popupWindow1.setFocusable(true)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(true)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000))//设置背景

关于背景的设置

popupWindow1.setFocusable(true)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(true)//能够响应触摸事件

//popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000))//设置背景

一般情况,如果前面几个设置都设置为true,而且果设置了背景的话,那么你按back键和点击d窗外的区域能使d窗消失,如果不设置背景的话,则不会有这样的效果,即使你设置了popupWindow.setOutsideTouchable(true)。

那么这是为什么呢?别人这里已经有完整的解答,就不再赘述了。

详情见: http://www.cnblogs.com/mengdd/p/3569127.html

关于touchable的设置

首先,我们要明确一点,点击到d窗上的touch事件是首先传递到d窗上的,如果你设置了touchable为true,那么当前d窗则会消耗掉touch事件,当前的activity则不会再收到touch事件,反之则会收到事件。

关于focusable的设置

foucsable设置为true,d窗在d出后就获取到了焦点,焦点的获取,就告诉设备,外部按键事件向哪里传递。如果d窗获取到了焦点,此时点击外部按键,按键事件是直接传递给d窗的。需要注意的是设置focusable为true,并不代表这个控件就获取到了焦点,而是表示可以获取焦点。

popupWindow1.setFocusable(false)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(true)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000))//设置背景

这也就解释了,按照上述设置,当你按back键的时候,并不是想象中的popwindow消失,因为d窗并没有获取到焦点,按键事件直接传递到当前activity了。

popupWindow1.setFocusable(true)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件,设置false也是一样的效果

popupWindow1.setTouchable(true)//能够响应触摸事件

// popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000))//设置背景

当focusable为true后,感觉d窗影响的区域是整个屏幕(猜测),这么猜测是有根据的,因为这时候点击d窗内和d窗外感觉是一样的,d窗的contentview都会收到同样的事件序列,所以这时候,你就会发现setOutsideTouchalbe并没有什么用。此时,如果touchable为true,一般情况下,无论点击的是d窗内还是外,当前的activity是收不到任何touch事件的,这也印证了我的猜测。

popupWindow1.setFocusable(true)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(false)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000))//设置背景

当你如上述设置的话,点击d窗外和点击d窗内都会使得d窗消失,因为d窗内外都是一样的效果,而d窗又没有消耗事件的话(setTouchable为false),事件首先传递到d窗,类型是MotionEvent.ACTION_OUTSIDE,此时如果没有设置背景的话,事件将会传递到activity中。如果setTouchable为true的话,那么传递到d窗的事件类型就是普通类型,而且怎么都不会传递到activity中去。

popupWindow1.setFocusable(true)//获取焦点

popupWindow1.setOutsideTouchable(false)//获取外部触摸事件

popupWindow1.setTouchable(false)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000))//设置背景

当然,如果你如上述那样设置,那么d窗是不会收到任何touch事件的,因为系统判断你都设置false了,就是说不需要了,因此就不会发touch事件给这个d窗

popupWindow1.setFocusable(false)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(true)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000))//设置背景

如果你设置f ocusable为false的话,那么d窗影响的区域就是你看到的d窗内,按上图设置,点击外部区域,事件首先传递到d窗,类型是MotionEvent.ACTION_OUTSIDE,如果没有设置背景的话,也就是说d窗没有消耗的话,事件会传递到当前的activity中的。

关于OutsideTouchable的设置

OutsideTouchalbe顾名思义,就是指的是外面的事件,在这里,指的就是d窗之外touch事件,比如说,像上述设置就能够点击d窗之外的区域,使得d窗消失。

popupWindow1.setFocusable(false)//获取焦点

popupWindow1.setOutsideTouchable(true)//获取外部触摸事件

popupWindow1.setTouchable(true)//能够响应触摸事件

popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000))//设置背景

上图这么设置,点击d窗外部区域能够使得d窗消失,就是因为设置了OutsideTouchalbe为true,导致 事件首先传递到d窗,类型是MotionEvent.ACTION_OUTSIDE。

总结:   设置focusalbe为true,两个效果那么d窗就会获取焦点,就会使得按键事件分发到d窗上;d窗影响的touch事件分发就是整个屏幕,点击d窗内和d窗外传递给d窗的事件序列是一样的

设置背景的话,就等于给d窗加了个外壳,而这个外壳重写了几个方法能够处理回退和一部分touch事件,这也就是设置了背景后,能够点击回退键和d窗外使得d窗消失的原因

设置 touchable为true的话,就表示d窗会消耗掉事件,只要是d窗内的事件都会被消耗掉,包括 focusalbe为true时d窗外的(因为说过,这时候d窗内外是一样的)。

设置OutsideTouchable为true的话,就是表示可以收到外部的事件 MotionEvent.ACTION_OUTSIDE。

注意: 无论怎么设置,只要d窗能够收到touch事件,那么一定是d窗先收到事件,如果d窗消耗掉了,那么当前activity将收不到touch事件

按键事件是向焦点获取的控件分发的

做个功能,实现这种效果

根据屏幕位置判断如果在屏幕中间上方点击时就在控件下方d出,如果在上方的话就在控件上方d出

,我是这么实现的使用了一个第三方封装的控件EasyPopup

但是存在一个问题就是部分机型正常实现这种效果

可是在部分模拟器上

却出现这种效果,经查发现问题出现在这个控件CENTER时,计算出的偏移量小于pop宽度/2,导致pop右边超出了屏幕范围,所以垂直偏移被忽略导致偏移无效。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11131468.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存