需求描述
类似微信视频、语音时点击返回会形成一个App小窗口浮动在界面上,点击继续是通通话,如下图:
效果展示
技术分析
其实实现这个功能只需要你细心分析一下就有思路了:首先这个小窗口是浮动在app最上层的视图,其次所有触屏事件需先由该小窗口处理,还有就是小窗口的生命周期和Application也能虽可能不能同生,但是确是可以共死。所以可以在Application中创建一个view添加到WindowManage,这里将视图为view的window的type设置成系统级别的窗口,这样这个window可以在在全局呈现。另外,还需要让这个window可以随手指拖动而滑动,手指释放后会回弹到距离这个释放点最近的屏幕侧边,所以需要重写view 的OnTouch事件。
代码细节实现
- 创建全局Application,在Application创建的时候初始化一个view,以及一个WindowManager.LayoutParams,并设置get方法,方便外部调用:
private SmallWindowView windowView;
private WindowManager wm;
private WindowManager.LayoutParams mLayoutParams;
public SmallWindowView getWindowView() {
return windowView;
}
public WindowManager getWm() {
return wm;
}
public WindowManager.LayoutParams getmLayoutParams() {
return mLayoutParams;
}
@Override
public void onCreate() {
super.onCreate();
initSmallViewLayout();
}
public void initSmallViewLayout() {
windowView = (SmallWindowView) LayoutInflater.from(this).inflate(R.layout.small_window, null);
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
mLayoutParams.gravity = Gravity.NO_GRAVITY;
//使用非CENTER时,可以通过设置XY的值来改变View的位置
windowView.setWm(wm);
windowView.setWmParams(mLayoutParams);
}
- 编写一个BaseActivity 实现可供子类来显示隐藏窗口的方法:
private WindowManager wm;
private SmallWindowView windowView;
private WindowManager.LayoutParams mLayoutParams;
private int OVERLAY_PERMISSION_REQ_CODE = 2;
private boolean isRange = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wm = ((MyApplication)getApplication()).getWm();
windowView = (