Android实现带磁性的悬浮窗体效果

本文实例讲述了Android实现带磁性的悬浮窗体效果。分享给大家供大家参考,具体如下:

带磁性的悬浮窗体,类似于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 * @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里加上权限(更多manifest功能与权限可参考本站:Android Manifest功能与权限描述大全:http://tools.jb51.net/table/AndroidManifest)

上面有个bug 就是点击的时候view下移

public int getStatusBarHeight() {    int titleBarHeight = 0;    Rect frame = new Rect();    mAct.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);    titleBarHeight = frame.top;    if (titleBarHeight == 0) {      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");      if (resourceId > 0) {        titleBarHeight = getResources().getDimensionPixelSize(resourceId);      }    }    return titleBarHeight;}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》、《Android文件操作技巧汇总》、《Android操作SQLite数据库技巧总结》、《Android操作json格式数据技巧总结》、《Android数据库操作技巧总结》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

可你仍然感谢天地和人世所带来的这些变化和发生。

Android实现带磁性的悬浮窗体效果

相关文章:

你感兴趣的文章:

标签云: