自定義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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM