代码地址
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 开发实践 ViewGroup 实现左右滑出窗口(二)
  2. Android: Service中创建窗口Dialog
  3. Android alertdialog的自定义添加按钮和添加点击
  4. android 多个按钮中一个高亮
  5. Android中包含多个Activity的应用退出按钮实现
  6. [转]Android 应用初始化及窗体事件(按键)的分发 [此博文包含图片]
  7. Android UI之ImageButton(带图标的按钮)
  8. Android ---ListView + 选择按钮
  9. Android视图加载到窗口的过程分析

随机推荐

  1. android 数据储存——网络存储(5)
  2. 【Android(安卓)Dev Guide - 01】 - What
  3. Android视图绘制流程完全解析,带你一步步
  4. Android(安卓)自定义组合控件
  5. 【Android自动化打包】03. APK的数字签名
  6. 一场关于Android的争论
  7. Android(安卓)开机启动应用
  8. Android调用WebService系列之封装能力
  9. adb通过TCP/IP来调试Android设备
  10. 2016这一年,回顾我们一起走过的"编码美丽"