为何PopupWindow一定要设置Background才能实现点击其他地方自动消失的效果

1150阅读 0评论2015-07-28 cjxqhhh
分类:Android平台

    好久没写博客了,来一篇有问题搞不懂就要看!源!码!系列
    
之前一直搞不懂为什么PopupWindow一定要设置Background才能实现点击其他地方消失的效果,后来在老师的带领下看了下源码,豁然开朗(虽然还有些地方搞不懂)。

PopupWindow类里有一个方法叫preparePopup(),对mBackground做了判断,若其不为空,则将mContentView嵌入到一个PopupViewContainer中。否则不执行此操作。具体代码如下:

点击(此处)折叠或打开

  1. /**
  2.      * <p>Prepare the popup by embedding in into a new ViewGroup if the
  3.      * background drawable is not null. If embedding is required, the layout
  4.      * parameters' height is modified to take into account the background's
  5.      * padding.</p>
  6.      *
  7.      * @param p the layout parameters of the popup's content view
  8.      */
  9.     private void preparePopup(WindowManager.LayoutParams p) {
  10.         if (mContentView == null || mContext == null || mWindowManager == null) {
  11.             throw new IllegalStateException("You must specify a valid content view by "
  12.                     + "calling setContentView() before attempting to show the popup.");
  13.         }

  14.         if (mBackground != null) {
  15.             final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
  16.             int height = ViewGroup.LayoutParams.MATCH_PARENT;
  17.             if (layoutParams != null &&
  18.                     layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
  19.                 height = ViewGroup.LayoutParams.WRAP_CONTENT;
  20.             }

  21.             // when a background is available, we embed the content view
  22.             // within another view that owns the background drawable
  23.             PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
  24.             PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
  25.                     ViewGroup.LayoutParams.MATCH_PARENT, height
  26.             );
  27.             popupViewContainer.setBackground(mBackground);
  28.             popupViewContainer.addView(mContentView, listParams);

  29.             mPopupView = popupViewContainer;
  30.         } else {
  31.             mPopupView = mContentView;
  32.         }

  33.         mPopupView.setElevation(mElevation);
  34.         mPopupViewInitialLayoutDirectionInherited =
  35.                 (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
  36.         mPopupWidth = p.width;
  37.         mPopupHeight = p.height;
  38.     }

再看下PopupViewContainer的代码:


它里面注册了Touch事件,这下就大概明白了。如果我们不设置background的话,mContentView就不会被放入PopupViewContainer, 自然响应不了触摸事件,也就不会消失了。具体还是看代码吧:


所以说,源码才是王道。但我搞不懂的地方是,为啥一定要设置了背景才把mContentView加到PopupViewContainer中,有了解的朋友们请指教。

上一篇:安卓Broadcast Receiver组件安全相关
下一篇:没有了