Launcher3 翻页动画详解与修改
一直对android桌面的翻页效果比较感兴趣,这两天有空所以去研究了下它的实现原理。
Launcher3 的页面分为两块:工作区(workspace)和主菜单(APPS_CUSTOMIZE),这两块基本功能差不多,都是继承于PagedView,工作区的翻页效果是普通的平滑过渡,没什么特殊效果。主菜单页则采用了类似于扑克牌的层叠效果,本文重点研究其实现,最后顺便修改成其它效果。
1,原理
开始一直以为是由动画效果生成的,结果走了不少弯路,后来发现是Scroller滚动时不断利用重载dispatchDraw绘制子页生成的一个动画效果。关键代码如下:
@Override
protected void dispatchDraw(Canvas canvas) {
int halfScreenSize = getViewportWidth() / 2; // 270
// mOverScrollX is equal to getScrollX() when we're within the normal
// scroll range.
// Otherwise it is equal to the scaled overscroll position.
int screenCenter = mOverScrollX + halfScreenSize;
// 当位置为变化或强制滑动时
if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
// set mForceScreenScrolled before calling screenScrolled so that
// screenScrolled can
// set it for the next frame
mForceScreenScrolled = false;
//绘制翻页效果的关键位置,下面将重点展开详解。
screenScrolled(screenCenter);
mLastScreenCenter = screenCenter;
}
// Find out which screens are visible; as an optimization we only call
// draw on them
final int pageCount = getChildCount();
if (pageCount > 0) {
getVisiblePages(mTempVisiblePagesRange);
final int leftScreen = mTempVisiblePagesRange[0];
final int rightScreen = mTempVisiblePagesRange[1];
if (leftScreen != -1 && rightScreen != -1) {
final long drawingTime = getDrawingTime();
// Clip to the bounds
canvas.save();
canvas.clipRect(getScrollX(), getScrollY(), getScrollX()
+ getRight() - getLeft(), getScrollY() + getBottom()
- getTop());
// Draw all the children, leaving the drag view for last
//绘制所有子页,拖动页最后绘制
for (int i = pageCount - 1<