众所周知,像qq音乐,当退出qq音乐app时,歌词会在桌面上显示,这里可以用悬浮窗实现。
用一个很简单的TextView来实现悬浮窗效果。
点击退出后:
1、需要添加的权限
<uses-permission
android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2、activity_main.xml(布局文件)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ws.day1025_01.MainActivity">
<--以一个TextView为例的悬浮窗-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:text="123456"
/>
</RelativeLayout>
3、MainActivity.java
importandroid.content.Context;
importandroid.content.Intent;
importandroid.graphics.PixelFormat;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.util.TypedValue;
importandroid.view.Gravity;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.WindowManager;
importandroid.widget.TextView;
public class MainActivity extends AppCompatActivity {
//WindowManager是管理Window的管理员
//我们想要把一个view悬浮在window上,就要使用windowmanager来操作window
private static WindowManager windowManager;
//申请一个布局参数成员
private WindowManager.LayoutParams lp;
//悬浮窗view,现在我们简单用一个textView来做
private static TextView txtInfo;
private Context applicationContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
applicationContext= getApplication();
//windowManager的实例化,上下文对象get到
if(windowManager==null){
windowManager= (WindowManager)applicationContext.getSystemService(WINDOW_SERVICE);
}
if(txtInfo!=null){//删除
windowManager.removeView(txtInfo);
txtInfo=null;
}else{//添加
//创建一个textView
txtInfo=newTextView(applicationContext);
txtInfo.setText("12345678");
txtInfo.setTextSize(TypedValue.COMPLEX_UNIT_SP,40);
//实例化布局参数
lp=newWindowManager.LayoutParams();
//设置布局参数
//WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
//TYPE_SYSTEM_OVERLAY意思是系统覆盖物,可以实现系统桌面的悬浮 2000+6=2006
//TYPE_SYSTEM_ALERT可以控制移动 2000+3=2003
//2006|2003=(2000+6)|(2000+3) = 2000|2000+6|3 = 2007
// lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
lp.type= WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
//设置flags
//FLAG_NOT_FOCUSABLE不获取焦点
//FLAG_FULLSCREEN使得View可以全屏拖拽
lp.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_FULLSCREEN;
lp.gravity= Gravity.LEFT|Gravity.TOP;
//设置初始位置
lp.x=10;
lp.y=50;
//设置宽高包裹内容
lp.width= WindowManager.LayoutParams.WRAP_CONTENT;
lp.height= WindowManager.LayoutParams.WRAP_CONTENT;
//设置悬浮窗会显示背景,也就是半透明
lp.format= PixelFormat.TRANSPARENT;
//windowManager添加一个view到window上
//要带着布局参数添加
windowManager.addView(txtInfo,lp);
//设置悬浮窗的点击事件的监听
txtInfo.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
Intent intent =newIntent(applicationContext,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
applicationContext.startActivity(intent);
}
});
//设置textView的移动处理
txtInfo.setOnTouchListener(newView.OnTouchListener() {
private WindowManager.LayoutParams mlp=lp;
//用于记录上一次的位置
private intlastX,lastY;
//记录最后一次按下的时间,用于在UP的时候判断是否小于300毫秒
private longlastDownTime;
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean ret =false;
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_DOWN:
lastDownTime= System.currentTimeMillis();
//获取手指的动作的坐标是用getX()
//使用Rax()可以获取相对于手机界面的坐标
lastX= (int) event.getRawX();
lastY= (int) event.getRawY();
ret =true;
break;
case MotionEvent.ACTION_MOVE:
float x = event.getRawX();
float y = event.getRawY();
//计算和last的差量
int ix = (int) (x-lastX);
int iy = (int) (y-lastY);
mlp.x+= ix;
mlp.y+= iy;
lastX= (int) x;
lastY= (int) y;
//更新view
windowManager.updateViewLayout(txtInfo,mlp);
break;
case MotionEvent.ACTION_UP://抬起
long ct = System.currentTimeMillis();
if(ct-lastDownTime<=300){//触发点击
txtInfo.performClick();
}
break;
}
return ret;
}
});
}
}
//如果同一个应用同时调用了onClickListener和onTouchListener,只会调用onTouchListener
}