Android中使用WindowManager在界面布局上添加浮动窗口

如果大家看过一些游戏sdk中的功能,现在大多都有悬浮窗口这个功能。如360,uc等等。。

这里不需要定义service,只需要这只WindowsManager中的LayoutParams就可以达到这个悬浮框可以绑定界面的功能。


话不多说,先上代码:

public class FloatBox extends BasicView {LinearLayout mFloatLayout;FloatButton floatView;String TAG = "FloatBox";WindowManager.LayoutParams windowParams;WindowManager mWindowManager;float mStartX = 0;float mStartY = 0;public FloatBox(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}public FloatBox(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public FloatBox(Context context, String str) {super(context, str);// TODO Auto-generated constructor stub}public FloatBox(Context context) {super(context);// TODO Auto-generated constructor stub}@Overrideprotected void init(Context context) {// TODO Auto-generated method stubinitWindowBox(context);}private void initViewBox(Context context){mFloatLayout = new LinearLayout(context);LinearLayout.LayoutParams mFloatLayoutLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);mFloatLayout.setLayoutParams(mFloatLayoutLP);mFloatLayout.setOrientation(LinearLayout.VERTICAL);floatView = new FloatButton(context);LinearLayout.LayoutParams floatViewLp = new LinearLayout.LayoutParams(MetricUtil.getDip(context, 50), MetricUtil.getDip(context, 50));floatView.setLayoutParams(floatViewLp);mFloatLayout.addView(floatView);}/** * 用windowManager来添加box * @param context */private void initWindowBox(Context context){windowParams = new WindowManager.LayoutParams();mWindowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);// 设置window type 这里使用的type是1000 - 2000之间的,需要绑定token// 如果使用2000以上的类型的话,一般适用于桌面上的悬浮窗.windowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;windowParams.format = PixelFormat.RGBA_8888;windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;windowParams.gravity = Gravity.LEFT | Gravity.TOP;// 以屏幕左上角为原点,设置x、y初始值,相对于gravitywindowParams.x = 0;windowParams.y = 0;// 长宽设置windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;mFloatLayout = new LinearLayout(context);LinearLayout.LayoutParams mFloatLayoutLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);mFloatLayout.setLayoutParams(mFloatLayoutLP);mFloatLayout.setOrientation(LinearLayout.VERTICAL);// 绑定tokenwindowParams.token = mFloatLayout.getWindowToken();// 添加layoutmWindowManager.addView(mFloatLayout, windowParams);floatView = new FloatButton(context);LinearLayout.LayoutParams floatViewLp = new LinearLayout.LayoutParams(MetricUtil.getDip(context, 50), MetricUtil.getDip(context, 50));floatView.setLayoutParams(floatViewLp);mFloatLayout.addView(floatView);mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));Log.i(TAG, "Width/2--->" + floatView.getMeasuredWidth() / 2);Log.i(TAG, "Height/2--->" + floatView.getMeasuredHeight() / 2);floatView.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubSystem.out.println("onTouch ");switch (event.getAction()) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE://加一个值,更方便点击if(Math.abs(event.getRawX() - mStartX) > 30){mStartX = event.getRawX();}if(Math.abs(event.getRawY() - mStartY) > 30){mStartY = event.getRawY();}updatePosition();break;case MotionEvent.ACTION_UP:break;default:break;}//if(event.getAction() == MotionEvent.ACTION_MOVE){////Log.i(TAG, "event.getRawX()--->" + event.getRawX());//Log.i(TAG, "event.getRawX()--->" + event.getRawY());//mStartX = event.getRawX();//mStartY = event.getRawY();//}else if(event.getAction() == MotionEvent.ACTION_UP){//return true;//}return false;}});final Context mcontext = context;floatView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubToast.makeText(mcontext, "floatView onclick", 1000).show();return;}});}private void updatePosition(){windowParams.x = (int) (mStartX - floatView.getMeasuredWidth() / 2);windowParams.y = (int) (mStartY - floatView.getMeasuredHeight() / 2);// refreshLog.i(TAG, "x--->" + windowParams.x);Log.i(TAG, "y--->" + windowParams.y);mWindowManager.updateViewLayout(mFloatLayout, windowParams);}public void showBox() {mFloatLayout.setVisibility(View.VISIBLE);}public void hideBox() {mFloatLayout.setVisibility(View.GONE);}public void removeBox() {mWindowManager.removeView(mFloatLayout);}}


然后,以下是自定义button的代码:

public class FloatButton extends Button {public FloatButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubinit();}public FloatButton(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubinit();}public FloatButton(Context context) {super(context);// TODO Auto-generated constructor stubinit();}private void init() {Decorator.setStateImage(this,ResourceLoader.getBitmapDrawable("appicon_normal.png"),ResourceLoader.getBitmapDrawable("appicon_hover.png"),ResourceLoader.getBitmapDrawable("appicon_normal.png"));}}