通过WindowManager实现可以移动的悬浮按钮

1、WindowManager获取

通过WindowManager主要有

addView( View arg0, LayoutParams arg1)
      removeView( View arg0)

     updateViewLayout(View arg0, LayoutParams arg1)三个方法

Context().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
或到WindowManager的实例

2、WindowManager.LayoutParams配置一些参数

参数配置如下

// 设置窗口类型,一共有三种Application windows, Sub-windows, System windows
        // API中以TYPE_开头的常量有23个
        mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        // 设置期望的bitmap格式
        mWindowParams.format = PixelFormat.RGBA_8888;
        mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
        
        // 以下属性在Layout Params中常见重力、坐标,宽高
        mWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
        //悬浮窗的初始位置(100,100)
        mWindowParams.x = 100;
        mWindowParams.y = 100;

设置悬浮窗的大小,下面设置宽高各为50dip

        DisplayMetrics metrics=new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        mWindowParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,metrics);
        mWindowParams.height =(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,metrics);
3、通过addview方法设置悬浮显示的内容

 mWindowManager.addView(imageView, mWindowParams);
到目前为止还只能显示、并不能移动下面讲实现悬浮按钮的实现

-----------------------------------不华丽的分割线---------------------------------------------------


实现移动是通过修改mWindowParams.x 和mWindowParams.y悬浮按钮的位置、然后通过updateViewLayout实现的


可以通过复写view的onTouchEvent方法(注意返回值,如果直接返回true、那么该view的onClick、onLongClick将不能被相应,最好返回父类的默认返回值)

step 1

private boolean isMoveable=false;//定义一个bool值,判断当前悬浮按钮是否可以移动,我们是只有长按以后才可以移动

在view的构造方法中

setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				isMoveable=true;
				return true;
			}
		});

当长按后标记为可以移动

step 2

复写父类的onTouchEvent方法

@Override
	public boolean onTouchEvent(MotionEvent event) {

		int titleHeight = 0;
		if (mListener != null) {
			titleHeight = mListener.getTitleHeight();
		}
		
		// 当前值以屏幕左上角为原点
		mRawX = event.getRawX();
		mRawY = event.getRawY() - titleHeight;
		Log.i("csl", "mRawX="+mRawX+","+"mRawY="+mRawY);
		final int action = event.getAction();
		
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			// 以当前父视图左上角为原点
			mStartX = event.getX();
			mStartY = event.getY();
			Log.i("csl", "ACTION_DOWN-->"+"mStartX="+mStartX+","+"mStartY="+mStartY);
			break;

		case MotionEvent.ACTION_MOVE:
			if (isMoveable) {
				if (moveListener!=null) {
                                     moveListener.onMove(mRawX-mStartX, mRawY-mStartY);
                                     }
			}
			break;
			
		case MotionEvent.ACTION_UP:
			if (isMoveable) {
				if (moveListener!=null) {
                                   moveListener.onMove(mRawX-mStartX, mRawY-mStartY);
                                }
			}
			isMoveable=false;
			break;	
		}
		
		// 消耗触摸事件
		return super.onTouchEvent(event);
	}

其中、getRawX(),getRawY()方法或的是当前触摸点在屏幕上的坐标 event.getX().event.getY()或得的是触摸点相对于当前View的左上角的坐标

所以当前View的坐标应该为(getRawX()-event.getX()  , getRawY()-event.getY())

所以我们在手指获得的时候(DOEN/MONE/UP)的时候将当前的view的左上角坐标设置到WindowManager.LayoutParams中,然后调用updateViewLayout方法即可实现悬浮按钮的拖动

接口如下:

	public interface MoveListener{
		public void onMove(float x,float y);
	}
	private MoveListener moveListener;
	public void setMoveListener(MoveListener moveListener){
		this.moveListener=moveListener;
	}

在Activity中实现接口并在回调方法中updateViewLayout


最后在Activity的onDestory生命周期中remove掉view









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值