代码地址
http://git.oschina.net/azure_sword/Sample_AS
可悬浮按钮的两种情况
1.当前页面悬浮
2.所有页面悬浮(包括系统页面)
注:第二种功能需要系统权限
android:name=”android.permission.SYSTEM_ALERT_WINDOW”

/**
* Created by zph on 2016/4/5.
*
* 当前页面悬浮按钮
*/
public class FloatView2 {
private Context c;
public FloatView2(Context c) {
this.c=c;
}

private WindowManager wm;private View view;// 浮动按钮/** * 添加悬浮View * @param paddingBottom 悬浮View与屏幕底部的距离 */public void createFloatView(int paddingBottom) {    int w = 100;// 大小    wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);    view = LayoutInflater.from(c).inflate(R.layout.floatview, null);    final WindowManager.LayoutParams params = new WindowManager.LayoutParams();    params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;// 所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。    params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;    params.format = PixelFormat.TRANSLUCENT;// 不设置这个弹出框的透明遮罩显示为黑色    params.width = w;    params.height = w;    params.gravity = Gravity.TOP | Gravity.LEFT;    int screenWidth = c.getResources().getDisplayMetrics().widthPixels;    int screenHeight = c.getResources().getDisplayMetrics().heightPixels;    params.x = screenWidth - w;    params.y = screenHeight - w - paddingBottom;    view.setBackgroundColor(Color.TRANSPARENT);    view.setVisibility(View.VISIBLE);    view.setOnTouchListener(new View.OnTouchListener() {        // 触屏监听        float lastX, lastY;        int oldOffsetX, oldOffsetY;        int tag = 0;// 悬浮球 所需成员变量        @Override        public boolean onTouch(View v, MotionEvent event) {            final int action = event.getAction();            float x = event.getX();            float y = event.getY();            if (tag == 0) {                oldOffsetX = params.x; // 偏移量                oldOffsetY = params.y; // 偏移量            }            if (action == MotionEvent.ACTION_DOWN) {                lastX = x;                lastY = y;            } else if (action == MotionEvent.ACTION_MOVE) {                params.x += (int) (x - lastX) / 3; // 减小偏移量,防止过度抖动                params.y += (int) (y - lastY) / 3; // 减小偏移量,防止过度抖动                tag = 1;                wm.updateViewLayout(view, params);            } else if (action == MotionEvent.ACTION_UP) {                int newOffsetX = params.x;                int newOffsetY = params.y;                // 只要按钮一动位置不是很大,就认为是点击事件                if (Math.abs(oldOffsetX - newOffsetX) <= 20                        && Math.abs(oldOffsetY - newOffsetY) <= 20) {                    onFloatViewClick(l);                } else {                    tag = 0;                }            }            return true;        }    });    wm.addView(view, params);}/** * 点击浮动按钮触发事件,需要override该方法 */private View.OnClickListener l;public void onFloatViewClick(View.OnClickListener l) {    this.l=l;    Toast.makeText(c, "FLOAT", Toast.LENGTH_SHORT).show();    view.setOnClickListener(l);}/** * 将悬浮View从WindowManager中移除,需要与createFloatView()成对出现 */public void removeFloatView() {    if (wm != null && view != null) {        wm.removeViewImmediate(view);

// wm.removeView(view);//不要调用这个,WindowLeaked
view = null;
wm = null;
}
}

/** * 隐藏悬浮View */public void hideFloatView() {    if (wm != null && view != null&&view.isShown()) {        view.setVisibility(View.GONE);    }}/** * 显示悬浮View */public void showFloatView(){    if (wm != null && view != null&&!view.isShown()) {        view.setVisibility(View.VISIBLE);    }}

}

/**
* Created by zph on 2016/4/5.
*
* 全系统悬浮按钮
*/
public class FloatView extends ImageView {

private Context c;private float mTouchX;private float mTouchY;private float x;private float y;private int startX;private int startY;private int imgId = R.drawable.ic_launcher;private int controlledSpace = 20;private int screenWidth;private int screenHeight;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);    DisplayMetrics dm=getResources().getDisplayMetrics();    screenWidth = dm.widthPixels;    screenHeight = dm.heightPixels;    this.setImageResource(imgId);    windowManagerParams.type = WindowManager.LayoutParams.TYPE_PHONE;    windowManagerParams.format = PixelFormat.RGBA_8888; // 背景透明    windowManagerParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;    // 调整悬浮窗口至左上角,便于调整坐标    windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;    // 以屏幕左上角为原点,设置x、y初始值    windowManagerParams.x = 0;    windowManagerParams.y = screenHeight>>1;    // 设置悬浮窗口长宽数据    windowManagerParams.width = WindowManager.LayoutParams.WRAP_CONTENT;    windowManagerParams.height = WindowManager.LayoutParams.WRAP_CONTENT;}public void setImgResource(int id) {    imgId = id;}@Overridepublic 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;    }}@Overridepublic void setOnClickListener(OnClickListener l) {    this.mClickListener = l;}private void updateViewPosition() {    // 更新浮动窗口位置参数    windowManagerParams.x = (int) (x - mTouchX);    windowManagerParams.y = (int) (y - mTouchY);    windowManager.updateViewLayout(this, windowManagerParams); // 刷新显示}

}

实现代码

public class FloatingButActivity extends BaseActivity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_floating_but);    floatView();    floatView2();}private FloatView floatView;private void floatView() {    floatView = new FloatView(this);    floatView.setImageResource(R.drawable.ic_launcher);    floatView.show();}private FloatView2 floatView2;private void floatView2() {    floatView2 = new FloatView2(this);    floatView2.createFloatView(100);}@Overrideprotected void onDestroy() {    super.onDestroy();    floatView2.removeFloatView();    floatView.hide();}

}

更多相关文章

  1. 【android】点击事件穿透解决方案
  2. Android(安卓)UI编程基础3
  3. Android跟软键盘的故事
  4. RadioGroup和RadioButton
  5. 系出名门Android(5) - 控件(View)之TextView, Button, ImageButt
  6. android drawing
  7. Android(安卓)开发实践 ViewGroup 实现左右滑出窗口(二)
  8. Design Widget
  9. Android(安卓)设置软键盘搜索键以及监听搜索键点击事件

随机推荐

  1. 1. 总是从ID选择器开始继承   在jquery
  2. 小弟初学网页(javascript),看不懂下面的代
  3. 通过jQuery提交的HTML不会接收点击事件
  4. 如何在没有pdf组件的移动浏览器中显示Bas
  5. HTML CSS Javascript中 id重复时会发生的
  6. JavaScript 利用 async await 实现 sleep
  7. js之DOM操作(访问父节点parentNode)
  8. Javascript日期/时间函数是否依赖于客户
  9. 为什么在JavaScript中[5,6,8,7][1,2]= 8
  10. 【第2篇】TypeScript - 基本类型详解