创建 service 后台启动
public class FBService extends Service {private static final String TAG = "FBService";public static final int TYPE_ADD = 0;public static final int TYPE_DEL = 1;private FloatBallManager mFBManager;@Overridepublic void onCreate() {super.onCreate();Log.d(TAG,"onCreate");mFBManager = FloatBallManager.getInstance(this);}private void showFloatBall() {Log.d(TAG,"showFloatBall");mFBManager.addBallView(); //通过mFBManager 在windowmanager添加view }@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG,"onStartCommand");showFloatBall(intent);showFloatBall();return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG,"onDestroy");}
}
通过FloatBallManager 在windowmanager 加载 悬浮球布局
public class FloatBallManager {private static final String TAG = "FloatBallManager";private FloatBallManager(Context ctx){mCtx = ctx;mWindowManager = (WindowManager) mCtx.getSystemService(Context.WINDOW_SERVICE);//获取WindowManager }public static FloatBallManager getInstance(Context ctx){if(instance == null){synchronized(FloatBallManager.class){if(instance == null){instance = new FloatBallManager(ctx);}}}return instance;}public void addBallView() {if (mFloatBallView == null) {//获取 整个手机的宽度和高度DisplayMetrics dm = new DisplayMetrics();mWindowManager.getDefaultDisplay().getMetrics(dm);mScreenWidth = dm.widthPixels;mScreenHeight = dm.heightPixels;//填充悬浮球 布局mFBWindow = LayoutInflater.from(mCtx).inflate(R.layout.float_ball, null);mFloatBallView = mFBWindow.findViewById(R.id.float_ball);mFBParams = new LayoutParams(); //设置悬浮球布局的参数mFBParams.x = mScreenWidth-mFloatBallView.getWidth(); mFBParams.y = mScreenHeight / 2;mFBParams.width = WindowManager.LayoutParams.WRAP_CONTENT;mFBParams.height = WindowManager.LayoutParams.WRAP_CONTENT;mFBParams.gravity = Gravity.LEFT | Gravity.TOP;mFBParams.type = LayoutParams.TYPE_SYSTEM_ALERT | LayoutParams.TYPE_SYSTEM_OVERLAY;//顶层的View ,就要用这两个type mFBParams.format = PixelFormat.TRANSLUCENT;//半透明mFBParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;//设置没有焦点不能touch,这样其他的界面才可以滑动和操作mWindowManager.addView(mFBWindow, mFBParams);//将View 按照mFBParams参数设置,添加到mWindowManager ,mFBParams是告诉mFBWindow 的父view}}//这个方法用来拖动时使用,更新位置public void updateBallView(int deltaX,int deltaY) {mFBParams.x += deltaX;mFBParams.y += deltaY;if (mWindowManager != null) {
// Log.d(TAG,"updateBallView mParams.x = "+mFBParams.x+" mParams.y = "+mFBParams.y);mWindowManager.updateViewLayout(mFBWindow, mFBParams);}}
}
悬浮球布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fl_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@android:color/transparent"android:orientation="vertical"><!--悬浮球背景--><ImageViewandroid:id="@+id/img_bg" android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleX="0.7"android:scaleY="0.7"android:background="@drawable/icon_bg"android:layout_gravity="center"/><!--悬浮球动画小球--><ImageViewandroid:id="@+id/img_ball"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:alpha="0.5"android:scaleX="0.7"android:scaleY="0.7"android:background="@drawable/icon_ball"/><!--悬浮球动画大球--><ImageViewandroid:id="@+id/img_big_ball"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:scaleX="0.7"android:scaleY="0.7"android:background="@drawable/icon_big_ball"android:visibility="invisible"/><!--悬浮球开关 默认是off--><TextViewandroid:id="@+id/tv_switch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="@string/switch_off"/>
</FrameLayout>
以上一个悬浮球 就可以显示了,但是不能操作
完整代码