最近做項目的時候,要實現一個浮動窗口的效果,而浮動窗口的使用主要是一個WindowManager。先上效果圖:
下面介紹下它的用法
1、WindowManager介紹
全 部Android的窗口機制是基於一個叫做WindowManager實現,這個接口可以添加view到屏幕,也可以從屏幕刪除view。它面向的對象一 端是屏幕,另一端就是View,直接忽視我們以前的Activity或者Dialog之類的元素。其實我們的Activity或者Diolog底層的實現 也是經過WindowManager,WindowManager是全局的,整個系統只有一個WindowManager。它是顯示View的最底層了。WindowManager主要用來管理窗口的一些狀態、屬性、view增加、刪除、更新、窗口順序、消息收集和處理等。通過Context.getSystemService(Context.WINDOW_SERVICE)的方式可以獲得WindowManager的實例.WindowManager繼承自ViewManager,里面涉及到窗口管理的三個重要方法,分別是
- addView();
- updateViewLayout();
- removeView();
在WindowManager中還有一個重要的靜態類LayoutParams。通過它可以設置和獲得當前窗口的一些屬性。我 們先來看看addView()方法,在addView中,會利用LayoutParams獲得window的View屬性,並為每個window創 ViewRoot,ViewRoot是View和WindowManager之間的橋梁,真正把View傳遞給WindowManager的是通過 ViewRoot的setView()方法,ViewRoot實現了View和WindowManager之間的消息傳遞。在將主窗口添加到 WindowManger時,它首先會建立一個代理對象:
wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)
並且打開會話(IWindowSession),之后Window將通過該會話與WindowManager建立聯系。
2、使用WindowManager實現浮動窗口的創建
/** * 創建懸浮窗 */ private void createFloatView() {
//加載xml布局 myLayout=View.inflate(this, R.layout.window, null); btn_floatView=(Button) myLayout.findViewById(R.id.btn_win_call); btn_floatView2=(Button) myLayout.findViewById(R.id.btn_call_shouchang); btn_floatView3=(Button) myLayout.findViewById(R.id.btn_call_what);
btn_floatView.setOnClickListener(new OnClickListener() {
public void onClick(View v) { Toast.makeText(Floating_windowActivity.this, "你點擊了撥打電話", Toast.LENGTH_SHORT).show(); System.out.println("你點擊了撥打電話");
} }); btn_floatView2.setOnClickListener(new OnClickListener() {
public void onClick(View v) { Toast.makeText(Floating_windowActivity.this, "你點擊了收藏", Toast.LENGTH_SHORT).show(); System.out.println("你點擊了收藏");
} }); btn_floatView3.setOnClickListener(new OnClickListener() {
public void onClick(View v) { Toast.makeText(Floating_windowActivity.this, "你點擊了什么", Toast.LENGTH_SHORT).show(); System.out.println("你點擊了什么");
} });
wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); params = new WindowManager.LayoutParams();
// 設置window type /* * 如果設置為params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么優先級會降低一些, * 即拉下通知欄不可見 */ params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
params.format = PixelFormat.RGBX_8888; // 設置圖片格式,效果為背景透明(RGBA_8888)
// 設置Window flag /* * 下面的flags屬性的效果形同“鎖定”。 懸浮窗不可觸摸,不接受任何事件,同時不影響后面的事件響應。 * wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL | * LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE; */ params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
// 設置懸浮窗的長得寬 params.width = LayoutParams.WRAP_CONTENT; params.height = LayoutParams.WRAP_CONTENT; //設置懸浮窗的位置 params.x=500;
wm.addView(myLayout, params); } |
我們可以看出懸浮窗的添加,使用的是addView()的方法,將一個view添加到WindowManager里面去,同時如果我們需要刪除這個懸浮窗,那么就只需要調用removeView()的方法即可。
3、浮動窗口的xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >
<Button android:id="@+id/btn_win_call" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="撥打電話" />
<Button android:id="@+id/btn_call_shouchang" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="點擊收藏" /> <Button android:id="@+id/btn_call_what" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="還有什么" />
</LinearLayout> |
4、注意事項
一定要在AndroidManifest.xml添加
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
原創博文,轉載請標明出處:http://www.cnblogs.com/jarvis2014/p/3670958.html
附上Demo源代碼地址: 點擊下載Demo