Launcher3 OverviewMode和mInsets
来源:互联网 发布:淘宝2017双11广告视频 编辑:程序博客网 时间:2024/06/06 01:20
OverviewMode
Launcher3里,在Workspace界面长按空白处,桌面进去OverviewMode,查看源码:Launcher类实现了View.OnLongClickListener接口,可以看到在onLongClick方法中有这么一句:
mWorkspace.enterOverviewMode();
这句代码在onLongClick方法中出现了两次:
- 在长按的view为Workspace且当前不在OverviewMode模式
- 长按的地方为Hotseat图标外的空白地方时,且当前不在拖动状态和OverviewMode下
退出OverviewMode的方法是exitOverviewMode,通过查看这两个方法,它们都调用了enableOverviewMode方法。
看一下enableOverviewMode方法,这一句比较重要:
Animator workspaceAnim = getChangeStateAnimation(finalState, animated, 0, snapPage);
如同对象名workspaceAnim,这句代码是取得Launcher3在各种状态之间变化时的动画,Workspace中有一个enum State,代表桌面的各种状态,OverviewMode时State为State.OVERVIEW,显示Workspace时状态为State.NORMAL,getChangeStateAnimation方法第一个参数就是桌面即将进入的状态。
getChangeStateAnimation方法比较重要,在桌面在各种状态之间变化时都会调用,这里看一下进入OverviewMode的动画:一开始经过新老状态boolean的判断,决定背景透明度(finalBackgroundAlpha)、Hotseat和PageIndicator透明度(finalHotseatAndPageIndicatorAlpha)等相关属性的设定和当前进行的状态改变。然后取得桌面上各种“拼图”:SearchBar,HotSeat,PageIndicator等对象并进行各种动画效果,比如scale就是Workspace对象的缩放动画。
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(this);scale.scaleX(mNewScale) .scaleY(mNewScale) .translationY(finalWorkspaceTranslationY) .setDuration(duration) .setInterpolator(mZoomInInterpolator);anim.play(scale);...
mInsets
在计算动画时各对象的属性变化中,关于透明度,缩放的值的计算比较简单,但是位置的计算通常要从DeviceProfile中取得信息计算而来,比如Workspace缩放后的TranslationY在OverviewMode下由Workspace的getOverviewModeTranslationY方法得来。
看这个方法使用到了mInsets对象,看源代码时一直想不明白这个值的意义,上网搜索后才恍然大悟,可以参考这里:LauncherRootView和DragLayer的布局过程。
这个网址打开较慢,摘录一下相关的:
在主布局launcher.xml中, 最外层是LauncherRootView。
我们发现它只是重写了一个方法, View.fitSystemWindow(rect), 那这个方法是干什么的呢?查了官方文档,还是看不懂他到底是做什么的,但是倒是会用了。如果你的View在status bar或者navigation bar之下,那么这个方法会传递进去一个参数,说明这个View的四周有多少是被status bar或者navigation bar挡住了的。这个方法的会调用父类的setInsets()方法,我们来看看父类InsettableFrameLayout。InsettableFrameLayout继承了FrameLayout, 并且实现了父类的一些方法,总的来说,他的目的就是给子View都设定一个Margin值,防止被status bar或者navigation bar挡住。如果一个View已经是Insettable的了,那么就忽略他。在Launcher3中,Workspace, DragLayer和AppsCustomizeTabHost都实现了这个接口,那么他们自身就不会被加Margin, 而搜索栏和Hotseat都没有实现这个接口,那么说明他们在被加到父亲上得时候会被设一个Margin,最后的到得效果就是搜索栏刚好在status bar之下(gravity为top,topmargin是statusbar的高度),Hotseat刚好在navigationbar的上方(gravity为bottom,bottomMargin为navigation bar的高度)。
可以看一下InsettableFrameLayout的setFrameLayoutChildInsets方法
public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (child instanceof Insettable) { ((Insettable) child).setInsets(newInsets); } else if (!lp.ignoreInsets) { lp.topMargin += (newInsets.top - oldInsets.top); lp.leftMargin += (newInsets.left - oldInsets.left); lp.rightMargin += (newInsets.right - oldInsets.right); lp.bottomMargin += (newInsets.bottom - oldInsets.bottom); } child.setLayoutParams(lp); }
child是当前类的子类,如果其不是Insettable的子类,fitSystemWindow方法中传进来的Rect就会当成Margin值加到LayoutParams中, 由于InsettableFrameLayout继承了FrameLayout,加了这些Margin的View可以保证自己至少不会被状态栏和导航栏遮挡。
如果child没有继承Insettable,如Workspace。Workspace重写了setInsets方法,将fitSystemWindow方法传递进来的mInsets给自己的mInsets,这样在计算布局的时候(例如上面提到的Workspace的getOverviewModeTranslationY方法),就可以考虑到状态栏和导航栏的影响了。
- Launcher3 OverviewMode和mInsets
- Launcher3源码浅析(5.1)--OverviewMode
- Android Launcher3修改长按屏幕空白处进入OverviewMode模式,进入OverviewMode模式点击Home无法复原的bug
- launcher3
- Launcher3
- Android launcher3布局和结构
- Android launcher3布局和结构
- (3)Launcher3 的布局和结构
- launcher3桌面阴影和systemUI阴影
- 去掉默认桌面:Launcher3 和 Home
- Launcher3--初识Launcher3
- Launcher3--初识Launcher3
- launcher3搜索栏和添加一些控件如Textview
- 奇葩的Twitter和更奇葩的Launcher3
- Launcher3动态切换桌面排列和解锁动画
- Android 7.0 Launcher3的启动和加载流程分析
- Launcher3如何设置桌面的行数和列数?
- Android N Launcher3到启动和加载流程
- python模拟新浪微博登陆之获取cookies
- 算法基础: 大数除法-二分法
- Andorid中使用Jsoup解析库解析XML、HTML、Dom节点---第三方库学习笔记(三)
- 什么是实例化?
- build-essential
- Launcher3 OverviewMode和mInsets
- [错误记录]tableviewcell问题
- connect to host **** port 22: Connection refused
- android 4.4状态栏沉浸
- error:[NSNull length]: unrecognized selector sent to instance 0x198dd6690'
- WebService学习笔记(五)拦截器与SOAP协议
- 自己动手做Android音乐播放器(续)
- typedef与#define的区别
- PhoneGap创建Android项目并使用eclipse打开