Window表示是一個窗口的概念贸典,它是一個抽象類凤粗,具體的實現(xiàn)是PhoneWindow纠炮,創(chuàng)建一個Window是很簡單的事,只需要通過WindowManager就可以完成杨幼,Android中所有的視圖都是通過Window來實現(xiàn)的撇簿,比如Activity,Toast和Dialog差购,當(dāng)我們需要做懸浮窗口的需求的時候四瘫,就需要用到它們,下面來看看
Window和WindowManager
先來看看如何通過WindowManager添加一個Window
Button button=new Button(this);
WindowManager wmManager=(WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams lp=new WindowManager.LayoutParams();
lp.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
lp.gravity= Gravity.TOP;
lp.x=100;
lp.y=300;
wmManager.addView(button,lp);
代碼很簡單欲逃,創(chuàng)建一個view之后就可以用WindowManager的addView方法引用到屏幕x=100和y=300坐標(biāo)上了找蜜,其實WindowManager常用的方法就是添加view,更新view和刪除view稳析,也就是addView洗做,updateViewLayout和removeView
(一)Flags
參數(shù)表示W(wǎng)indow的屬性弓叛,它有很多選項,通過這些選項可以控制Window的顯示特性
FLAG_NOT_FOCUSABLE
表示window不需要獲取焦點诚纸,這個比較好理解撰筷,設(shè)置了這個屬性后,window將不會獲取到焦點
FLAG_NOT_TOUCH_MODAL
在此模式下畦徘,系統(tǒng)會將當(dāng)前Window區(qū)域以外的單擊事件傳遞給底層的Window毕籽,當(dāng)前Window區(qū)域以內(nèi)的單擊事件則自己處理。 一般來說都需要開啟此標(biāo)記井辆,否則其他Window將無法收到單擊事件
FLAG_SHOW_WHEN_LOCKED
此模式可以讓W(xué)indow顯示在鎖屏的界面上
(二)Type
Type代表的是window的類型关筒,共有3種,分別是:應(yīng)用window杯缺,子window和系統(tǒng)window蒸播,應(yīng)用window對應(yīng)一個Activity,子window需要依附在父window上夺谁,不能單獨存在廉赔,比如dialog肉微,系統(tǒng)window就是系統(tǒng)提供的匾鸥,比如toast,狀態(tài)欄等碉纳,這些在使用的時候需要聲明權(quán)限勿负,否則報錯,每一類型的window都有一個范圍
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
應(yīng)用window(1-99):Activity劳曹,F(xiàn)ragment等
子window(1000-1999):Dialog奴愉,Popupwindow等
系統(tǒng)window(2000-2999):Toast,狀態(tài)欄铁孵,通知等
層級范圍對應(yīng)這WindowManager.LayoutParams的type參數(shù)锭硼,層級大的會覆蓋在層級小的Window上面。所以系統(tǒng)層級是最大的蜕劝,系統(tǒng)層級一般選用TYPE_SYSTEM_ERROR或者TYPE_SYSTEM_OVERLAY
上面提到了windowManger對view的操作有addView檀头,updateViewLayout和removeView,這3個方法定義在ViewManager中岖沛,而WindowManger是繼承了ViewManager暑始,我們來看看這三個方法:
public interface ViewManager
{
/**
* Assign the passed LayoutParams to the passed View and add the view to the window.
* <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming
* errors, such as adding a second view to a window without removing the first view.
* <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a
* secondary {@link Display} and the specified display can't be found
* (see {@link android.app.Presentation}).
* @param view The view to be added to this window.
* @param params The LayoutParams to assign to view.
*/
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
這3個功能足夠我們平常用了,其實WindowManager操作Window的過程就好像Window操作view的過程婴削,我們有時候看到那些可以拖動Window的效果廊镜,其實就可以通過updateViewLayout來實現(xiàn),設(shè)置view的onTouchListener唉俗,然后根據(jù)手指拖動來改變x和y的值嗤朴,不斷更新view就可以了
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getRawX();
int y= (int) event.getRawY();
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
lp.x=x;
lp.y=y;
wmManager.updateViewLayout(button,lp);
break;
}
return false;
}
});
好了配椭,這篇文章到這就結(jié)束了