简介

  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弹窗的更多相关文章

  1. Android开发 PopupWindow弹窗调用第三方地图(百度,高德)实现导航功能

    博客描述:后台返回地点的经纬度在地图上进行描点,点击导航弹出PopupWindow进行选择地图操作,如果手机中没有安装地图,提示没有,否则传值调起地图进行导航操作 看一下实现的效果,没图说再多都白搭 ...

  2. android开发 PopupWindow 设置充满屏幕

    View qrcode_view = this.getLayoutInflater().inflate(R.layout.taskdetail_qrcode,null); final PopupWin ...

  3. Android:PopupWindow简单弹窗改进版

    Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...

  4. Android进阶2之PopupWindow弹窗(有点悬浮窗的感觉)

    PopupWindow是一个可以用来显示一个任意的视图的弹出窗口,他需要完全依赖layout布局. 它没什么界面,在弹出的窗口中完全显示布局中的控件. 上面两个美女头就是弹窗PopupWindow显示 ...

  5. Android开发技巧——使用PopupWindow实现弹出菜单

    在本文当中,我将会与大家分享一个封装了PopupWindow实现弹出菜单的类,并说明它的实现与使用. 因对界面的需求,android原生的弹出菜单已不能满足我们的需求,自定义菜单成了我们的唯一选择,在 ...

  6. 【Android开发日记】Popupwindow 完美demo

    Popupwindow 完美demo实现 图示: 关键代码说明: 1.弹出popupwindow,背景变暗 ColorDrawable cd = new ColorDrawable(0x000000) ...

  7. 【Android开发坑系列】之PopupWindow

    PopupWindow在4.0之前的版本有个系统级别的BUG,必须借助一段自定义的fix代码来修复.其中mPopPm就是PopupWindow实例.java.lang.NullPointerExcep ...

  8. 【转】Android开发规范

    转自:https://github.com/Blankj/AndroidStandardDevelop 摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规 ...

  9. 【转】Android 开发规范(完结版)

    摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规范 7 第三方库规范 8 注释规范 9 测试规范 10 其他的一些规范 1 前言 为了有利于项目维护.增 ...

随机推荐

  1. Oracle数据库 基础SQL语句练习

    一.说明 第一次使用Oracle,想做一些练习,熟悉一些oracle. 表:使用的是scott用户,默认的表 具体表讲解,可以参考该文档:https://www.cnblogs.com/xjcheng ...

  2. 渗透测试学习 二、Windows基础

    系统目录  服务  端口  注册表  黑客常用DOS命令(在拿到shell时会用到) 一.  系统目录 Windows目录  系统的安装目录 System32àconfigàSAM文件  是用户密码的 ...

  3. Kali安装zmap简单介绍

    zmap是一个非常方便的扫描器,跟nmap和masscan一样,不过区别在于zmap他快,号称是一小时扫遍整个互联网.主要使用方式是TCP SYN scan.TCP connectscan.UDP s ...

  4. javaEE十三种核心技术

    郭晨 软件151 1531610114 java的大方向就是JavaEE,JavaEE不仅仅是socket编程,具体包括13中核心技术. JAVAEE的核心API与组件 JAVAEE平台由一整套服务( ...

  5. RGB颜色名称与色值对应表

    实色效果 英文名称 R.G.B 16色 实色效果 英文名称 R.G.B 16色   Snow 255 250 250 #FFFAFA   PaleTurquoise1 187 255 255 #BBF ...

  6. PHP数组和XML相互转换的函数

    //数组转xml function ArrToXml($arr) { if(!is_array($arr) || count($arr) == 0) return ''; $xml = "& ...

  7. 使用composer遇到的坑

    平台:Windows下cmd命令行內 問題 [Composer\Downloader\TransportException] The "https://packagist.phpcompos ...

  8. Jquery 一个页面单个倒计时 实现

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. SSHD启动失败,错误码255

    查看/etc/ssh/sshd_config 发现,Listen Address并不是我想要的ip,将其注释掉 sshd restart,结果返回 Permission denied (publick ...

  10. 【java】之算法复杂度o(1), o(n), o(logn), o(nlogn)

    在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义: 这是算法的时空复杂度的表示.不仅仅用于表示时间复杂 ...