閱讀916 返回首頁    go 阿裏雲 go 技術社區[雲棲]


android 帶磁性的懸浮窗體

https://blog.csdn.net/manymore13/article/details/8577286

帶磁性的懸浮窗體,類似於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="https://blog.csdn.net/manymore13">https://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" />


最後更新:2017-04-03 14:53:55

  上一篇:go [類和對象]-C#OOP
  下一篇:go MySQL JDBC 5.1.25的一個坑(應該算是BUG)