OSDN Git Service

Fix RTL bugs with wallpaper parallax
authorMichael Jurka <mikejurka@google.com>
Thu, 3 Oct 2013 08:05:14 +0000 (01:05 -0700)
committerMichael Jurka <mikejurka@google.com>
Thu, 3 Oct 2013 23:19:06 +0000 (16:19 -0700)
Bug: 10901046

Change-Id: Id4277173b0c13d25eb0507bd6fa9fa1309946510

res/layout/wallpaper_picker.xml
src/com/android/launcher3/PagedView.java
src/com/android/launcher3/WallpaperCropActivity.java
src/com/android/launcher3/WallpaperPickerActivity.java
src/com/android/launcher3/Workspace.java

index 3058a3c..fd66a57 100644 (file)
@@ -48,6 +48,7 @@
             android:layout_height="2dp"
             android:background="@drawable/tile_shadow_top" />
         <HorizontalScrollView
+            android:id="@+id/wallpaper_scroll_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" >
             <LinearLayout android:id="@+id/master_wallpaper_list"
index fcc1aff..c8e34dd 100644 (file)
@@ -265,6 +265,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
 
     protected final Rect mInsets = new Rect();
 
+    protected int mFirstChildLeft;
+
     public interface PageSwitchListener {
         void onPageSwitch(View newPage, int newPageIndex);
     }
@@ -857,6 +859,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
         requestLayout();
     }
 
+    protected int getFirstChildLeft() {
+        return mFirstChildLeft;
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         if (!mIsDataReady || getChildCount() == 0) {
@@ -881,8 +887,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
         final int delta = isRtl ? -1 : 1;
 
         int verticalPadding = getPaddingTop() + getPaddingBottom();
-        int childLeft = offsetX + (screenWidth - getChildWidth(startIndex)) / 2;
 
+        int childLeft = mFirstChildLeft = offsetX + (screenWidth - getChildWidth(startIndex)) / 2;
         if (mPageScrolls == null || getChildCount() != mChildCountOnLastLayout) {
             mPageScrolls = new int[getChildCount()];
         }
index 343d0ff..703db9a 100644 (file)
@@ -221,9 +221,11 @@ public class WallpaperCropActivity extends Activity {
 
     protected void cropImageAndSetWallpaper(Uri uri,
             OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
-     // Get the crop
+        // Get the crop
         Point inSize = mCropView.getSourceDimensions();
 
+        boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
+
         Point minDims = new Point();
         Point maxDims = new Point();
         Display d = getWindowManager().getDefaultDisplay();
@@ -234,12 +236,12 @@ public class WallpaperCropActivity extends Activity {
 
         int maxDim = Math.max(maxDims.x, maxDims.y);
         final int minDim = Math.min(minDims.x, minDims.y);
-        int defaultWidth;
+        int defaultWallpaperWidth;
         if (isScreenLarge(getResources())) {
-            defaultWidth = (int) (maxDim *
+            defaultWallpaperWidth = (int) (maxDim *
                     wallpaperTravelToScreenWidthRatio(maxDim, minDim));
         } else {
-            defaultWidth = Math.max((int)
+            defaultWallpaperWidth = Math.max((int)
                     (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
         }
 
@@ -264,12 +266,17 @@ public class WallpaperCropActivity extends Activity {
 
         // ADJUST CROP WIDTH
         // Extend the crop all the way to the right, for parallax
-        float extraSpaceToRight = inSize.x - cropRect.right;
+        // (or all the way to the left, in RTL)
+        float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
         // Cap the amount of extra width
-        float maxExtraSpace = defaultWidth / cropScale - cropRect.width();
-        extraSpaceToRight = Math.min(extraSpaceToRight, maxExtraSpace);
+        float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
+        extraSpace = Math.min(extraSpace, maxExtraSpace);
 
-        cropRect.right += extraSpaceToRight;
+        if (ltr) {
+            cropRect.right += extraSpace;
+        } else {
+            cropRect.left -= extraSpace;
+        }
 
         // ADJUST CROP HEIGHT
         if (isPortrait) {
index 7f49c86..12e69d3 100644 (file)
@@ -50,9 +50,12 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
@@ -278,6 +281,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
             public void onChanged() {
                 liveWallpapersView.removeAllViews();
                 populateWallpapersFromAdapter(liveWallpapersView, a, false, false);
+                initializeScrollForRtl();
             }
         });
 
@@ -303,12 +307,16 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
             galleryThumbnailBg.setImageBitmap(getThumbnailOfLastPhoto());
             int colorOverlay = getResources().getColor(R.color.wallpaper_picker_translucent_gray);
             galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP);
+
         }
 
         PickImageInfo pickImageInfo = new PickImageInfo();
         galleryThumbnail.setTag(pickImageInfo);
         galleryThumbnail.setOnClickListener(mThumbnailOnClickListener);
 
+        // Update the scroll for RTL
+        initializeScrollForRtl();
+
         // Create smooth layout transitions for when items are deleted
         final LayoutTransition transitioner = new LayoutTransition();
         transitioner.setDuration(200);
@@ -409,6 +417,23 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
         };
     }
 
+    private void initializeScrollForRtl() {
+        final HorizontalScrollView scroll =
+                (HorizontalScrollView) findViewById(R.id.wallpaper_scroll_container);
+
+        if (scroll.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+            final ViewTreeObserver observer = scroll.getViewTreeObserver();
+            observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+                public void onGlobalLayout() {
+                    LinearLayout masterWallpaperList =
+                            (LinearLayout) findViewById(R.id.master_wallpaper_list);
+                    scroll.scrollTo(masterWallpaperList.getWidth(), 0);
+                    scroll.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                }
+            });
+        }
+    }
+
     public boolean enableRotation() {
         return super.enableRotation() || Launcher.sForceEnableRotation;
     }
index 5a40d44..5a8472c 100644 (file)
@@ -617,7 +617,7 @@ public class Workspace extends SmoothPagedView
 
     public boolean hasExtraEmptyScreen() {
         int nScreens = getChildCount();
-        nScreens = hasCustomContent() ? nScreens - 1 : nScreens;
+        nScreens = nScreens - numCustomPages();
         return mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID) && nScreens > 1;
     }
 
@@ -691,7 +691,7 @@ public class Workspace extends SmoothPagedView
 
         // We enforce at least one page to add new items to. In the case that we remove the last
         // such screen, we convert the last screen to the empty screen
-        int minScreens = hasCustomContent() ? 2 : 1;
+        int minScreens = 1 + numCustomPages();
 
         int pageShift = 0;
         for (Long id: removeScreens) {
@@ -1075,7 +1075,7 @@ public class Workspace extends SmoothPagedView
         float mAnimationStartOffset;
         private final int ANIMATION_DURATION = 250;
         // Don't use all the wallpaper for parallax until you have at least this many pages
-        private final int MIN_PARALLAX_PAGE_SPAN = 4;
+        private final int MIN_PARALLAX_PAGE_SPAN = 3;
         int mNumScreens;
 
         public WallpaperOffsetInterpolator() {
@@ -1131,12 +1131,15 @@ public class Workspace extends SmoothPagedView
             }
 
             // Exclude the leftmost page
-            final int startPage = hasCustomContent() ? 1 : 0;
-            final int firstIndex = isLayoutRtl() ? getChildCount() - 1 - startPage : startPage;
+            int emptyExtraPages = numEmptyScreensToIgnore();
+            int firstIndex = numCustomPages();
             // Exclude the last extra empty screen (if we have > MIN_PARALLAX_PAGE_SPAN pages)
-            int emptyExtraPages = numExtraScreensToIgnore();
-            final int lastIndex =
-                    isLayoutRtl() ? 0 + emptyExtraPages : getChildCount() - 1 - emptyExtraPages;
+            int lastIndex = getChildCount() - 1 - emptyExtraPages;
+            if (isLayoutRtl()) {
+                int temp = firstIndex;
+                firstIndex = lastIndex;
+                lastIndex = temp;
+            }
 
             int firstPageScrollX = getScrollForPage(firstIndex);
             int scrollRange = getScrollForPage(lastIndex) - firstPageScrollX;
@@ -1144,28 +1147,36 @@ public class Workspace extends SmoothPagedView
                 return 0;
             } else {
                 // TODO: do different behavior if it's  a live wallpaper?
-                float offset = Math.min(1, (getScrollX() - firstPageScrollX) / (float) scrollRange);
+                // 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 offsetForLayoutTransitionAnimation = isLayoutRtl() ?
+                        getPageAt(getChildCount() - 1).getLeft() - getFirstChildLeft() : 0;
+                int adjustedScroll =
+                        getScrollX() - firstPageScrollX - offsetForLayoutTransitionAnimation;
+                float offset = Math.min(1, adjustedScroll / (float) scrollRange);
                 offset = Math.max(0, offset);
                 // Don't use up all the wallpaper parallax until you have at least
                 // MIN_PARALLAX_PAGE_SPAN pages
-                int numScrollingPages = getNumScreensExcludingExtraEmptyScreenAndLeftmost();
-                int parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages) - 1;
-                return offset * (numScrollingPages - 1) / parallaxPageSpan;
+                int numScrollingPages = getNumScreensExcludingEmptyAndCustom();
+                int parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages - 1);
+                // On RTL devices, push the wallpaper offset to the right if we don't have enough
+                // pages (ie if numScrollingPages < MIN_PARALLAX_PAGE_SPAN)
+                int padding = isLayoutRtl() ? parallaxPageSpan - numScrollingPages + 1 : 0;
+                return offset * (padding + numScrollingPages - 1) / parallaxPageSpan;
             }
         }
 
-        private int numExtraScreensToIgnore() {
-            int numScrollingPages = getChildCount() - 1;
-            if (numScrollingPages > MIN_PARALLAX_PAGE_SPAN && hasExtraEmptyScreen()) {
+        private int numEmptyScreensToIgnore() {
+            int numScrollingPages = getChildCount() - numCustomPages();
+            if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && hasExtraEmptyScreen()) {
                 return 1;
             } else {
                 return 0;
             }
         }
 
-        private int getNumScreensExcludingExtraEmptyScreenAndLeftmost() {
-            int numScrollingPages = getChildCount() - numExtraScreensToIgnore();
-            if (hasCustomContent()) numScrollingPages -= 1;
+        private int getNumScreensExcludingEmptyAndCustom() {
+            int numScrollingPages = getChildCount() - numEmptyScreensToIgnore() - numCustomPages();
             return numScrollingPages;
         }
 
@@ -1197,12 +1208,12 @@ public class Workspace extends SmoothPagedView
         public void setFinalX(float x) {
             scheduleUpdate();
             mFinalOffset = Math.max(0f, Math.min(x, 1.0f));
-            if (getNumScreensExcludingExtraEmptyScreenAndLeftmost() != mNumScreens) {
+            if (getNumScreensExcludingEmptyAndCustom() != mNumScreens) {
                 if (mNumScreens > 0) {
                     // Don't animate if we're going from 0 screens
                     animateToFinal();
                 }
-                mNumScreens = getNumScreensExcludingExtraEmptyScreenAndLeftmost();
+                mNumScreens = getNumScreensExcludingEmptyAndCustom();
             }
         }
 
@@ -1356,6 +1367,10 @@ public class Workspace extends SmoothPagedView
         return (mScreenOrder.size() > 0 && mScreenOrder.get(0) == CUSTOM_CONTENT_SCREEN_ID);
     }
 
+    public int numCustomPages() {
+        return hasCustomContent() ? 1 : 0;
+    }
+
     public boolean isOnOrMovingToCustomContent() {
         return hasCustomContent() && getNextPage() == 0;
     }
@@ -1735,9 +1750,7 @@ public class Workspace extends SmoothPagedView
 
     @Override
     protected void getOverviewModePages(int[] range) {
-        int count = mScreenOrder.size();
-
-        int start = hasCustomContent() ? 1 : 0;
+        int start = numCustomPages();
         int end = getChildCount() - 1;
 
         range[0] = Math.max(0, Math.min(start, getChildCount() - 1));
@@ -4277,7 +4290,7 @@ public class Workspace extends SmoothPagedView
     protected PageIndicator.PageMarkerResources getPageIndicatorMarker(int pageIndex) {
         long screenId = getScreenIdForPageIndex(pageIndex);
         if (screenId == EXTRA_EMPTY_SCREEN_ID) {
-            int count = mScreenOrder.size() - (hasCustomContent() ? 1 : 0);
+            int count = mScreenOrder.size() - numCustomPages();
             if (count > 1) {
                 return new PageIndicator.PageMarkerResources(R.drawable.ic_pageindicator_current,
                         R.drawable.ic_pageindicator_add);