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 前言 为了有利于项目维护.增 ...
随机推荐
- MATLAB 进行五种边缘检测
自定义函数: function []=edge_detect(image_name) a=imread(image_name); I=rgb2gray(a); BW1=edge(I,'Roberts' ...
- 关于java中为什么尽量把受检异常转化为非受检异常
首先理解一下受检异常与非受检异常: 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机操作中可能遇到的异常,是一种常见的运行错误,只要程序设计的没有问题通常就不会发生.受检异常与程序的上 ...
- 实现react路由动态加载的组件
import React, { Component } from 'react'; import Loading from '../../base/nc_Loading'; /* * date: 20 ...
- Mechanism:Limited Direct Execution
虚拟化机制的几大挑战:1.性能.在实现虚拟化的同时不增加系统过多开销.2.控制.高效运行程序的同时对CPU保持控制(对资源的管理). Limited direct execution:直接在CPU中运 ...
- 剑指offer7~10题
斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项. n<=39 思路:此题用递归会超内存,故直接循环. 代码: class Solution { pub ...
- CF285D.Permutation Sum
想了很久觉得自己做法肯定T啊,就算是CF机子的3s时限,但我毕竟是 O ( C(15,7)*7!*log ) .... 果然在n=15的点T了...贱兮兮地特判了15过掉了,结果发现题解说就是打表.. ...
- IT名词概括与简单了解
云计算概念 云架构 我看过两本云计算,<云计算><云计算架构技术与实践> 云计算是一个很广的概念,简单的说将互联网中的计算机资源按需分配,提高闲置资源的利用率,需要多少你就购买 ...
- SignalR 行实时通信遇到的
SignalR可用于向ASP.NET应用程序添加任何类型的“实时”Web功能.虽然聊天经常被用作示例,但您可以做更多的事情.每当用户刷新网页以查看新数据,或者页面实现Ajax长轮询以检索新数据时,都可 ...
- Proxifier代理工具简介和下载
Proxifier 是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链.支持64位系统,支持Xp,Vista,Win7,支持soc ...
- verilog中24LC04B iic(i2c)读写通信设计步骤,以及程序常见写法错误。
板子使用的是黑金的是xilinx spartan-6开发板,首先准备一份24LC04B芯片资料,读懂资料后列出关键参数. 如下: 1.空闲状态为SDA和SCL都为高电平 2.开始状态为:保持SCL,S ...