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
	}

	@Override
	protected void init(Context context) {
		// TODO Auto-generated method stub
		initWindowBox(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初始值,相对于gravity
		windowParams.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);
		
		// 绑定token
		windowParams.token = mFloatLayout.getWindowToken();
		// 添加layout
		mWindowManager.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() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				System.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() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Toast.makeText(mcontext, "floatView onclick", 1000).show();
				return;
			}
		});
	}
	
	
	private void updatePosition(){
		windowParams.x = (int) (mStartX - floatView
				.getMeasuredWidth() / 2);
		windowParams.y = (int) (mStartY - floatView
				.getMeasuredHeight() / 2);
		// refresh
		Log.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 stub
		init();
	}

	public FloatButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	public FloatButton(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}

	private void init() {
		Decorator.setStateImage(this,
				ResourceLoader.getBitmapDrawable("appicon_normal.png"),
				ResourceLoader.getBitmapDrawable("appicon_hover.png"),
				ResourceLoader.getBitmapDrawable("appicon_normal.png"));
	}
}



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值