Android WindowManager的使用
经常,我们看到在桌面上可移动的悬浮窗,这种场景还是很多的, 像流量统计,桌面歌词等,安全软件的清理小部件
这种小部件主要是通过 WindowManager ; WindowManager.LayoutParams 这两个类来实现
调用 WindowManager 的addView(view, params)方法来添加一个悬浮窗.updateViewLayout(view,params)来更新悬浮窗参数.removeView(view)用于移除悬浮窗
WindowManager.LayoutParams 主要是用来提供参数的
其中的参数有type: 悬浮窗的类型,通常设置为2002, 即在所有程序之上.状态栏之下
flags :用于确定悬浮窗的行为
gravity : 用于确定悬浮窗的对其方式
x: 悬浮窗的横向坐标
y: 悬浮窗的纵向坐标
width: 悬浮窗的宽度
height : 悬浮窗的高度
创建悬浮窗需要添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
悬浮窗布局
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/small_window_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bg" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="拖拽移动.." android:textSize="20sp" /> </LinearLayout>
新建一个类继承Application,Application就是应用的入口点,写在这里,就是程序一运行,就会出来
同时,需要在清单文件的Application结点上配置名称
package com.example.windowmanagerdemo; import android.annotation.SuppressLint; import android.app.Application; import android.content.Context; import android.graphics.PixelFormat; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.Toast; public class MAppliction extends Application { WindowManager mWM; WindowManager.LayoutParams mParams; @Override public void onCreate() { super.onCreate(); mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); mParams = new WindowManager.LayoutParams(); final View mwm = LayoutInflater.from(this).inflate(R.layout.mwm, null); mwm.setOnTouchListener(new OnTouchListener() { float lastX, lastY; @SuppressLint("NewApi") @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getX(); lastY = event.getY(); break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); mParams.x += (int) (moveX - lastX); mParams.y += (int) (moveY - lastY); mWM.updateViewLayout(mwm, mParams); break; default: break; } return true; } }); mParams.type = LayoutParams.TYPE_PHONE; mParams.format = PixelFormat.RGBA_8888; mParams.width = 50; mParams.height = 30; mWM.addView(mwm, mParams); mwm.setOnTouchListener(new onDoubleClick()); } public int count; class onDoubleClick implements View.OnTouchListener { private long firClick; private long secClick; @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEvent.ACTION_DOWN == event.getAction()) { count++; if (count == 1) { firClick = System.currentTimeMillis(); } else if (count == 2) { secClick = System.currentTimeMillis(); if (secClick - firClick < 1000) { // 双击事件 mWM.removeView(v); Toast.makeText(getApplicationContext(), "关闭悬浮窗", Toast.LENGTH_SHORT).show(); } count = 0; firClick = 0; secClick = 0; } } return true; } } }