Android 开发 PopupWindow弹窗
简介
PopupWindow,顾名思义弹窗.PopupWindow是与AlertDialog在形式上类似的弹窗功能,都是为了在activity最上层显示一个弹窗.但是区别是PopupWindow可以自定义出现的位置,并且可以添加入自己需要的View或者导入自己写好的xml布局
应用场景
在很多场景下都可以见到它。例如ActionBar/Toolbar的选项弹窗,一组选项的容器,或者列表等集合的窗口等等。
简单的Demo
为了了解基本的流程,我们来一个最简单demo演示一下.
创建流程:
- 用LayoutInflater获得xml布局View .或者直接在代码上new一个View
- 实例化一个PopupWindow,将View在实例化作为参数传入
- 配置PopupWindow参数
代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2); TextView textView = new TextView(Main2Activity.this);
textView.setText("测试文本");
final PopupWindow popupWindow = new PopupWindow(textView,200,300);//参数为1.View 2.宽度 3.高度
popupWindow.setOutsideTouchable(true);//设置点击外部区域可以取消popupWindow mTestButton = (Button)findViewById(R.id.test_btn);
mTestButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.showAsDropDown(mTestButton);//设置popupWindow显示,并且告诉它显示在那个View下面 }
});
}
效果图:

PopupWindow的配置参数详解
设置内容View
setContentView(View contentView)
除了正常在实例化PopupWindow的时候直接将view传入也可以用这个方法在实例化后重新配置需要的view
设置PopupWindow宽度与高度
setWidth(int width) setHeight(int height)
除了正常实例化的时候传入宽度与高度,也可以用这个2个方法在实例化后在重新配置需要的宽度与高度
设置PopupWindow背景
setBackgroundDrawable(Drawable background)
final PopupWindow popupWindow = new PopupWindow(textView,200,300);
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher_background));//设置背景
mTestButton = (Button)findViewById(R.id.test_btn);
mTestButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.showAsDropDown(mTestButton); }
});

设置外部点击退出
setOutsideTouchable(boolean touchable)
这个我在上面的代码已经演示过了
设置PopupWindow可聚焦
setFocusable(boolean focusable)
除了一般的聚焦选中功能,还有一个用处重点!重点!重点!设置了可聚焦后,返回back键按下后,不会直接退出当前activity而是先退出当前的PopupWindow.
设置弹窗弹出的动画高度
setElevation(float elevation)
原本没有设置,弹窗的弹出动画效果位置就只会在控件附件,但是设置后弹窗的起始动画位置就变更远了.请看下面的效果图:
popupWindow.setElevation(1000f);//我将动画位置设置为1000f

设置显示方法
显示提供了两种形式:
showAtLocation()显示View的内部在指定位置()
有两个方法重载:
这个属性一般使用在在整个Activity的window里显示,也就是在整个屏幕内,这个也支持在指定View的内部找到锚点.
例子1:如果你需要在一个布局的里面的下方显示就只需要设置属性为
popupWindow.showAtLocation(view,Gravity.BOTTOM,0,0);
例子2:如果你需要在Activity的window里显示的下方显示就需要设置属性为:
popupWindow.showAtLocation(activity.getWindow().getDecorView(),Gravity.BOTTOM,0,0);
public void showAtLocation(View parent, int gravity, int x, int y)
public void showAtLocation(IBinder token, int gravity, int x, int y)
showAsDropDown()显示在一个参照物View的外部周围
有三个方法重载:
注意!这里参照物View的周围,使用这个方法是无法在View的内部找到锚点,它的锚点都是围绕者View的外部四周
public void showAsDropDown(View anchor)
public void showAsDropDown(View anchor, int xoff, int yoff)
public void showAsDropDown(View anchor, int xoff, int yoff, int gravity)
带Gravity参数的方法是API 19新引入的。
这里的xoff与yoff是对应view的坐标偏移量,对应的初始坐标位置是view的左下角.
请注意!在实际使用showAsDropDown()方法的时候,如果只使用showAsDropDown(View anchor, int xoff, int yoff),这个形参会出现在一些品牌的机型上出现一些问题。原因是有些机型初始坐标其实不一定在左下角,而是在左上角。所以,你这个时候设置yoff值就会出现2种不同去情况。怎么解决这个问题呢? 就是尽量使用showAsDropDown(View anchor, int xoff, int yoff, int gravity),这个形参主动设置第4个int gravity的值,来确定初始坐标的位置。
这里我们用一个demo演示一下,假设我现在需要把显示位置移动到目标控件的右上角就需要如下代码:
popupWindow.showAsDropDown(mTestButton,mTestButton.getWidth(),-mTestButton.getHeight())

设置PopupWindow叠放效果
setOverlapAnchor(true);
当然你把PopupWindow的位置设置到可以完全覆盖你指定位置显示PopupWindow的view时,如果设置这个方法为true,那么你无论如何都无法覆盖这个view始终会让这个view漏出一小部分,如效果图所示:

设置PopupWindow可触摸
setTouchable(true);
设置false后,将会阻止PopupWindow窗口里的所有点击事件
设置PopupWindow监听拦截指定触摸事件
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//如果这里设置返回true,说明你会消耗这个触摸事件,不会向下传递到内容view里
return false;
}
});
设置PopupWindow覆盖状态栏或者超过屏幕尺寸
允许弹出窗口扩展到屏幕范围之外。默认情况下,窗口被裁剪到屏幕边界。将其设置为false将允许精确定位窗口
popupWindow.setClippingEnabled(false);
设置PopupWindow监听取消事件
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
}
});
一些问题总结
解决Android7.0调用showAsDropDown方法失效问题
原理是重写showAsDropDown,将PopupWindow对话框的高度设置成整个屏幕这么大,然后在减去这View指定的底部坐标值。有点治标不治本的味道。
但是,在个别对话框宽度是屏幕的宽度,但是高度是某个View下边与屏幕底部的长度的时候有很好的实现。
如图所示:
没有对话框的时候

有对话框的时候

@Override
public void showAsDropDown(View anchor) {
if(Build.VERSION.SDK_INT >= 24) {
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);
DisplayMetrics outMetrics = new DisplayMetrics();
Context context = anchor.getContext();
((Activity) context).getWindowManager().getDefaultDisplay().getRealMetrics(outMetrics);
int h = outMetrics.heightPixels - rect.bottom;
setHeight(h);
}
super.showAsDropDown(anchor);
}
end
Android 开发 PopupWindow弹窗的更多相关文章
- Android开发 PopupWindow弹窗调用第三方地图(百度,高德)实现导航功能
博客描述:后台返回地点的经纬度在地图上进行描点,点击导航弹出PopupWindow进行选择地图操作,如果手机中没有安装地图,提示没有,否则传值调起地图进行导航操作 看一下实现的效果,没图说再多都白搭 ...
- android开发 PopupWindow 设置充满屏幕
View qrcode_view = this.getLayoutInflater().inflate(R.layout.taskdetail_qrcode,null); final PopupWin ...
- Android:PopupWindow简单弹窗改进版
Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...
- Android进阶2之PopupWindow弹窗(有点悬浮窗的感觉)
PopupWindow是一个可以用来显示一个任意的视图的弹出窗口,他需要完全依赖layout布局. 它没什么界面,在弹出的窗口中完全显示布局中的控件. 上面两个美女头就是弹窗PopupWindow显示 ...
- Android开发技巧——使用PopupWindow实现弹出菜单
在本文当中,我将会与大家分享一个封装了PopupWindow实现弹出菜单的类,并说明它的实现与使用. 因对界面的需求,android原生的弹出菜单已不能满足我们的需求,自定义菜单成了我们的唯一选择,在 ...
- 【Android开发日记】Popupwindow 完美demo
Popupwindow 完美demo实现 图示: 关键代码说明: 1.弹出popupwindow,背景变暗 ColorDrawable cd = new ColorDrawable(0x000000) ...
- 【Android开发坑系列】之PopupWindow
PopupWindow在4.0之前的版本有个系统级别的BUG,必须借助一段自定义的fix代码来修复.其中mPopPm就是PopupWindow实例.java.lang.NullPointerExcep ...
- 【转】Android开发规范
转自:https://github.com/Blankj/AndroidStandardDevelop 摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规 ...
- 【转】Android 开发规范(完结版)
摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规范 7 第三方库规范 8 注释规范 9 测试规范 10 其他的一些规范 1 前言 为了有利于项目维护.增 ...
随机推荐
- 双十一LoanMarket压力测试报告
测试背景 评估服务器资源及几个重要接口的并发性能. 测试需求 由开发提供的5个重要接口: 业务场景 URL 访问量(万) TPS 请求比例(%) 随手借点-首页产品接口 /suishoujiedian ...
- 20155208徐子涵 《网络对抗技术》Web基础
20155208徐子涵 <网络对抗技术>Web基础 实验要求 Web前端HTML Web前端javascipt Web后端:MySQL基础:正常安装.启动MySQL,建库.创建用户.修改密 ...
- 个人 git-hub使用方法
注册码云 安装git hub git init here 创建本地仓库(repository),将会在文件夹下创建一个 .git 文件夹,.git 文件夹里存储了所有的版本信息.标记等 ...
- hql和sql的一些区别
日期格式化查询的区别: selectSql.append(" AND DATE_FORMAT(o.createDate,\'%Y-%m-%d\') = :createDate"); ...
- SQL-函数-014
SQL中函数的种类: 聚合函数.数学函数.字符串函数.时间函数.元数据函数 聚合函数: sum():求和函数 select SUM(Admin.age) as Age from Admin max() ...
- Python变量和常量
1.什么是变量 变量:核心在于变和量儿字,变->变化,量->状态如何定义? x=1 变量名 变量赋值符号:= 变量值:1 其中变量名又称为标识符: 1. 可以是字母,数字,下划线的任意组合 ...
- hello1 hello2 服务器安装加部署全过程
1.安装maven和glassfish及配置环境变 首先搜索并下载maven3.6.0和glassfish4.1.1(版本看按需要选择). 点击安装包进行安装 安装完成后开始配置环境变量 打开系统环境 ...
- 弹出的 Dialog 里,包含 Form,如何在关闭 Dialog 时,执行 resetFields(对整个表单进行重置,将所有字段值重置为初始值并移除校验结果)
做法: before-close 事件中,调用 resetFields 取消按钮事件中,调用 resetFields <el-dialog title="弹出窗口" :vis ...
- 一、python中的一切皆对象
1.函数和类是对象,是Python中的一级公民 (1)将函数和类赋值给一个变量 将函数或类赋值给一个变量,就可以把该变量当成函数或类来使用 def ask(name): print(name) cla ...
- [转]解决百度ueditor插入动态地图空白 支持iframe方法
说明:新版本ueditor要修改 xss过滤白名单 修改配置文件ueditor.config.js 搜索: whitList 增加下面第二行即可 ,whitList:{ iframe: ['fram ...