悬在activity之上的组件,但不影响activity的操作
如果设置在服务中,不移除的话,可以显示在任何界面
实现如图:你好
public void showAddressTip(String number) {
// TN的构造方法(参考Toast的源码)
final LayoutParams params = new WindowManager.LayoutParams();
// 设置宽高为WrapContent
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
// 半透明
params.format = PixelFormat.TRANSLUCENT;
// 类型为Toast
// TYPE_PRIORITY_PHONE 优先于通话界面权限:android.permission.SYSTEM_ALERT_WINDOW
// Android保护机制: 在通话的时候,通话界面优先级最高其他界面都不可被触摸
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON // 保持屏幕常量
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不可获取焦点
// 焦点和触摸事件没有任何关系
// |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; //客官不可摸
// 加载布局
final TextView tvAddress = (TextView) View.inflate(MyServicer.this,
R.layout.tip_address, null);
// 设置内容
tvAddress.setText(number);
tvAddress.setBackgroundResource(android.R.color.holo_green_light);
// 获取WindowManager
final WindowManager mWm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 通过WindowManager添加一个控件最终控件会显示在Window上
mWm.addView(tvAddress, params);
tvAddress.setOnTouchListener(new OnTouchListener() {
private int downX;
private int downY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test", "down");
// 获取当前点击下去的位置
downX = (int) event.getRawX();
downY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
Log.i("test", "move");
// 获取X和Y的偏移量
int moveX = (int) event.getRawX();
int moveY = (int) event.getRawY();
// 计算差值
int dx = moveX - downX;
int dy = moveY - downY;
// 在原来的基础上加上现在移动的差值
params.x = params.x + dx;
params.y = params.y + dy;
// 更新控件参数布局
mWm.updateViewLayout(tvAddress, params);
downX = moveX;
downY = moveY;
break;
case MotionEvent.ACTION_UP:
Log.i("test", "up");
break;
default:
break;
}
return false;
}
});
}