带磁性的悬浮窗体

转载请注明出处,本文来自 http://blog.csdn.net/manymore13

带磁性的悬浮窗体,类似于360绿色小人

主要实现的是:

1.悬浮所有窗体之上

2.有吸引力,吸附于屏幕边上

3.有点击效果

下面我就实现上面三点,简单封装了个FloatView 

先看下本次Demo的效果图,然后再看代码,

效果图:


FloatView代码如下

package com.manymore13.flowwindowdemo;

import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;

/**
 * @author manymore13  
 * @Blog <a href="http://blog.csdn.net/manymore13">http://blog.csdn.net/manymore13</a>
 * @version 1.0
 */
public class FloatView extends ImageView{
	
	private float mTouchX;
	private float mTouchY;
	private float x;
	private float y;
	private int startX;
	private int startY;
	private Context c;
	private int imgId = R.drawable.ic_launcher;
	private int controlledSpace = 20; 
	private int screenWidth;
	boolean isShow = false;
	private OnClickListener mClickListener;
	
	private WindowManager windowManager ;
	
	private WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams();

	public FloatView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	public FloatView(Context c)
	{
		super(c);
		initView(c);
	}
	// 初始化窗体
	public void initView(Context c)
	{
		windowManager = (WindowManager) c.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
		screenWidth = windowManager.getDefaultDisplay().getWidth();
		this.setImageResource(imgId);
		windowManagerParams.type = LayoutParams.TYPE_PHONE;
		windowManagerParams.format = PixelFormat.RGBA_8888;	// 背景透明
		windowManagerParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
				| LayoutParams.FLAG_NOT_FOCUSABLE;
		// 调整悬浮窗口至左上角,便于调整坐标
		windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP; 
		// 以屏幕左上角为原点,设置x、y初始值
		windowManagerParams.x = 0;
		windowManagerParams.y = 200;
		// 设置悬浮窗口长宽数据
		windowManagerParams.width = LayoutParams.WRAP_CONTENT;
		windowManagerParams.height = LayoutParams.WRAP_CONTENT;
		
	}
	
	public void setImgResource(int id)
	{
		imgId = id;
	}
		
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		x = event.getRawX();
		y = event.getRawY();
				
		switch(event.getAction())
		{
			case MotionEvent.ACTION_DOWN:
			{
				mTouchX = event.getX();
				mTouchY = event.getY();
				startX = (int) event.getRawX();
				startY = (int) event.getRawY();
				break;
				
			}
			case MotionEvent.ACTION_MOVE:
			{
				updateViewPosition();
				break;
			}
			case MotionEvent.ACTION_UP:
			{
			
				if(Math.abs(x - startX) < controlledSpace && Math.abs(y - startY) < controlledSpace)
				{
					if(mClickListener != null)
					{
						mClickListener.onClick(this);
					}
				}
				Log.i("tag", "x="+x+" startX+"+startX+" y="+y+" startY="+startY);
				if(x <= screenWidth/2)
				{
					x = 0;
				}else{
					x = screenWidth;
				}
				
				updateViewPosition();
							
				break;
			}
		}
			
		return super.onTouchEvent(event);
	}
	
	// 隐藏该窗体
	public void hide()
	{
		if(isShow)
		{
			windowManager.removeView(this);
			isShow = false;
		}
				
	}
	
	// 显示该窗体
	public void show()
	{
		if(isShow == false)
		{
			windowManager.addView(this, windowManagerParams);
			isShow = true;
		}
		
	}
	
	@Override
    public void setOnClickListener(OnClickListener l) {
         this.mClickListener = l;
    }
	
    private void updateViewPosition() {
         // 更新浮动窗口位置参数
	     windowManagerParams.x = (int) (x - mTouchX);
	     windowManagerParams.y = (int) (y - mTouchY);
	     windowManager.updateViewLayout(this, windowManagerParams); // 刷新显示
    }
}
 
 

源码

如果需要用上面的类可以这样做

floatView = new FloatView(this); // 创建窗体

floatView.setOnClickListener(this); // 设置事件,你需要实现FloatView里的onclick接口

floatView.show();  // 显示该窗体

floatView.hide();  // 隐藏窗体

PS  不要忘记在manifest里加上权限  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


你可能感兴趣的:(带磁性的悬浮窗体)