From b7e15adc7b67cb1d70ca72014b200dd6cbbf166a Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 7 May 2015 14:51:31 -0700 Subject: Animating the folder title & page indicator when a multi-page folder is opened for the first time Change-Id: I70f5fd942724251a5e863fbb78a0c24f440b0283 --- res/layout/user_folder.xml | 21 ++++++----- src/com/android/launcher3/Folder.java | 49 ++++++++++++++++++++++++-- src/com/android/launcher3/FolderInfo.java | 5 +++ src/com/android/launcher3/FolderPagedView.java | 38 ++++++++++++++++---- 4 files changed, 95 insertions(+), 18 deletions(-) diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml index cd3a051ad..099da32e6 100644 --- a/res/layout/user_folder.xml +++ b/res/layout/user_folder.xml @@ -45,20 +45,16 @@ android:id="@+id/folder_footer" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" > - - + android:orientation="horizontal" + android:paddingLeft="8dp" + android:paddingRight="8dp" > + + \ No newline at end of file diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index a2828054c..f2d7a6991 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -89,6 +89,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList */ private static final float ICON_OVERSCROLL_WIDTH_FACTOR = 0.45f; + public static final int FOOTER_ANIMATION_DURATION = 200; + private static final int REORDER_DELAY = 250; private static final int ON_EXIT_CLOSE_DELAY = 400; private static final Rect sTempRect = new Rect(); @@ -201,10 +203,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); mFooter = findViewById(R.id.folder_footer); - updateFooterHeight(); - } - public void updateFooterHeight() { // We find out how tall footer wants to be (it is set to wrap_content), so that // we can allocate the appropriate amount of space for it. int measureSpec = MeasureSpec.UNSPECIFIED; @@ -529,6 +528,36 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mContent.setFocusOnFirstChild(); } }); + + // Footer animation + if (mContent.getPageCount() > 1 && !mInfo.hasOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION)) { + int footerWidth = mContent.getDesiredWidth() + - mFooter.getPaddingLeft() - mFooter.getPaddingRight(); + + float textWidth = mFolderName.getPaint().measureText(mFolderName.getText().toString()); + mFolderName.setTranslationX((footerWidth - textWidth) / 2); + mContent.setMarkerScale(0); + + // Do not update the flag if we are in drag mode. The flag will be updated, when we + // actually drop the icon. + final boolean updateAnimationFlag = !mDragInProgress; + openFolderAnim.addListener(new AnimatorListenerAdapter() { + + @Override + public void onAnimationEnd(Animator animation) { + mFolderName.animate().setDuration(FOOTER_ANIMATION_DURATION).translationX(0); + mContent.animateMarkers(); + + if (updateAnimationFlag) { + mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher); + } + } + }); + } else { + mFolderName.setTranslationX(0); + mContent.setMarkerScale(1); + } + openFolderAnim.start(); // Make sure the folder picks up the last drag move even if the finger doesn't move. @@ -805,6 +834,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList // Reordering may have occured, and we need to save the new item locations. We do this once // at the end to prevent unnecessary database operations. updateItemLocationsInDatabaseBatch(); + + // Use the item count to check for multi-page as the folder UI may not have + // been refreshed yet. + if (getItemCount() <= mContent.itemsPerPage()) { + // Show the animation, next time something is added to the folder. + mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, false, mLauncher); + } + } @Override @@ -1183,6 +1220,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList // Clear the drag info, as it is no longer being dragged. mCurrentDragInfo = null; mDragInProgress = false; + + if (mContent.getPageCount() > 1) { + // The animation has already been shown while opening the folder. + mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher); + } } // This is used so the item doesn't immediately appear in the folder when added. In one case @@ -1197,6 +1239,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList v.setVisibility(VISIBLE); } + @Override public void onAdd(ShortcutInfo item) { // If the item was dropped onto this open folder, we have done the work associated // with adding the item to the folder, as indicated by mSuppressOnAdd being set diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java index 80b156413..aea21c95b 100644 --- a/src/com/android/launcher3/FolderInfo.java +++ b/src/com/android/launcher3/FolderInfo.java @@ -41,6 +41,11 @@ public class FolderInfo extends ItemInfo { */ public static final int FLAG_WORK_FOLDER = 0x00000002; + /** + * The multi-page animation has run for this folder + */ + public static final int FLAG_MULTI_PAGE_ANIMATION = 0x00000004; + /** * Whether this folder has been opened */ diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java index a1c909a1f..f070a6bba 100644 --- a/src/com/android/launcher3/FolderPagedView.java +++ b/src/com/android/launcher3/FolderPagedView.java @@ -20,9 +20,11 @@ import android.annotation.SuppressLint; import android.content.Context; import android.util.AttributeSet; import android.util.Log; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.animation.DecelerateInterpolator; +import android.view.animation.OvershootInterpolator; import com.android.launcher3.FocusHelper.PagedFolderKeyEventListener; import com.android.launcher3.PageIndicator.PageMarkerResources; @@ -44,6 +46,8 @@ public class FolderPagedView extends PagedView { private static final int START_VIEW_REORDER_DELAY = 30; private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f; + private static final int PAGE_INDICATOR_ANIMATION_DELAY = 150; + /** * Fraction of the width to scroll when showing the next page hint. */ @@ -73,7 +77,7 @@ public class FolderPagedView extends PagedView { private FocusIndicatorView mFocusIndicatorView; private PagedFolderKeyEventListener mKeyListener; - private View mPageIndicator; + private PageIndicator mPageIndicator; public FolderPagedView(Context context, AttributeSet attrs) { super(context, attrs); @@ -101,7 +105,7 @@ public class FolderPagedView extends PagedView { mFolder = folder; mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator); mKeyListener = new PagedFolderKeyEventListener(folder); - mPageIndicator = folder.findViewById(R.id.folder_page_indicator); + mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator); } /** @@ -338,11 +342,8 @@ public class FolderPagedView extends PagedView { setEnableOverscroll(getPageCount() > 1); // Update footer - int indicatorVisibility = mPageIndicator.getVisibility(); mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE); - if (indicatorVisibility != mPageIndicator.getVisibility()) { - mFolder.updateFooterHeight(); - } + mFolder.mFolderName.setGravity(getPageCount() > 1 ? Gravity.START : Gravity.CENTER_HORIZONTAL); } public int getDesiredWidth() { @@ -628,4 +629,29 @@ public class FolderPagedView extends PagedView { } } } + + public void setMarkerScale(float scale) { + int count = mPageIndicator.getChildCount(); + for (int i = 0; i < count; i++) { + View marker = mPageIndicator.getChildAt(i); + marker.animate().cancel(); + marker.setScaleX(scale); + marker.setScaleY(scale); + } + } + + public void animateMarkers() { + int count = mPageIndicator.getChildCount(); + OvershootInterpolator interpolator = new OvershootInterpolator(4); + for (int i = 0; i < count; i++) { + mPageIndicator.getChildAt(i).animate().scaleX(1).scaleY(1) + .setInterpolator(interpolator) + .setDuration(Folder.FOOTER_ANIMATION_DURATION) + .setStartDelay(PAGE_INDICATOR_ANIMATION_DELAY * i); + } + } + + public int itemsPerPage() { + return mMaxItemsPerPage; + } } -- cgit v1.2.3