簡易的可拖動的案頭懸浮窗效果Demo,拖動案頭懸浮demo

來源:互聯網
上載者:User

簡易的可拖動的案頭懸浮窗效果Demo,拖動案頭懸浮demo

首先,我們需要知道,懸浮窗分為兩種:Activity層級的懸浮窗,系統層級的懸浮窗

Activity層級的懸浮窗跟隨所屬Activity的生命週期而變化,而系統層級的懸浮窗則可以脫離Activity而存在。

 

由此可知,要實現360手機衛士那樣的懸浮窗效果,就需要使用系統層級的懸浮窗

 

下面學習實現案頭懸浮窗效果的代碼步驟:

Demo描述,懸浮窗為一個ImageView ,可以在案頭 ,任意應用,鎖屏上方任意移動

 

1、配置資訊清單檔AndroidManifest.xml 中 添加系統懸浮窗的許可權

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

 

2、開始Activity代碼的編寫

 先看成員變數:

    private WindowManager.LayoutParams lp = new WindowManager.LayoutParams();    private static WindowManager windowManager;    private static ImageView imageView;

 onCreate()方法:

擷取WindwoManager對象,該對象是系統層級的

windowManager = (WindowManager) getApplication().getSystemService(WINDOW_SERVICE);

使用WindowManager可以顯示在其他應用最上層,甚至手機案頭最上層顯示視窗。

 

3、添加一個UI空間,作為懸浮窗的內容 ,當然Demo是一個ImageView作為懸浮窗內容,實際項目中就需要用複雜View,ViewGroup來擴充功能了

     
     //注意,懸浮窗只有一個,而當開啟應用的時候才會產生懸浮窗,所以要判斷懸浮窗是否已經存在,
     if (imageView != null){ windowManager.removeView(imageView); } // 使用Application context 建立UI控制項,避免Activity銷毀導致上下文出現問題,因為現在的懸浮窗是系統層級的,不依賴與Activity存在    imageView = new ImageView(getApplicationContext()); imageView.setImageResource(R.mipmap.normal);

 

4、設定系統層級的懸浮窗的參數,保證懸浮窗懸在手機案頭上

     lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT                  |WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE                  |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
//TYPE_SYSTEM_ALERT  系統提示,它總是出現在應用程式視窗之上
//TYPE_SYSTEM_OVERLAY 系統頂層視窗。顯示在其他一切內容之上。此視窗不能獲得輸入焦點,否則影響鎖屏
// FLAG_NOT_FOCUSABLE 懸浮視窗較小時,後面的應用表徵圖由不可長按變為可長按,不設定這個flag的話,home頁的劃屏會有問題
// FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到後面的視窗

關於 WindowManager.LayoutParams 的詳解 請參考:Android中WindowManager.LayoutParams類詳解

5、懸浮窗預設顯示的位置
 lp.gravity = Gravity.LEFT|Gravity.TOP;  //顯示在螢幕左上方

 

6、懸浮窗相對5預設位置的位置差和懸浮窗寬高設定

     //顯示位置與指定位置的相對位置差        lp.x = 0;        lp.y = 0;        //懸浮窗的寬高        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;

 

7、設定懸浮窗背景透明

lp.format = PixelFormat.TRANSPARENT;

 

8、將懸浮窗添加到WindowManager對象中

 windowManager.addView(imageView,lp);

 

9.設定懸浮窗的響應事件

 這裡為移動懸浮窗操作,可以自己擴充添加點擊等響應事件

imageView.setOnTouchListener(new View.OnTouchListener() {            private float lastX; //上一次位置的X.Y座標            private float lastY;            private float nowX;  //當前移動位置的X.Y座標            private float nowY;            private float tranX; //懸浮窗移動位置的相對值            private float tranY;            @Override            public boolean onTouch(View v, MotionEvent event) {                boolean ret = false;                switch (event.getAction()){                    case MotionEvent.ACTION_DOWN:                        // 擷取按下時的X,Y座標                        lastX = event.getRawX();                        lastY = event.getRawY();                        ret = true;                        break;                    case MotionEvent.ACTION_MOVE:                        // 擷取移動時的X,Y座標                        nowX = event.getRawX();                        nowY = event.getRawY();                        // 計算XY座標位移量                        tranX = nowX - lastX;                        tranY = nowY - lastY;                        // 移動懸浮窗                        lp.x += tranX;                        lp.y += tranY;                        //更新懸浮窗位置                        windowManager.updateViewLayout(imageView,lp);                        //記錄當前座標作為下一次計算的上一次移動的位置座標                        lastX = nowX;                        lastY = nowY;                        break;                    case MotionEvent.ACTION_UP:                        break;                }                return ret;            }        });

10、擴充移除懸浮窗功能

11、:


完整代碼:
注意添加許可權!!!
1 package com.xqx.window.app; 2 3 import android.app.Activity; 4 import android.graphics.PixelFormat; 5 import android.os.Bundle; 6 import android.view.*; 7 import android.widget.ImageView; 8 9 /** 10 * 系統層級懸浮窗,可以在手機案頭上顯示的懸浮窗 11 */ 12 public class FloatWindowActivity extends Activity { 13 14 private WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 15 private static WindowManager windowManager; 16 private static ImageView imageView; 17 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_float_window); 22 23 // 1、擷取系統層級的WindowManager 24 windowManager = (WindowManager) getApplication().getSystemService(WINDOW_SERVICE); 25 26 // 判斷UI控制項是否存在,存在則移除,確保開啟任意次應用都只有一個懸浮窗 27 if (imageView != null){ 28 windowManager.removeView(imageView); 29 } 30 // 2、使用Application context 建立UI控制項,避免Activity銷毀導致上下文出現問題 31 imageView = new ImageView(getApplicationContext()); 32 imageView.setImageResource(R.mipmap.normal); 33 34 35 // 3、設定系統層級的懸浮窗的參數,保證懸浮窗懸在手機案頭上 36 // 系統層級需要指定type 屬性 37 // TYPE_SYSTEM_ALERT 允許接收事件 38 // TYPE_SYSTEM_OVERLAY 懸浮在系統上 39 // 注意資訊清單檔添加許可權 40 41 //系統提示。它總是出現在應用程式視窗之上。 42 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 43 |WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 44 45 // FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到後面的視窗 46 // FLAG_NOT_FOCUSABLE 懸浮視窗較小時,後面的應用表徵圖由不可長按變為可長按,不設定這個flag的話,home頁的劃屏會有問題 47 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 48 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 49 50 //懸浮窗預設顯示的位置 51 lp.gravity = Gravity.LEFT|Gravity.TOP; 52 //顯示位置與指定位置的相對位置差 53 lp.x = 0; 54 lp.y = 0; 55 //懸浮窗的寬高 56 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 57 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 58 59 lp.format = PixelFormat.TRANSPARENT; 60 windowManager.addView(imageView,lp); 61 62 //設定懸浮窗監聽事件 63 imageView.setOnTouchListener(new View.OnTouchListener() { 64 private float lastX; //上一次位置的X.Y座標 65 private float lastY; 66 private float nowX; //當前移動位置的X.Y座標 67 private float nowY; 68 private float tranX; //懸浮窗移動位置的相對值 69 private float tranY; 70 71 @Override 72 public boolean onTouch(View v, MotionEvent event) { 73 boolean ret = false; 74 switch (event.getAction()){ 75 case MotionEvent.ACTION_DOWN: 76 // 擷取按下時的X,Y座標 77 lastX = event.getRawX(); 78 lastY = event.getRawY(); 79 ret = true; 80 break; 81 case MotionEvent.ACTION_MOVE: 82 // 擷取移動時的X,Y座標 83 nowX = event.getRawX(); 84 nowY = event.getRawY(); 85 // 計算XY座標位移量 86 tranX = nowX - lastX; 87 tranY = nowY - lastY; 88 // 移動懸浮窗 89 lp.x += tranX; 90 lp.y += tranY; 91 //更新懸浮窗位置 92 windowManager.updateViewLayout(imageView,lp); 93 //記錄當前座標作為下一次計算的上一次移動的位置座標 94 lastX = nowX; 95 lastY = nowY; 96 break; 97 case MotionEvent.ACTION_UP: 98 break; 99 }100 return ret;101 }102 });103 }104 105 }FloatWindowActivity.java

 






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.