可移动悬浮球的实现

可移动悬浮球的实现

近期看到魅族的悬浮球功能,初步研究了下,实现了基本的功能。

一、Window 和WindowManger 的概念

Window:一个抽象类,具体实现在PhoneWindow。表示一个窗口的概念,Android中所有的View都是通过Window来显示的,Actvity/Dialog/Toast中的View都是附加在Window上的——Window是View的直接管理者。View的事件是由Window传递给DecorView,然后DecorView传递给View;setContentView的底层也是通过Window来完成

WindowManger:Window的管理者。有三大接口 Window添加——addView,Window删除——removeView,Window更新——updateViewLayout

二、使用WindowManger添加一个Window来实现悬浮效果

    private void setFloatingButton() {
        mFloatingBtn = new Button(this);
        mFloatingBtn.setText("Suspend");
        mLayoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                0,
                0,
                PixelFormat.TRANSPARENT);
        mLayoutParams.flags =
                //本区域内的事件自己处理,本区域外的事件底层Window处理
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                //不获取焦点,也不接收输入事件
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                //可以显示锁屏界面
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        mLayoutParams.x = 100;
        mLayoutParams.y = 300;
        //选用系统层级的Type,这样Window会显示在最顶层
        mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
        //利用WindowManger添加一个Window
        getWindowManager().addView(mFloatingBtn, mLayoutParams);
        

    }

 三、悬浮球随手指滑动的效果

首先,要先给悬浮球设置onTouchListener

mFloatingBtn.setOnTouchListener(this);

然后,在onTouch方法中,不断更新View的位置即可,更新View位置使用了WindowManger的Window更新(updateViewLayout)方法

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - mLastX;
                int deltaY = y - mLastY;
                mLayoutParams.x = mLayoutParams.x + deltaX;
                mLayoutParams.y = mLayoutParams.y + deltaY;
                mWM.updateViewLayout(v, mLayoutParams);
                mLastX = x;
                mLastY = y;
                break;
            default:
                break;
        }
        return false;
    }

  

这样,一个具备基本功能的悬浮球效果就实现了。

扩展:

1.给这个悬浮球赋予更丰富的功能

2.在悬浮球随手指滑动的效果上做些动画,提升滑动体验

参考资料:《Android开发艺术探索》

              https://github.com/xerrard/SuspendedBall

原文地址:https://www.cnblogs.com/xerrard/p/4967711.html