PopupWindow

概述

组件的名字其实已经很直观了,直译一下即弹出窗口。

说起弹窗,想起了不久前的AlertDialog,顺便贴一下当时写的博文链接:https://blog.csdn.net/nishigesb123/article/details/88605356

既然效果类似,肯定有差别,不然干嘛要定义两个一模一样的?

这个问题先留着,先把PopupWindow实现了,看一下效果,再和AlertDialog进一步的比对。

 

老规矩,我们还是先开始设计

布局

为了满足最基本的测试,我们添加一个简单的按钮,并未它赋上一个点击事件。代码比较简单,直接给出:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示弹出窗口"
        android:onClick="showWindow"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

MainActivity

  • 既然定义了一个点击事件,那么我们首先完成点击事件的编写
  • 在这个事件中,我们需要创建PopupWindow对象实例(new一下)
  • 然后PopupWindow构造方法如下,我们这里选择了前者(窗体视图,宽,高)
public PopupWindow(View contentView, int width, int height)

public PopupWindow(View contentView, int width, int height, boolean focusable)
  • 为了给PopupWindow提供contentView参数,我们需要定义一个布局文件popup_layout.xml

(布局文件名和布局内容随意,下面给出一个我写的测试用的参考代码)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="测试1"
        android:id="@+id/t1"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="测试2"
        android:id="@+id/t2"/>
</LinearLayout>
  • 回到MainActivity,把写好的布局文件用inflate实例化一下,以便给PopuWindow创建提供参数。
  • 然后简单设置一些PopuWindow的属性(具体设置了哪些就不一一写出来了,在代码中加了注释)
  • 最后是显示,有如下几种方法,DropDown相对于某个控件的位置,Location相对于父控件的位置,参数xy为偏移量(如果有的话)。另外还有一个关闭弹窗的方法...dismiss() 无参数

一切准备就绪就可以运行了...效果的话就看看就好...点击按钮,文字会从右侧飞入...

然后我们就可以分析之前留下来的问题了,找一张当时AlertDialog的效果图

可以看到,AlertDialog弹出的对话框置顶于元素之上,屏蔽掉了其他控件的样式。

反观,PopupWindow虽然没有屏蔽其他控件的样式,但是有一种操作系统里“中断”的感觉,如果不完成它(退出它),其他组件无法响应。

 

当然,这样有感而发的简单描述并不能完全概况这两个组件的区别,也不敢误人子弟。

所以在文末转载了一篇总结的很到位的博文(orz)

获取设备屏幕尺寸

放着先,日后用到了回来填坑(学的视频里的人也就讲到这里 HaH)

        //获取屏幕尺寸固定用法
        DisplayMetrics dm =new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = dm.heightPixels;

文章接近尾声,贴心的附上一份

API

介于...google国内访问各种肉疼....这里是网上搜的两篇别人整理的API文档,非常全,而且进行了翻译

https://blog.csdn.net/u011240877/article/details/46058349

https://blog.csdn.net/xiangshiweiyu_hd/article/details/83316237

PopupWindow和AlertDialog的异同

(1)Popupwindow在显示之前一定要设置宽高,Dialog无此限制。

(2)Popupwindow默认不会响应物理键盘的back,除非显示设置了popup.setFocusable(true);而在点击back的时候,Dialog会消失。

(3)Popupwindow不会给页面其他的部分添加蒙层,而Dialog会。

(4)Popupwindow没有标题,Dialog默认有标题,可以通过dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消标题

(5)二者显示的时候都要设置Gravity。如果不设置,Dialog默认是Gravity.CENTER。

(6)二者都有默认的背景,都可以通过setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));去掉。

其中最本质的差别就是:AlertDialog是非阻塞式对话框:AlertDialog弹出时,后台还可以做事情;而PopupWindow是阻塞式对话框:PopupWindow弹出时,程序会等待,在PopupWindow退出前,程序一直等待,只有当我们调用了dismiss方法的后,PopupWindow退出,程序才会向下执行。这两种区别的表现是:AlertDialog弹出时,背景是黑色的,但是当我们点击背景,AlertDialog会消失,证明程序不仅响应AlertDialog的操作,还响应其他操作,其他程序没有被阻塞,这说明了AlertDialog是非阻塞式对话框;PopupWindow弹出时,背景没有什么变化,但是当我们点击背景的时候,程序没有响应,只允许我们操作PopupWindow,其他操作被阻塞。我们在写程序的过程中可以根据自己的需要选择使用Popupwindow或者是Dialog。
--------------------- 
作者:android_cmos 
来源:CSDN 
原文:https://blog.csdn.net/android_cmos/article/details/51223776 
版权声明:本文为博主原创文章,转载请附上博文链接!