Android WindowManager實現懸浮窗效果 (一)——與當前Activity綁定

來源:互聯網
上載者:User

標籤:

  最近有學生做畢業設計,想使用懸浮窗這種效果,其實很簡單,我們可以通過系統服務WindowManager來實現此功能,本章我們來實驗一下在當前Activity之上建立一個懸浮的view。

第一步:認識WindowManager

l  這個介面用於與 window manager (視窗管理器, 應用程式框架層) 進行互動。

l  通過getSystemService(Context.WINDOW_SERVICE)可以擷取到WM的執行個體.

l  繼承關係

       public interface WindowManager implements ViewManager

l  所屬包

       android.view.WindowManager

l  重要方法

addView()             添加view

removeView()          刪除view

updateViewLayout ()     改變view的參數

  Window Manager Service 是全域的,是唯一的。 它將使用者的操作,翻譯成為指令,發送給呈現在介面上的各個Window。Activity會將頂級的控制項註冊到 Window Manager 中,當使用者真是觸碰螢幕或鍵盤的時候,Window Manager就會通知到,而當控制項有一些請求產生,也會經由ViewParent送回到Window Manager中。從而完成整個通訊流程

 

第二步:重寫ImageView 的onTouchEvent方法

  上一步我們知道了 WindowManager可以添加,刪除,改變view,那麼想要實現懸浮窗的拖動效果我們就要擷取ImageView的座標位置。

l  擷取相對螢幕的座標,即以螢幕左上方為原點

       float  x = event.getRawX();

       float  y = event.getRawY()-25;   //25是系統狀態列的高度

l  通過WindowManager.LayoutParams wmParams 設定 x ,y

wmParams.x=(int)( x-mTouchStartX);

        wmParams.y=(int) (y-mTouchStartY);

l  再通過updateViewLayout()方法設定懸浮窗的當前位置

第三步:加入許可權

  在AndroidManifest.xml中加入如下的許可權:

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

效果如下:

重要代碼 :   建立 MyApplication

import android.app.Application;import android.view.WindowManager;public class MyApplication extends Application {    /**     * 建立全域變數     * 注意在AndroidManifest.xml中的Application節點添加android:name=".MyApplication"屬性     *     */    private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();    public WindowManager.LayoutParams getMywmParams(){        return wmParams;    }}

建立自訂View 繼承ImageView

import android.content.Context;import android.util.Log;import android.view.MotionEvent;import android.view.WindowManager;import android.widget.ImageView;public class MyFloatView extends ImageView {    private float mTouchStartX;    private float mTouchStartY;    private float x;    private float y;    private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);    //此wmParams為擷取的全域變數,用以儲存懸浮視窗的屬性    private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams();    public MyFloatView(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    @Override    public boolean onTouchEvent(MotionEvent event) {        //擷取相對螢幕的座標,即以螢幕左上方為原點        x = event.getRawX();        y = event.getRawY()-25;   //25是系統狀態列的高度        Log.i("currP", "currX"+x+"====currY"+y);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                //擷取相對View的座標,即以此View左上方為原點                mTouchStartX =  event.getX();                mTouchStartY =  event.getY();                break;            case MotionEvent.ACTION_MOVE:                updateViewPosition();                break;            case MotionEvent.ACTION_UP:                updateViewPosition();                mTouchStartX=mTouchStartY=0;                break;        }        return true;    }    private void updateViewPosition(){        //更新浮動視窗位置參數        wmParams.x=(int)( x-mTouchStartX);        wmParams.y=(int) (y-mTouchStartY);        wm.updateViewLayout(this, wmParams);    }}

建立Activity

import android.app.Activity;import android.content.Context;import android.graphics.PixelFormat;import android.os.Bundle;import android.util.Log;import android.view.Gravity;import android.view.View;import android.view.WindowManager;import android.view.View.OnClickListener;import android.view.WindowManager.LayoutParams;public class MyFloatViewActivity extends Activity{    private WindowManager wm=null;    private WindowManager.LayoutParams wmParams=null;    private MyFloatView myFV=null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        //建立懸浮視窗        createView();    }    private void createView(){        myFV=new MyFloatView(getApplicationContext());        myFV.setImageResource(R.drawable.angry_birds);        //擷取WindowManager        wm=(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);        //設定LayoutParams(全域變數)相關參數        wmParams = ((MyApplication)getApplication()).getMywmParams();        wmParams.type=LayoutParams.TYPE_PHONE;   //設定window type        wmParams.format=PixelFormat.RGBA_8888;   //設定圖片格式,效果為背景透明        //設定Window flag        wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL                | LayoutParams.FLAG_NOT_FOCUSABLE;        wmParams.gravity=Gravity.LEFT|Gravity.TOP;   //調整懸浮視窗至左上方        //以螢幕左上方為原點,設定x、y初始值        wmParams.x=0;        wmParams.y=0;        //設定懸浮視窗長寬資料        wmParams.width=40;        wmParams.height=40;        //顯示myFloatView映像        wm.addView(myFV, wmParams);    }    @Override    public void onDestroy(){        super.onDestroy();        //在程式退出(Activity銷毀)時銷毀懸浮視窗        wm.removeView(myFV);    }}

l  最後在程式安裝時修改手機裡的程式許可權-》懸浮窗可用

 

傑瑞教育
出處:http://www.cnblogs.com/jerehedu/ 
著作權聲明:本文著作權歸煙台傑瑞教育科技有限公司和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。
技術諮詢: 

Android WindowManager實現懸浮窗效果 (一)——與當前Activity綁定

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.