zoukankan      html  css  js  c++  java
  • 自定义PopupWindow

    PopupWindow,一个弹出窗口控件,可以用来显示任意View,而且会浮动在当前activity的顶部

    自定义PopupWindow。

    1.extends PopupWindow

    2.构造方法中可以进行一些属性设置


    setContentView(View convertView); //设置popupWindow显示的View

    getContentView(); //获取popupWindow显示的view

    setWidth(mWith); //设置popupWindow的宽度

    setHeight(mHeight); //设置popupWindow的高度

    设置宽高,也可以在构造方法那里指定好宽高, 除了可以写具体的值,还可以用WRAP_CONTENT或MATCH_PARENT, popupWindow的width和height属性直接和第一层View相对应。

    setAnimationStyle(R.style.PopupAnimation); //设置弹出动画


    setFocusable(true);

    设置焦点,PopupWindow弹出后,所有的触屏和物理按键都由PopupWindows 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)。 比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下。

    而setFocusable(false); //PopUpWindow只是一个浮现在当前界面上的view而已,不影响当前界面的任何操作,是一个没有存在感的东西

    一般情况下setFocusable(true);


    setTouchable(true); // 设置popupwindow可点击


    要让点击PopupWindow之外的地方PopupWindow消失:

    1.setOutsideTouchable(true);

    2.调用setBackgroundDrawable(new BitmapDrawable()); 设置背景,为了不影响样式,这个背景是空的。

    除此之外,还可以这样写,setBackgroundDrawable(new ColorDrawable(0x00000000));背景不空,但是完全透明

    经过实际检验,只要设置了背景,不管有没有设置setOutsideTouchable(true);即使设置了setOutsideTouchable(false);一样能够实现点击PopupWindow之外的地方PopupWindow消失,有点奇葩,不过为了保险起见,还是加上setOutsideTouchable(true);比较好。


    PopupWindow还有一个方法,也是用来设置点击PopupWindow外部使得PopupWindow消失的,不过仅仅是实现这个方法是不行的,一样要设置背景才起作用。可是当设置了背景的时候,下面这个方法不管有没有用都能够实现点击PopupWindow外部使得PopupWindow消失,也是够醉。

    setTouchInterceptor(new OnTouchListener() 
            {
                @Override
                public boolean onTouch(View v, MotionEvent event) 
                {
                    if(event.getAction()==MotionEvent.ACTION_OUTSIDE)
                    {
                        dismiss();
                        return true;
                    }
                    return false;
                }
            });

    设置PopupWindow的弹出位置

    popupWindow = new SelectPicPopupWindow(参数);

    popupWindow.showAtLocation(findViewById(R.id.settings_layout),
         Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);

     //在这里findViewById(R.id.settings_layout)是当前界面的id。


     

    设置了PopupWindow的background,点击Back键或者点击弹窗的外部区域,弹窗就会dismiss.相反,如果不设置PopupWindow的background,那么点击back键和点击弹窗的外部区域,弹窗是不会消失的.

    如果我想要一个效果,点击外部区域,弹窗不消失,但是点击事件会向下面的activity传递,比如下面是一个WebView,我想点击里面的链接等.

       /**
         * 点击外部区域,弹窗不消失,但是点击事件会向下面的activity传递,要给Window设置一个Flag,
        * WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
        * 看了源码,这个Flag的设置与否是由一个叫mNotTouchModal的字段控制,但是设置该字段的set方法被标记为@hide。
        * 所以要通过反射的方法调用:
         * Set whether this window is touch modal or if outside touches will be sent
         * to
         * other windows behind it.
         *
         */
        public static void setPopupWindowTouchModal(PopupWindow popupWindow,
                boolean touchModal) {
            if (null == popupWindow) {
                return;
            }
            Method method;
            try {
    
                method = PopupWindow.class.getDeclaredMethod("setTouchModal",
                        boolean.class);
                method.setAccessible(true);
                method.invoke(popupWindow, touchModal);
    
            }
            catch (Exception e) {
                e.printStackTrace();
            }
    
        }

     

    然后调用setPopupWindowTouchModal(popupWindow, false);就可以了。

     


     不过还有要注意的是:

    1.设置了setHeight();假如设置的高度小于屏幕的高,那么透明的那一部分是不属于PopupWindow的。

    2.设置setContentView(View v);由于v里面的组件在布局文件里并没有占满整个屏幕,例如只是放在了底部,使得弹出PopupWindow上部分出现了透明,这个透明部分还是属于PopupWindow的,那么要想做到点击透明部分使得PopupWindow消失,又该怎么做呢?

    这个也不难,答案如下:

    /**
      *public class SelectPicPopupWindow extends PopupWindow
      */
    private View popupView;
    
    popupView = inflater.inflate(R.layout.popup_window, null);
    this.setContentView(popupView);
    
    popupView.setOnTouchListener(new OnTouchListener() {
                @SuppressLint("ClickableViewAccessibility")
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int height = popupView.findViewById(R.id.popup_layout).getHeight();
                    int y = (int) event.getY();
                    if(event.getAction() == MotionEvent.ACTION_UP){
                        if(y<height) {
                            dismiss();
                        }
                    }
                    return true;
                }
            });

    转载请标明出处:

    https://www.cnblogs.com/tangZH/p/6119483.html

    http://77blogs.com/?p=29

  • 相关阅读:
    Flush the AOS cache from code
    EntityConnectionStringBuilder 构造EF连接字符串
    AX中文转拼音
    AX2012 AOT中Web部署显示二级以上菜单
    clearCompanyCache
    AX2009 打印到PDF优化
    AX ODBC读取其他SQL数据库服务器数据
    AX2009报表打印固定长度Barcode条码
    Create Product Variant
    Rename AOT Object
  • 原文地址:https://www.cnblogs.com/tangZH/p/6119483.html
Copyright © 2011-2022 走看看