Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b2e2109 authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Smooth drag and drop scrolling

Bug: 10686781
Change-Id: I4435b5b1087c132d1f94978489cdacac1ac519f3
parent eaebb31a
Loading
Loading
Loading
Loading
+58 −15
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.dialer.list;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -140,6 +143,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            mActivityScrollListener.onListFragmentScrollStateChange(scrollState);
            mLastScrollState = scrollState;
        }
    }

@@ -182,6 +186,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
            new ContactTileLoaderListener();
    private final ScrollListener mScrollListener = new ScrollListener();

    private int mLastScrollState = ListView.OnScrollListener.SCROLL_STATE_IDLE;

    @Override
    public void onAttach(Activity activity) {
        if (DEBUG) Log.d(TAG, "onAttach()");
@@ -404,18 +410,41 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
        if (mItemIdLeftMap.isEmpty()) {
            return;
        }
        final AnimatorSet animSet = new AnimatorSet();
        final ArrayList<Animator> animators = new ArrayList<Animator>();
        for (int i = 0; i < list.size(); i++) {
            final View child = row.getChildAt(i);
            final ContactEntry entry = list.get(i);
            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);

            if (containsId(idsInPlace, itemId)) {
                child.setAlpha(0.0f);
                child.animate().alpha(1.0f)
                        .setDuration(mAnimationDuration)
                        .start();
                animators.add(ObjectAnimator.ofFloat(
                        child, "alpha", 0.0f, 1.0f));
                break;
            } else {
                Integer startLeft = mItemIdLeftMap.get(itemId);
                int left = child.getLeft();
                if (startLeft != null) {
                    if (startLeft != left) {
                        int delta = startLeft - left;
                        if (DEBUG) {
                            Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i +
                                    " Left: " + left +
                                    " Delta: " + delta);
                        }
                        animators.add(ObjectAnimator.ofFloat(
                                child, "translationX", delta, 0.0f));
                    }
                } else {
                    // In case the last square row is pushed up from the non-square section.
                    animators.add(ObjectAnimator.ofFloat(
                            child, "translationX", left, 0.0f));
                }
            }
        }
        if (animators.size() > 0) {
            animSet.setDuration(mAnimationDuration).playTogether(animators);
            animSet.start();
        }
    }

@@ -424,7 +453,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
     * animations will be performed instead.
     */
    private void animateListView(final long... idsInPlace) {
        if (mItemIdTopMap.isEmpty()) {
        if (mItemIdTopMap.isEmpty() ||
                mLastScrollState == ListView.OnScrollListener.SCROLL_STATE_FLING) {
            // Don't do animations if the database is being queried for the first time and
            // the previous item offsets have not been cached, or the user hasn't done anything
            // (dragging, swiping etc) that requires an animation.
@@ -437,6 +467,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
            public boolean onPreDraw() {
                observer.removeOnPreDrawListener(this);
                final int firstVisiblePosition = mListView.getFirstVisiblePosition();
                final AnimatorSet animSet = new AnimatorSet();
                final ArrayList<Animator> animators = new ArrayList<Animator>();
                for (int i = 0; i < mListView.getChildCount(); i++) {
                    final View child = mListView.getChildAt(i);
                    int position = firstVisiblePosition + i;
@@ -450,17 +482,12 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
                    final long itemId = mAdapter.getItemId(position);

                    if (containsId(idsInPlace, itemId)) {
                        child.setAlpha(0.0f);
                        child.animate().alpha(1.0f)
                                .setDuration(mAnimationDuration)
                                .start();
                        animators.add(ObjectAnimator.ofFloat(
                                child, "alpha", 0.0f, 1.0f));
                        break;
                    } else {
                        Integer startTop = mItemIdTopMap.get(itemId);
                        final int top = child.getTop();
                        if (DEBUG) {
                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
                                    " Top: " + top);
                        }
                        int delta = 0;
                        if (startTop != null) {
                            if (startTop != top) {
@@ -473,14 +500,30 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
                            int childHeight = child.getHeight() + mListView.getDividerHeight();
                            startTop = top + (i > 0 ? childHeight : -childHeight);
                            delta = startTop - top;
                        } else {
                            // In the case the first non-square row is pushed down
                            // from the square section.
                            animators.add(ObjectAnimator.ofFloat(
                                    child, "translationX", -child.getWidth(), 0.0f));
                        }
                        if (DEBUG) {
                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
                                    " Top: " + top +
                                    " Delta: " + delta);
                        }

                        if (delta != 0) {
                            child.setTranslationY(delta);
                            child.animate().setDuration(mAnimationDuration).translationY(0);
                            animators.add(ObjectAnimator.ofFloat(
                                    child, "translationY", delta, 0.0f));
                        }
                    }
                }

                if (animators.size() > 0) {
                    animSet.setDuration(mAnimationDuration).playTogether(animators);
                    animSet.start();
                }

                mItemIdTopMap.clear();
                mItemIdLeftMap.clear();
                return true;
+2 −11
Original line number Diff line number Diff line
@@ -105,7 +105,8 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba

    private final AnimatorListenerAdapter mDragShadowOverAnimatorListener =
            new AnimatorListenerAdapter() {
        private void recycleDragShadow() {
        @Override
        public void onAnimationEnd(Animator animation) {
            if (mDragShadowBitmap != null) {
                mDragShadowBitmap.recycle();
                mDragShadowBitmap = null;
@@ -113,16 +114,6 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba
            mDragShadowOverlay.setVisibility(GONE);
            mDragShadowOverlay.setImageBitmap(null);
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            recycleDragShadow();
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            recycleDragShadow();
        }
    };

    public PhoneFavoriteListView(Context context) {
+4 −1
Original line number Diff line number Diff line
@@ -407,7 +407,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements
        return mColumnCount * mMaxTiledRows;
    }

    protected int getRowIndex(int entryIndex) {
    public int getRowIndex(int entryIndex) {
        if (entryIndex < mMaxTiledRows * mColumnCount) {
            return entryIndex / mColumnCount;
        } else {
@@ -593,11 +593,14 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements
     */
    private void markDropArea(int itemIndex) {
        if (isIndexInBound(mDragEnteredEntryIndex) && isIndexInBound(itemIndex)) {
            mDataSetChangedListener.cacheOffsetsForDatasetChange();
            // Remove the old placeholder item and place the new placeholder item.
            final int oldIndex = mDragEnteredEntryIndex;
            mContactEntries.remove(mDragEnteredEntryIndex);
            mDragEnteredEntryIndex = itemIndex;
            mContactEntries.add(mDragEnteredEntryIndex, ContactEntry.BLANK_ENTRY);
            ContactEntry.BLANK_ENTRY.id = mDraggedEntry.id;
            mDataSetChangedListener.onDataSetChangedForAnimation();
            notifyDataSetChanged();
        }
    }
+1 −13
Original line number Diff line number Diff line
@@ -337,24 +337,12 @@ public class SwipeHelper {
                invalidateGlobalRegion(animView);
            }
        });
        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                animView.setAlpha(mStartAlpha);
                mCallback.onDragCancelled(mCurrView);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        anim.start();
    }