Popupwindow的showAsDropDown方法详解

PopupWindow
在开发项 目中,经常会用popupwindow来弹出一个供选择操作的窗口,作为一个弹出菜单一样被使用。一般这时候设置popupwindow的位置时都是设置在点击的view下面弹出展示。比如点击一个button,只要使用showAsDropDown(btn)方法,popupwindow就会贴着button的底部显示出来。如下图一样:



基本的是代码:

main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
<RelativeLayout

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.xiaxiao.showpopupwindow.MainActivity">

    <Button
        android:id="@+id/btn_main"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:text="Hello World!" />
</RelativeLayout>
</ScrollView>


popupwindow加载的view:

popup_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.xiaxiao.showpopupwindow2.MainActivity">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#dd6666"
        android:gravity="center"
        android:text="Hello World!" />
    <ImageView android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ic_launcher"
        android:background="#aaaaaa"
        android:layout_weight="1"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#dd6666"
        android:gravity="center"
        android:text="Hello  , can you see me?"/>

</LinearLayout>
点击按钮就会弹出popupwindow: showPop(showPop_btn)

按钮事件:

public void showPop(View anchor) {
        View view = View.inflate(this, R.layout.popup_view, null);
        Button btn = (Button) view.findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "how are you", Toast.LENGTH_SHORT).show();
            }
        });
        pop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        pop.setHeight(2000);
        pop.setOutsideTouchable(true);
        pop.setFocusable(true);
        pop.showAsDropDown(showPop_btn);
    }



showAsDropDown

一般情况下使用这个方法都没有什么问题,但是当popupwindow的height过大的时候,根据官方对showAsDropDown方法的解释,popupwindow的位置就会出现”理所当然的错位”,即并不是按照我们预期的那样呈现出来了。同时,安卓发布了7.0 version24.。和版本23相比,同样的设置,23  ,24 的处理也有一些不一样了。

首先,我们看一下官方对showAsDropDown方法的解释:

Display the content view in a popup window anchored to the bottom-left
corner of the anchor view. If there is not enough room on screen to show
the popup in its entirety, this method tries to find a parent scroll
view to scroll. If no parent scroll view can be scrolled, the
bottom-left corner of the popup is pinned at the top left corner of the
anchor view.

以一个button为例,这段解释的大义是:popupwindow会在button的下面 贴着button的底部展示出来,但是当button底部到屏幕底部的高度
小于popupwindow的高度时,popupwindow就会找button的父view作为参考点,如果也没有符合的parent view ,popupwindow就会使自己的底部
贴button的顶部展示。以上就是api规定的showAsDropDown方法的行为。

区别:
version6.x 23
但是在安卓6.0 version23上,系统并没有遵循这个规则,可以说系统根本没有考虑button之外的其他view,这也是24和23版本的区别所在。popupwindow的高度不管是多大,
永远是基于button底部展示的。
在version23上:第一次我们设置popupwindow加载的view的高度时match_parent,其中的imageview自动扩展高度,同时设置popupwindow为match_parent:
pop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
这时弹出popupwindow的样子是这样的:

可以看出,系统首先考虑的是button到屏幕底部的高度大小是不是能装得下popupwindow,能的话,直接显示,不能的话则考虑是否可以对加载的view处理,使之能适应剩下的高度空间。
发现并不能装的下高度设置为match_parent的popupwindow,
于是在imageview高度可变的允许下,自动压缩了popupwindow的高度,使popupwindow填充了button底部到屏幕底部的高度空间,显示是正常的。

然后,我们设置popupwindow的高度为一个比较大的数值,明显超过手机屏幕高度的:2000
  pop.setHeight(2000);
这时候,显示效果是这样的:

可以看出来,popupwindow没有完全展示出来。但是依然是基于button 底部的。因为此时popupwindow高度是固定设置的了,
无法改变,由于version23又不会真正按照api要求来,所以popupwindow就显示的不完全了。


version7.0 24

在version24,7.0系统上,则会首先考虑加载的view的大小,然后看剩余的空间是否足够大,如果不足够大,则会执行api规定的showAsDropDown方法的行为,去寻找符合条件的父view。
也就是说 7.0系统不会出现这种现象:屏幕上还有未被popupwindow占用的空间,但是popupwindow显示的不完整。
所以这时候设置popupwindow高度为match_parent 时,button已经不符合定位条件了,这时候显示的效果是这样的:
《补图》



以上。

如有不对的地方,请指正。^_^ ^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值