使用WindowManager實現Android懸浮窗

ShaRoyer 8年前發布 | 7K 次閱讀 安卓開發 Android開發 移動開發

在做項目的時候有時候會用到windowmanager,下面將一些核心代碼貼出來供參考。

效果圖

windowmanager.png

聲明權限

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

控制類

package com.test.window;

import java.lang.reflect.Method;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

public class ControlService extends Service {
    public static final String TAG = ControlService.class.getSimpleName();
    LayoutInflater mLayoutInflater;
    public static Context mContext;
    Test testView;
    Test2 testView2;
    public static int screenWidth = 0, screenHeight = 0;
    public static WindowManager mWindowManager;
    public static Window mWindow;
    static ColorDrawable colorDrawable = new ColorDrawable();
    public static final int CHANGE_VIEW_EVENT = 0X30;// 界面轉換事件標志
    public static final int LIVE_TV = 0x39;// 主界面
    public static final int TEST_VIEW = 13;// 第一個界面
    public static final int TEST_VIEW2 = 14;// 第二個界面
    public static Handler myHandler;

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case CHANGE_VIEW_EVENT:
                changeView(msg);
                break;
            }
        }
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String event = intent.getStringExtra(Const.START_SERVICE_HEAD);
            if (event == null) {
                return super.onStartCommand(intent, flags, startId);
            } else if (Const.START_DTV_EVENT.equals(event)) {
                changeViewEvent(LIVE_TV, TEST_VIEW, null);
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        myHandler = new MyHandler();
        mContext = this;
        mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metric = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels; // 屏幕寬度(像素)
        int height = metric.heightPixels; // 屏幕高度(像素)
        screenHeight = height;
        screenWidth = width;
        String POLICYMANAGER_CLASS_NAME = "com.android.internal.policy.PolicyManager";
        try {
            Class policyManagerClass = Class.forName(POLICYMANAGER_CLASS_NAME);
            Class[] parameterTypes = { Context.class };
            Method method = policyManagerClass.getMethod("makeNewWindow", parameterTypes);
            mWindow = (Window) method.invoke(null, mContext);
            mWindow.setFormat(PixelFormat.TRANSLUCENT);
            mWindow.requestFeature(Window.FEATURE_NO_TITLE);
            mWindow.setWindowManager(mWindowManager, null, null);
            colorDrawable.setAlpha(0);
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        testView = new Test(mLayoutInflater, mContext);
        testView2 = new Test2(mLayoutInflater, mContext);
    }

    private void changeView(Message msg) {
        int toView = msg.arg2;
        switch (toView) {
        case TEST_VIEW:
            testView.showView();
            break;
        case TEST_VIEW2:
            testView2.showView();
            break;
        case LIVE_TV:
            removeContentView();
            break;
        }
    }

    public static void changeViewEvent(int ar1, int ar2, Object obj) {
        Message msg = myHandler.obtainMessage(CHANGE_VIEW_EVENT, ar1, ar2, obj);
        myHandler.sendMessage(msg);
    }

    static Handler handler = new Handler();

    public static void setContentView(View view, LayoutParams params) {
        try {
            mWindowManager.removeView(mWindow.getDecorView());
        } catch (Exception e) {
            e.printStackTrace();
        }
        mWindow.setBackgroundDrawable(colorDrawable);
        mWindow.setContentView(view, params);
        mWindowManager.addView(mWindow.getDecorView(), params);
    }

    public static void removeContentView() {
        try {
            mWindowManager.removeView(mWindow.getDecorView());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

界面展示

package com.test.window;

import com.htv.daoshi.R;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

/**
 * Created by Think on 2016/9/19.
 */
public class Test implements View.OnKeyListener, View.OnClickListener {
    public static final String TAG = Test.class.getSimpleName();
    Context context;
    View myRoot;
    Button btnSkip,btnClose;
    WindowManager.LayoutParams mParams;
    int x, y, width, height;

    public Test(LayoutInflater inflater, Context c) {
        context = c;
        width = ControlService.screenWidth;
        height = ControlService.screenHeight * 264 / 720;
        x = 0;
        y = 0;
        mParams = new WindowManager.LayoutParams();
        mParams.width = width;
        mParams.height = height;
        mParams.x = x;
        mParams.y = y;
        mParams.gravity = Gravity.RIGHT | Gravity.BOTTOM;
        mParams.format = PixelFormat.TRANSLUCENT;
        mParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        myRoot = (View) inflater.inflate(R.layout.test, null);
        btnSkip = (Button) myRoot.findViewById(R.id.btn_skip);
        btnClose = (Button) myRoot.findViewById(R.id.btn_close);
        btnSkip.setOnClickListener(this);
        btnSkip.setOnKeyListener(this);
        btnClose.setOnClickListener(this);
        btnClose.setOnKeyListener(this);
    }
    /**
     * 顯示view
     */
    public void showView() {
        ControlService.setContentView(myRoot, mParams);
    }
    /**
     * 關閉view
     */
    public void closeView() {
        ControlService.removeContentView();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_skip://跳轉到第二個windowmanager
            ControlService.changeViewEvent(ControlService.TEST_VIEW, ControlService.TEST_VIEW2, null);
            break;
        case R.id.btn_close://關閉
            closeView();
            break;
        }
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            closeView();
            return true;
        }
        return false;
    }
}

 

 

來自:http://www.jianshu.com/p/29b385e53feb

 

 本文由用戶 ShaRoyer 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!