aosp13 实现自由窗口最小化功能

 学习android framework有一段时间了,感觉有必要实战一个复杂点的功能来巩固一下学到的东西。于是就仿照自己手上华为nova 8 pro的自由窗口最小化效果,做了一下,过程还是挺漫长的,终于做出来了,下面是完整的效果:

自由窗口最小化完整效果

效果概述:

1.点击最小化按钮后,侧边栏会出现一个悬浮球。悬浮球可以随意拖动,但松手后会靠边。

2.每当一个自由窗口最小化后,都会更新悬浮球上的logo

3.只允许出现一个自由窗口,新的自由窗口或进入最近任务页面都会触发已有的自由窗口最小化

4.点击悬浮球出现的自由窗口会有一个放大的动画;点击最小化按钮会有一个逐渐缩小的动画。

5.当最小化的自由窗口大于等于2个时,点击悬浮球会展示已最小化的窗口列表,且背景是模糊的。

6.太多细节就不赘述了。。。

遇到的问题分享

实现的过程中遇到了太多的问题,但都解决了。这里就挑两个问题分享一下:

1.最小化按钮

我在加这个最小化按钮的时候,需要修改DecorCaptionView的布局文件,这就涉及到了修改frameworks/base/core/res/res目录下的文件。而修改这个文件下的内容时(添加id,layout,drawable,style等),注意,需要在frameworks/base/core/res/res/values/symbols.xml中添加对应的<java-symbol>标签。否则,编译会报错:cannot find symbol

另外,感觉修改frameworks/base/core目录下的东西,哪怕修改一点点,都会编译很长时间。所以,以后应该注意尽量不要改这个目录下的内容吧。

2.SurfaceControl.Transaction的setCrop()方法

在做窗口的缩小动画时,分两步:1 把画面渐渐裁成一个正方形  2 把正方形缩小平移到悬浮球位置。第一步时裁剪出了问题,请看慢动作回放:

发现一开始顶部就突然少了一部分,这就导致变成正方形时,看上去logo并没有居中。

其实是因为setCrop(SurfaceControl sc,Rect rect)这个方法中第二个参数rect应该是相对task的坐标而不是绝对坐标。看图,假如task在屏幕的区域为(0,100)-(1440,2500)

那如果想完整地把task内容裁出来,就需要这样:

t.setCrop(task.getSurfaceControl,new Rect(0,0,1440,2400));

而不是这样:

t.setCrop(task.getSurfaceControl,new Rect(0,100,1440,2500));

再比如,如果想要裁剪task的左上角一块边长100的正方形,不论task位置在何处,只需要这样:

t.setCrop(task.getSurfaceControl,new Rect(0,0,100,100));

了解了这个,修改后的完整动画如图:

 总结

其他细节实现:

1.动画过程中,画面上的logo实现方案参考的时app启动时的addStartingWindow

2.悬浮球,侧边栏都是直接add的TYPE_APPLICATION_OVERLAY窗口

未实现的或待改进的:

1.放大缩小动画根据task画面和悬浮球的相对位置不同而不同

2.悬浮球拖动到底部某一区域,移除全部的最小化task。感觉可以参考pip的类似功能

3.还是有非必现的闪退bug

4.现在实现代码都写在systemServer里,感觉应该写到systemUI里是不是更好

最后,要感谢一下马哥在我framework学习过程中给予的帮助,在开发过程中大部分问题的解决思路也都是从马哥那里学到的,最终实现的这个自由窗口最小化功能虽然还有问题,但还是很开心的。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值