android 360悬浮框实现原理

通过WindowManageraddView()方法,并设置WindowManager.LayoutParams的相关属性,就可以往WindowManager中加入所需要的View,而根据WindowManager.LayoutParams属性不同,也就能实现不同的效果。比如创建系统顶级窗口,实现悬浮窗口效果。如果需要将ViewWindowManager中移除,只需要调用removeView()即可。

下面以一个简单的例子来解释一下如何实现悬浮窗口效果。

首先,得到WindoeManager对象:
        WindowManager wManager = getApplicationContext().getSystemService( Context. WINDOW_ SERVICE);

其次,得到WindowManager.LayoutParams对象,为后续设置相关参数做准备:
        private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();

接着,设置相关的窗口布局参数,要实现悬浮窗口效果,主要需要设置的参数有:
        wmParams.type = LayoutParams.TYPE_PHONE; // 设置window type
        wmParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明

        /*
        * 下面的flags属性的效果形同锁定。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
        */
        wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
        LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;

wmParams.gravity = Gravity.RIGHT| Gravity. CENTER_VERTICAL; // 调整悬浮窗口至右侧中间
         // 以屏幕左上角为原点,设置xy初始值
         wmParams.x = 0;
        wmParams.y = 0;

// 设置悬浮窗口长宽数据
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;;
         wmParams.height =WindowManager.LayoutParams.WRAP_CONTENT;;

然后,就可以将需要加到悬浮窗口中的View加入到窗口中了:
        if(view.getParent==null)//如果view没有被加入到某个父组件中,则加入WindowManager
        wManager.addView(view,wmParams);

其中,view为需要放到悬浮窗口中的视图组件。

如果要将其从WindowManager中移除,则可以执行以下语句:
        if(view.getParent()!=null)
        wManager.removeView(view);

最后,还有需要注意的是,如果要用悬浮窗口,需要在AndroidManifest.xml中加入如下的权限:
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

  @Override

  public void onStart(Intent intent, int startId) { 

  super.onStart(intent, startId); 

  //通过WindowManager将浮动的窗口添加到屏幕 

  mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 

  mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 

  mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

  mView = (ViewGroup) mInflater.inflate(R.layout.float_window, null); 

  mView.setOnTouchListener(this); 

  mView.setVisibility(View.GONE); 

  mTextView = (TextView) mView.findViewById(R.id.text); 

  mLayoutParams = new WindowManager.LayoutParams(); 

  mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 

  mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 

  mLayoutParams.alpha = (float) 0.99; 

  mLayoutParams.gravity =  Gravity.LEFT | Gravity.TOP; 

  mLayoutParams.x = 10; 

  mLayoutParams.y = 10; 

  mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 

  //使用此类型要额外添加一个权限 

  mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; 

  mWindowManager.addView(mView, mLayoutParams); 

  listenActivity(); 

}

  private void listenActivity(){ 

  new Thread(){ 

  public void run(){ 

  List<RunningTaskInfo> taskInfos; 

  //判断程序是否处于桌面 

  //木有找到比较好的监听方法,所以用了一个最笨的方法 

  //因为对相应要求不高,所以每100毫秒检查一次 

  //有好方法的请留言,不胜感谢 

  try { 

  while(true){ 

  sleep(100); 

  taskInfos = mActivityManager.getRunningTasks (1); 

  if(taskInfos.get(0).topActivity.getPackageName().equals("com.android.launcher") ){ 

  mHandler.sendEmptyMessage(View.VISIBLE); 

  }else{ 

  mHandler.sendEmptyMessage(View.GONE); 

  

  

  } catch (InterruptedException e) { 

  e.printStackTrace(); 

  

  

  }.start(); 

  

  @Override

  public void onDestroy() { 

  mWindowManager.removeView(mView); 

  super.onDestroy(); 

  

  @Override

  public boolean onTouch(View v, MotionEvent event) { 

  switch (event.getAction()){ 

  //此处实现在桌面的拖动 

  case MotionEvent.ACTION_DOWN: 

  xOffset = (int) event.getRawX(); 

  yOffset = (int) event.getRawY(); 

  x = mLayoutParams.x; 

  y = mLayoutParams.y; 

  startTime = System.currentTimeMillis(); 

  break; 

  case MotionEvent.ACTION_MOVE: 

  if ( System.currentTimeMillis() - startTime < 1000 )break; 

  mLayoutParams.x = x + (int) event.getRawX() - xOffset; 

  mLayoutParams.y = y + (int) event.getRawY() - yOffset; 

  mWindowManager.updateViewLayout(mView, mLayoutParams); 

  break; 

  case MotionEvent.ACTION_UP: 

  if (robotMsg%2 == 0){ 

  mTextView.setText("Hello Boy!"); 

  }else{ 

  mTextView.setText("Hello Gril!!"); 

  

  robotMsg ++; 

  break; 

  

  return true; 

  }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值