【教程】Android 下帶磁性的懸浮窗體實現

帶磁性的懸浮窗體,類似於360綠色小人
主要實現的是:
1.懸浮所有窗體之上
2.有吸引力,吸附於屏幕邊上
3.有點擊效果
下面我就實現上面三點,簡單封裝了個FloatView
先看下本次Demo的效果圖,然後再看代碼,
效果圖:
https://img-my.csdn.net/uploads/201302/08/1360333747_3322.gif


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();  // 隱藏窗體


以上是本文關於Android 下帶磁性的懸浮窗體實現的詳細教程,希望本文對廣大安卓開發者有所幫助,感謝閱讀本文。

發佈了31 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章