路径:packages\apps\Launcher3\src\com\android\launcher3
目前代码中是未打开的状态
packages\apps\Launcher3\src\com\android\launcher3\util\WallpaperOffsetInterpolator.java
涉及到的方法有:(重要性从上往下)
updateOffset()
——最重要
computeScrollOffset()
——在updateOffset()中被调用
doFrame()
——调用updateOffset()
syncWithScroll()
——调用updateOffset()
wallpaperOffsetForCurrentScroll()
——调用wallpaperOffsetForScroll
wallpaperOffsetForScroll
——计算屏幕滚动时壁纸的偏移量setFinalX()
——壁纸当前滑动的目标值
animateToFinal()
——打开boolean mAnimating属性
computeScroll()
——在别的类中,initWorkspace里创建了WallpaperOffsetInterpolator的对象,并在computeScroll方法调用了syncWithScroll方法涉及到的常量有:
MIN_PARALLAX_PAGE_SPAN
——壁纸滑动至显示完整时的滚动次数,即屏幕的数量减一
private void updateOffset(boolean force) {
if (mWaitingForUpdate || force) {
mWaitingForUpdate = false;
if (computeScrollOffset() && mWindowToken != null) {
try {
mWallpaperManager.setWallpaperOffsets(mWindowToken, getCurrX(), 0.5f);
setWallpaperOffsetSteps();
} catch (IllegalArgumentException e) {
Log.e(TAG, "Error updating wallpaper offset: " + e);
}
}
}
}
public boolean computeScrollOffset() {
final float oldOffset = mCurrentOffset;
if (mAnimating) {
long durationSinceAnimation = System.currentTimeMillis() - mAnimationStartTime;
float t0 = durationSinceAnimation / (float) ANIMATION_DURATION;
float t1 = mInterpolator.getInterpolation(t0);
mCurrentOffset = mAnimationStartOffset +
(mFinalOffset - mAnimationStartOffset) * t1;
mAnimating = durationSinceAnimation < ANIMATION_DURATION;
} else {
mCurrentOffset = mFinalOffset;
}
if (Math.abs(mCurrentOffset - mFinalOffset) > 0.0000001f) {
scheduleUpdate();
}
if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
return true;
}
return false;
}
@Override
public void doFrame(long frameTimeNanos) {
updateOffset(false);
}
public void syncWithScroll() {
float offset = wallpaperOffsetForCurrentScroll();
setFinalX(offset);
updateOffset(true);
}
private float wallpaperOffsetForCurrentScroll() {
return wallpaperOffsetForScroll(mWorkspace.getScrollX());
}
public float wallpaperOffsetForScroll(int scroll) {
// To match the default wallpaper behavior in the system, we default to either the left
// or right edge on initialization
int numScrollingPages = getNumScreensExcludingEmptyAndCustom();
if (mLockedToDefaultPage || numScrollingPages <= 1) {
return mIsRtl ? 1f : 0f;
}
// Distribute the wallpaper parallax over a minimum of MIN_PARALLAX_PAGE_SPAN workspace
// screens, not including the custom screen, and empty screens (if > MIN_PARALLAX_PAGE_SPAN)
if (mWallpaperIsLiveWallpaper) {
mNumPagesForWallpaperParallax = numScrollingPages;
} else {
mNumPagesForWallpaperParallax = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages);
}
// Offset by the custom screen
int leftPageIndex;
int rightPageIndex;
if (mIsRtl) {
rightPageIndex = mWorkspace.numCustomPages();
leftPageIndex = rightPageIndex + numScrollingPages - 1;
} else {
leftPageIndex = mWorkspace.numCustomPages();
rightPageIndex = leftPageIndex + numScrollingPages - 1;
}
// Calculate the scroll range
int leftPageScrollX = mWorkspace.getScrollForPage(leftPageIndex);
int rightPageScrollX = mWorkspace.getScrollForPage(rightPageIndex);
int scrollRange = rightPageScrollX - leftPageScrollX;
if (scrollRange == 0) {
return 0f;
}
// Sometimes the left parameter of the pages is animated during a layout transition;
// this parameter offsets it to keep the wallpaper from animating as well
int adjustedScroll = scroll - leftPageScrollX -
mWorkspace.getLayoutTransitionOffsetForPage(0);
float offset = Utilities.boundToRange((float) adjustedScroll / scrollRange, 0f, 1f);
// The offset is now distributed 0..1 between the left and right pages that we care about,
// so we just map that between the pages that we are using for parallax
float rtlOffset = 0;
if (mIsRtl) {
// In RTL, the pages are right aligned, so adjust the offset from the end
rtlOffset = (float) ((mNumPagesForWallpaperParallax - 1) - (numScrollingPages - 1)) /
(mNumPagesForWallpaperParallax - 1);
}
return rtlOffset + offset *
((float) (numScrollingPages - 1) / (mNumPagesForWallpaperParallax - 1));
}
public void setFinalX(float x) {
scheduleUpdate();
mFinalOffset = Math.max(0f, Math.min(x, 1f));
if (getNumScreensExcludingEmptyAndCustom() != mNumScreens) {
if (mNumScreens > 0 && Float.compare(mCurrentOffset, mFinalOffset) != 0) {
// Don't animate if we're going from 0 screens, or if the final offset is the same
// as the current offset
animateToFinal();
}
mNumScreens = getNumScreensExcludingEmptyAndCustom();
}
}
private void animateToFinal() {
mAnimating = true;
mAnimationStartOffset = mCurrentOffset;
mAnimationStartTime = System.currentTimeMillis();
}