WindowManager实现桌面歌词悬浮框功能

QQ音乐,网易云音乐等音乐类app都有桌面迷你歌词功能,包括桌面歌词的显示、隐藏,锁定解锁,点击事件传递处理,字号切换等等,下面我就根据参与的项目来阐述一下实现逻辑。

一、桌面歌词控件的创建与销毁。

1.创建。

首先在manifest中添加如下权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

通过LayoutInflater加载自定义布局:

LayoutInflater inflater = LayoutInflater.from(appContext);
View floatView = inflater.inflate(R.layout.floating_window, null);

创建WindowManager及WindowManager.LayoutParams,并设置属性:

WindowManager = (WindowManager) MyApplication.getInstance().getSystemService(Service.WINDOW_SERVICE);
WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mLayoutParams.format = PixelFormat.TRANSPARENT;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLayoutParams.gravity = Gravity.TOP;
mLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

这里设置的显示属性为展示在手机屏幕上方,具体关于WindowManager.LayoutParams的属性设置可以参考以下链接:

https://www.cnblogs.com/henu529/p/7061583.html。

使用WindowManager的addView方法:

windowManager.addView(floatView, mLayoutParams);

创建完成。

2.销毁。

windowManager.removeView(floatView);

二、桌面歌词锁定与解锁。

锁定与解锁都通过设置WindowManager.LayoutParams的flags属性实现:

锁定:

mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

这种状态下,桌面歌词控件无法获取焦点,事件将向后传递。

解锁:

mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

这种状态,点击桌面歌词区域会走相关的点击逻辑,点击其他区域仍然执行桌面的点击逻辑。

最后,无论锁定还是解锁,都调用WindowManager的updateViewLayout方法:

windowManager.updateViewLayout(floatView, mLayoutParams);

三、设置歌词字体大小,歌词颜色这些,就是通过setTextSize,setColor这些方法,这里不再阐述。

四、桌面歌词控件可拖动。通过给根部局设置OnTouchListener来实现,具体代码如下:

public View.OnTouchListener onTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startY = event.getRawY();
                    margin = startY - mLayoutParams.y;
                    break;
                case MotionEvent.ACTION_MOVE:
                    y = event.getRawY();
                    int pos = (int) (y - margin);
                  mLayoutParams.y = pos;
                  if (windowManager != null && floatView != null && mLayoutParams != null) {
                     windowManager.updateViewLayout(floatView, mLayoutParams);
                  }
                  break;
              case MotionEvent.ACTION_UP:                
                break;
          }
          return true;
      }
};
五、其他逻辑想到再更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值