android 悬浮窗那点事儿

    不管是桌面小球,悬浮歌词,还是实时监控窗口等等,这些在我这里统统都叫做悬浮窗,虽然长相不同,但实质一样。我认为这些都是配饰,就像美女带的眼镜,耳环,更或者刺青等等,有了这些美女才更美,那有人就会辩驳了说“清水出芙蓉,天然去雕饰”。我只能这么回答你,人能达到这个境界的寥寥无几,更何况物乎。

    不再闲扯,言归正传。
    首先要把一个View贴在窗口上,当然我们必须能够管理这个窗口,就像看门的老大爷的通知栏一样,你没有管理权限,即使你贴上了小广告,大爷照样把你的给扯掉。就这么道理,所以

mWindowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
我们必须能够管理窗口。
然后就是我们怎么去贴
		mLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				LayoutParams.TYPE_SYSTEM_ERROR, LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSPARENT);
		mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
去设置我们要贴的大小,位置,透明度等等。
接着是怎么贴
	private void refreshView() {
		
		if (isViewAdd) {
			mWindowManager.updateViewLayout(mView, mLayoutParams);
		} else {
			mWindowManager.addView(mView, mLayoutParams);
			isViewAdd = true;
		}
	}
如果已经贴上了我们就只要更新就ok了,如果没有贴上,那只能贴了。
最后是贴什么了
mView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.floating, null);
这就是我们要贴的了,至于floating这个布局里面是什么,就是你需要什么写什么了,什么都行,说白了就是你随便扯淡了,想咋扯咋扯了。如果你有想象力可以作出很美丽的雕饰。
举个例子,我们要想做一个控制音乐的悬浮控制板,我们的布局里面就可以定义三个ImageView,一个上一曲,一个播放与暂停,一个下一曲
		mPre = (ImageView)mView.findViewById(R.id.pre);
		mStartStop = (ImageView)mView.findViewById(R.id.start_stop);
		mNext = (ImageView)mView.findViewById(R.id.next);

		mNext.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				if(event.getAction() == MotionEvent.ACTION_DOWN){
					mNext.setBackgroundColor(0xff0000ff);
					mContext.sendBroadcast(new Intent("com.android.music.musicservicecommand.next"));
				}else if(event.getAction() == MotionEvent.ACTION_UP){
					mNext.setBackgroundColor(0x88000000);
				}
				return true;
			}
		});

然后我们点击的时候去完成我们的任务就行了,就这么简单,但是这样的窗口也只能显示出来,没啥意义,所以首先,我们要让他动起来

		mView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					
					mTouchStartX = event.getX();
					mTouchStartY = event.getY();
					break;
				
				case MotionEvent.ACTION_MOVE:
					
					refreshView((int)(event.getRawX() - mTouchStartX), (int)(event.getRawY() - mTouchStartY));
					break;
					
				case MotionEvent.ACTION_UP:
					
					mTouchStartX = 0;
					mTouchStartY = 0;
					break;
				}
				return false;
			}
		});

这就是我们拖动的代码了,当然里面的refreshView我们也贴出来
	private void refreshView(int x, int y) {
		
		if (statusBarHeight == 0) {
			
			View rootView = mView.getRootView();
			Rect r = new Rect();
			rootView.getWindowVisibleDisplayFrame(r);
			statusBarHeight = r.top;
		}
		
		mLayoutParams.x = x;
		mLayoutParams.y = y - statusBarHeight;
		refreshView();
	}

当然了,我们不能把悬浮窗拖到状态栏上去了。
这样的悬浮窗口,在每个界面都有的,我们要是只想在桌面显示,怎么办呢?这个也简单。我们只要知道啥时候是桌面就行了,然后
    private void showView(){
    	if(isEnd){
    		mView.setVisibility(View.GONE);
    	}else{
    		if(isShowAll){
    			mView.setVisibility(View.VISIBLE);
    		}else{
    			if(isCurLauncher){
    				mView.setVisibility(View.VISIBLE);
    			}else{
    				mView.setVisibility(View.GONE);
    			}
    		}
    	}
    }

我们只管去隐藏和显现我们的悬浮窗就行了。那我们怎么判断是在桌面呢?办法有很多中,如果你是做方案设计的,那就简单了,直接在进入桌面的activity是做一个标记,然后检测到这个标记更改了,就如更新悬浮窗口就行了;如果你是做单独的apk的,那也有办法

	class CheckTopActivityTast extends AsyncTask<Object, Object, String> {

		@Override
		protected String doInBackground(Object... arg0) {
			// TODO Auto-generated method stub

			String top_activity = null;
			boolean islauncher = false;
			while (true) {
				top_activity = getTopActivityClassName();
				if(top_activity.contains("launcher")){
					islauncher = true;
				}else{
					islauncher = false;
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				if(isCurLauncher == islauncher){
					continue;
				}else{
					isCurLauncher = islauncher;
					Message msg = new Message();
					msg.what = 1111;
					mHandler.sendMessage(msg);
				}
			}
		}
		
	}
	
    private synchronized String getTopActivityClassName(){  
    	ActivityManager mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 
    	List<RunningTaskInfo>  tasksInfo = mActivityManager.getRunningTasks(1);  
    	if(null!=tasksInfo&&tasksInfo.size() > 0){  
    		return tasksInfo.get(0).topActivity.getClassName();  
    	}  
    	return "";  
    } 

就去启一个线程,一直观察top activity顶层活动了,如果是桌面Launcher,更新就是了,也就这么简单。当然了,我们这些都是在服务中进行的,这样悬浮窗才是悬浮窗。

完整代码http://download.csdn.net/detail/zhiyuan263287/6861095

悬浮窗也就这么点事儿,接下来就是一个人创造力的事情了,你有多大想象力,就能作出多么美妙的设计。



猜你喜欢

转载自blog.csdn.net/zhiyuan263287/article/details/18448335