Rewrite animation logic

* Remove old animation-related code. In the past, animations would be applied to a
view everytime getView was called. This is no longer the case so it fixes the issue of
animations triggering everytime the list was scrolled, dialpad opened, etc.

* Make PhoneFavoriteMergedAdapter (and PhoneFavoritesTileAdapter) return stable IDs, so
that they can be used for animations. The ID schemes are described below:
    (N + 1) to -2: CallLogAdapterItems, where N is equal to the number of call log items
    -1: All contacts button
    0 to (N -1): Rows of tiled contacts, where N is equal to the max rows of tiled contacts
    N to infinity: Rows of regular contacts. Their item id is calculated by N + contact_id,
    where contact_id is guaranteed to never be negative.

* Perform animations by saving each view's offset before the data set changes, and then
applying a translation animation to them based on their new offsets in the updated list view.
This is the same method described by the framework team at :
http://graphics-geek.blogspot.com/2013/06/devbytes-animating-listview-deletion.html
    In our case, we need to perform both horizontal and vertical animations because of the
contact tile favorites.

Bug: 10294203

Change-Id: I3ea4ff9995c539267410a264dbbea5ffa02bc6e3
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index 1a78c5f..efbee9b 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -29,6 +29,7 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
@@ -41,6 +42,7 @@
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactTileLoaderFactory;
 import com.android.contacts.common.GeoUtil;
+import com.android.contacts.common.list.ContactEntry;
 import com.android.contacts.common.list.ContactTileView;
 import com.android.contacts.common.list.PhoneNumberListAdapter;
 import com.android.dialer.DialtactsActivity;
@@ -48,6 +50,10 @@
 import com.android.dialer.calllog.ContactInfoHelper;
 import com.android.dialer.calllog.CallLogAdapter;
 import com.android.dialer.calllog.CallLogQueryHandler;
+import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
+
+import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * Fragment for Phone UI's favorite screen.
@@ -58,9 +64,13 @@
  * A contact filter header is also inserted between those adapters' results.
  */
 public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener,
-        CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
+        CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher,
+        PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener {
+
     private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
+
+    private static final int ANIMATION_DURATION = 300;
 
     /**
      * Used with LoaderManager.
@@ -146,6 +156,9 @@
     private SwipeableListView mListView;
     private View mShowAllContactsButton;
 
+    private final HashMap<Long, Integer> mItemIdTopMap = new HashMap<Long, Integer>();
+    private final HashMap<Long, Integer> mItemIdLeftMap = new HashMap<Long, Integer>();
+
     /**
      * Layout used when contacts load is slower than expected and thus "loading" view should be
      * shown.
@@ -168,6 +181,7 @@
         // that will be available on onCreateView().
 
         mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener,
+                this,
                 getResources().getInteger(R.integer.contact_tile_column_count_in_favorites_new),
                 1);
         mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
@@ -321,4 +335,166 @@
         mContactTileAdapter.removePendingContactEntry();
         super.onPause();
     }
+
+    /**
+     * Saves the current view offsets into memory
+     */
+    @SuppressWarnings("unchecked")
+    private void saveOffsets(long... idsInPlace) {
+        final int firstVisiblePosition = mListView.getFirstVisiblePosition();
+        if (DEBUG) {
+            Log.d(TAG, "Child count : " + mListView.getChildCount());
+        }
+        for (int i = 0; i < mListView.getChildCount(); i++) {
+            final View child = mListView.getChildAt(i);
+            final int position = firstVisiblePosition + i;
+            final long itemId = mAdapter.getItemId(position);
+            final int itemViewType = mAdapter.getItemViewType(position);
+            if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
+                // This is a tiled row, so save horizontal offsets instead
+                saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>)
+                        mAdapter.getItem(position), idsInPlace);
+            }
+            if (DEBUG) {
+                Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: "
+                        + child.getTop());
+            }
+            mItemIdTopMap.put(itemId, child.getTop());
+        }
+    }
+
+    private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list,
+            long... idsInPlace) {
+        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 (DEBUG) {
+                Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: "
+                        + child.getTop());
+            }
+            mItemIdLeftMap.put(itemId, child.getLeft());
+        }
+    }
+
+    /*
+     * Performs a animations for a row of tiles
+     */
+    private void performHorizontalAnimations(ContactTileRow row, ArrayList<ContactEntry> list,
+            long[] idsInPlace) {
+        if (mItemIdLeftMap.isEmpty()) {
+            return;
+        }
+        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);
+
+            // Skip animation for this view if the caller specified that it should be
+            // kept in place
+            if (containsId(idsInPlace, itemId)) continue;
+
+            Integer startLeft = mItemIdLeftMap.get(itemId);
+            int left = child.getLeft();
+            if (DEBUG) {
+                Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i +
+                        " Left: " + left);
+            }
+            if (startLeft != null) {
+                if (startLeft != left) {
+                    int delta = startLeft - left;
+                    child.setTranslationX(delta);
+                    child.animate().setDuration(ANIMATION_DURATION).translationX(0);
+                }
+            }
+            // No need to worry about horizontal offsets of new views that come into view since
+            // there is no horizontal scrolling involved.
+        }
+    }
+
+    /*
+     * Performs animations for the list view. If the list item is a row of tiles, horizontal
+     * animations will be performed instead.
+     */
+    private void animateListView(final long... idsInPlace) {
+        if (mItemIdTopMap.isEmpty()) {
+            // 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.
+            return;
+        }
+        final ViewTreeObserver observer = mListView.getViewTreeObserver();
+        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public boolean onPreDraw() {
+                observer.removeOnPreDrawListener(this);
+                final int firstVisiblePosition = mListView.getFirstVisiblePosition();
+                for (int i = 0; i < mListView.getChildCount(); i++) {
+                    final View child = mListView.getChildAt(i);
+                    int position = firstVisiblePosition + i;
+                    final int itemViewType = mAdapter.getItemViewType(position);
+                    if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
+                        // This is a tiled row, so perform horizontal animations instead
+                        performHorizontalAnimations((ContactTileRow) child, (
+                                ArrayList<ContactEntry>) mAdapter.getItem(position), idsInPlace);
+                    }
+
+                    final long itemId = mAdapter.getItemId(position);
+
+                    // Skip animation for this view if the caller specified that it should be
+                    // kept in place
+                    if (containsId(idsInPlace, itemId)) continue;
+
+                    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) {
+                            delta = startTop - top;
+                        }
+                    } else if (!mItemIdLeftMap.containsKey(itemId)) {
+                        // Animate new views along with the others. The catch is that they did not
+                        // exist in the start state, so we must calculate their starting position
+                        // based on neighboring views.
+                        int childHeight = child.getHeight() + mListView.getDividerHeight();
+                        startTop = top + (i > 0 ? childHeight : -childHeight);
+                        delta = startTop - top;
+                    }
+
+                    if (delta != 0) {
+                        child.setTranslationY(delta);
+                        child.animate().setDuration(ANIMATION_DURATION).translationY(0);
+                    }
+                }
+                mItemIdTopMap.clear();
+                mItemIdLeftMap.clear();
+                return true;
+            }
+        });
+    }
+
+    private boolean containsId(long[] ids, long target) {
+        // Linear search on array is fine because this is typically only 0-1 elements long
+        for (int i = 0; i < ids.length; i++) {
+            if (ids[i] == target) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void onDataSetChangedForAnimation(long... idsInPlace) {
+        animateListView(idsInPlace);
+    }
+
+    @Override
+    public void cacheOffsetsForDatasetChange() {
+        saveOffsets();
+    }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
index ce2b627..cbb94b2 100644
--- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
@@ -42,6 +42,7 @@
 
     private static final String TAG = PhoneFavoriteMergedAdapter.class.getSimpleName();
 
+    private static final int ALL_CONTACTS_BUTTON_ITEM_ID = -1;
     private final PhoneFavoritesTileAdapter mContactTileAdapter;
     private final CallLogAdapter mCallLogAdapter;
     private final View mLoadingView;
@@ -95,9 +96,35 @@
         return mContactTileAdapter.getItem(position);
     }
 
+    /**
+     * In order to ensure that items have stable ids (for animation purposes), we need to
+     * guarantee that every single item has a unique ID, even across data set changes.
+     *
+     * These are the ranges of IDs reserved for each item type.
+     *
+     * -(N + 1) to -2: CallLogAdapterItems, where N is equal to the number of call log items
+     * -1: All contacts button
+     * 0 to (N -1): Rows of tiled contacts, where N is equal to the max rows of tiled contacts
+     * N to infinity: Rows of regular contacts. Their item id is calculated by N + contact_id,
+     * where contact_id is guaranteed to never be negative.
+     */
     @Override
     public long getItemId(int position) {
-        return position;
+        final int callLogAdapterCount = mCallLogAdapter.getCount();
+        if (position < callLogAdapterCount) {
+            // Call log items are not animated, so reusing their position for IDs is fine.
+            return ALL_CONTACTS_BUTTON_ITEM_ID - 1 - position;
+        } else if (position < (callLogAdapterCount + mContactTileAdapter.getCount())) {
+            return mContactTileAdapter.getItemId(position - callLogAdapterCount);
+        } else {
+            // All contacts button
+            return ALL_CONTACTS_BUTTON_ITEM_ID;
+        }
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return true;
     }
 
     @Override
diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java
index dc82f73..8887a2c 100644
--- a/src/com/android/dialer/list/PhoneFavoriteTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java
@@ -144,6 +144,18 @@
             animSet.playTogether(fadeIn);
         }
 
+        animSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mParentRow.setHasTransientState(true);
+            };
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mParentRow.setHasTransientState(false);
+            }
+        });
+
         animSet.start();
     }
 
@@ -164,19 +176,22 @@
                 "alpha", 255).setDuration(ANIMATION_LENGTH);
         final AnimatorSet animSet = new AnimatorSet();
         animSet.playTogether(fadeIn, moveBack, backgroundFadeOut);
-        animSet.start();
         animSet.addListener(new AnimatorListenerAdapter() {
             @Override
+            public void onAnimationStart(Animator animation) {
+                mParentRow.setHasTransientState(true);
+            }
+            @Override
             public void onAnimationEnd(Animator animation) {
                 if (mParentRow.getItemViewType() == ViewTypes.FREQUENT) {
                     SwipeHelper.setSwipeable(mParentRow, true);
                 } else {
                     SwipeHelper.setSwipeable(PhoneFavoriteTileView.this, true);
                 }
+                mParentRow.setHasTransientState(false);
             }
         });
-
-
+        animSet.start();
         // Signals the PhoneFavoritesTileAdapter to undo the potential delete.
         mParentRow.getTileAdapter().undoPotentialRemoveEntryIndex();
     }
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index 88520dd..263794f 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -50,6 +50,7 @@
 
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.PriorityQueue;
@@ -67,14 +68,9 @@
 
     public static final int ROW_LIMIT_DEFAULT = 1;
 
-    /** Time period for an animation. */
-    private static final int ANIMATION_LENGTH = 300;
-
-    private final ObjectAnimator mTranslateHorizontalAnimation;
-    private final ObjectAnimator mTranslateVerticalAnimation;
-    private final ObjectAnimator mAlphaAnimation;
-
     private ContactTileView.Listener mListener;
+    private OnDataSetChangedForAnimationListener mDataSetChangedListener;
+
     private Context mContext;
     private Resources mResources;
 
@@ -88,6 +84,7 @@
     private int mDropEntryIndex = -1;
     /** Position of the contact pending removal. */
     private int mPotentialRemoveEntryIndex = -1;
+    private long mIdToKeepInPlace = -1;
 
     private boolean mAwaitingRemove = false;
 
@@ -134,13 +131,15 @@
         }
     };
 
-    public PhoneFavoritesTileAdapter(Context context, ContactTileView.Listener listener,
-            int numCols) {
-        this(context, listener, numCols, ROW_LIMIT_DEFAULT);
-    }
+    public interface OnDataSetChangedForAnimationListener {
+        public void onDataSetChangedForAnimation(long... idsInPlace);
+        public void cacheOffsetsForDatasetChange();
+    };
 
     public PhoneFavoritesTileAdapter(Context context, ContactTileView.Listener listener,
+            OnDataSetChangedForAnimationListener dataSetChangedListener,
             int numCols, int maxTiledRows) {
+        mDataSetChangedListener = dataSetChangedListener;
         mListener = listener;
         mContext = context;
         mResources = context.getResources();
@@ -152,15 +151,6 @@
         mPaddingInPixels = mContext.getResources()
                 .getDimensionPixelSize(R.dimen.contact_tile_divider_padding);
 
-        // Initiates all animations.
-        mAlphaAnimation = ObjectAnimator.ofFloat(null, "alpha", 1.f).setDuration(ANIMATION_LENGTH);
-
-        mTranslateHorizontalAnimation = ObjectAnimator.ofFloat(null, "translationX", 0.f).
-                setDuration(ANIMATION_LENGTH);
-
-        mTranslateVerticalAnimation = ObjectAnimator.ofFloat(null, "translationY", 0.f).setDuration(
-                ANIMATION_LENGTH);
-
         bindColumnIndices();
     }
 
@@ -229,11 +219,21 @@
     public void setContactCursor(Cursor cursor) {
         if (cursor != null && !cursor.isClosed()) {
             mNumStarred = getNumStarredContacts(cursor);
+            if (mAwaitingRemove) {
+                mDataSetChangedListener.cacheOffsetsForDatasetChange();
+            }
+
             saveNumFrequentsFromCursor(cursor);
             saveCursorToCache(cursor);
-
             // cause a refresh of any views that rely on this data
             notifyDataSetChanged();
+            // about to start redraw
+            if (mIdToKeepInPlace != -1) {
+                mDataSetChangedListener.onDataSetChangedForAnimation(mIdToKeepInPlace);
+            } else {
+                mDataSetChangedListener.onDataSetChangedForAnimation();
+            }
+            mIdToKeepInPlace = -1;
         }
     }
 
@@ -440,15 +440,36 @@
         }
     }
 
+    /**
+     * For the top row of tiled contacts, the item id is the position of the row of
+     * contacts.
+     * For frequent contacts, the item id is the maximum number of rows of tiled contacts +
+     * the actual contact id. Since contact ids are always greater than 0, this guarantees that
+     * all items within this adapter will always have unique ids.
+     */
     @Override
     public long getItemId(int position) {
-        // As we show several selectable items for each ListView row,
-        // we can not determine a stable id. But as we don't rely on ListView's selection,
-        // this should not be a problem.
-        return position;
+        if (getItemViewType(position) == ViewTypes.FREQUENT) {
+            return getAdjustedItemId(getItem(position).get(0).id);
+        } else {
+            return position;
+        }
+    }
+
+    /**
+     * Calculates the stable itemId for a particular entry based on its contactID
+     */
+    public long getAdjustedItemId(long id) {
+        return mMaxTiledRows + id;
     }
 
     @Override
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    @Override
+
     public boolean areAllItemsEnabled() {
         // No dividers, so all items are enabled.
         return true;
@@ -467,54 +488,6 @@
         super.notifyDataSetChanged();
     }
 
-    /**
-     * Configures the animation for each view.
-     *
-     * @param contactTileRowView The row to be animated.
-     * @param position The position of the row.
-     * @param itemViewType The type of the row.
-     */
-    private void configureAnimationToView(ContactTileRow contactTileRowView, int position,
-            int itemViewType) {
-        // No need to animate anything if we are just entering a drag, because the blank
-        // entry takes the place of the dragged entry anyway.
-        if (mInDragging) return;
-        if (mDropEntryIndex != -1) {
-            // If one item is dropped in front the row, animate all following rows to shift down.
-            // If the item is a favorite tile, animate it to appear from left.
-            if (position >= getRowIndex(mDropEntryIndex)) {
-                if (itemViewType == ViewTypes.FREQUENT) {
-                    if (position == getRowIndex(mDropEntryIndex) || position == mMaxTiledRows) {
-                        contactTileRowView.setVisibility(View.VISIBLE);
-                        mAlphaAnimation.setTarget(contactTileRowView);
-                        mAlphaAnimation.clone().start();
-                    } else {
-                        mTranslateVerticalAnimation.setTarget(contactTileRowView);
-                        mTranslateVerticalAnimation.setFloatValues(-contactTileRowView.getHeight(),
-                                0);
-                        mTranslateVerticalAnimation.clone().start();
-                    }
-                } else {
-                    contactTileRowView.animateTilesAppearRight(mDropEntryIndex + 1 -
-                            position * mColumnCount);
-                }
-            }
-        } else if (mPotentialRemoveEntryIndex != -1) {
-            // If one item is to be removed above this row, animate the row to shift up. If it is
-            // a favorite contact tile, animate it to appear from right.
-            if (position >= getRowIndex(mPotentialRemoveEntryIndex)) {
-                if (itemViewType == ViewTypes.FREQUENT) {
-                    mTranslateVerticalAnimation.setTarget(contactTileRowView);
-                    mTranslateVerticalAnimation.setFloatValues(contactTileRowView.getHeight(), 0);
-                    mTranslateVerticalAnimation.clone().start();
-                } else {
-                    contactTileRowView.animateTilesAppearLeft(
-                            mPotentialRemoveEntryIndex - position * mColumnCount);
-                }
-            }
-        }
-    }
-
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         if (DEBUG) {
@@ -533,8 +506,6 @@
 
         contactTileRowView.configureRow(contactList, position, position == getCount() - 1);
 
-        configureAnimationToView(contactTileRowView, position, itemViewType);
-
         return contactTileRowView;
     }
 
@@ -572,6 +543,7 @@
         if (index >= 0 && index < mContactEntries.size()) {
             mDraggedEntry = mContactEntries.get(index);
             mContactEntries.set(index, ContactEntry.BLANK_ENTRY);
+            ContactEntry.BLANK_ENTRY.id = mDraggedEntry.id;
             mDraggedEntryIndex = index;
             notifyDataSetChanged();
         }
@@ -590,6 +562,8 @@
                 // When we receive a new cursor the list of contact entries will automatically be
                 // populated with the dragged ContactEntry at the correct spot.
                 mDropEntryIndex = index;
+                mIdToKeepInPlace = getAdjustedItemId(mDraggedEntry.id);
+                mDataSetChangedListener.cacheOffsetsForDatasetChange();
                 changed = true;
             } else if (mDraggedEntryIndex >= 0 && mDraggedEntryIndex <= mContactEntries.size()) {
                 /** If the index is invalid, falls back to the original position of the contact. */
@@ -636,9 +610,8 @@
     public boolean removePendingContactEntry() {
         boolean removed = false;
         if (mPotentialRemoveEntryIndex >= 0 && mPotentialRemoveEntryIndex < mContactEntries.size()) {
-            final ContactEntry entry = mContactEntries.remove(mPotentialRemoveEntryIndex);
+            final ContactEntry entry = mContactEntries.get(mPotentialRemoveEntryIndex);
             unstarAndUnpinContact(entry.lookupKey);
-            notifyDataSetChanged();
             removed = true;
             mAwaitingRemove = true;
         }
@@ -699,7 +672,6 @@
                         R.dimen.favorites_row_start_padding);
                 mRowPaddingEnd = resources.getDimensionPixelSize(
                         R.dimen.favorites_row_end_padding);
-
             } else {
                 // For row views, padding is set on the view itself.
                 mRowPaddingTop = 0;
@@ -744,6 +716,13 @@
                         columnCounter < list.size() ? list.get(columnCounter) : null;
                 addTileFromEntry(entry, columnCounter, isLastRow);
             }
+            if (columnCount == 1) {
+                if (list.get(0) == ContactEntry.BLANK_ENTRY) {
+                    setVisibility(View.INVISIBLE);
+                } else {
+                    setVisibility(View.VISIBLE);
+                }
+            }
             setPressed(false);
             getBackground().setAlpha(255);
         }
@@ -916,24 +895,6 @@
             return PhoneFavoritesTileAdapter.this;
         }
 
-        public void animateTilesAppearLeft(int index) {
-            for (int i = index; i < getChildCount(); ++i) {
-                View childView = getChildAt(i);
-                mTranslateHorizontalAnimation.setTarget(childView);
-                mTranslateHorizontalAnimation.setFloatValues(childView.getWidth(), 0);
-                mTranslateHorizontalAnimation.clone().start();
-            }
-        }
-
-        public void animateTilesAppearRight(int index) {
-            for (int i = index; i < getChildCount(); ++i) {
-                View childView = getChildAt(i);
-                mTranslateHorizontalAnimation.setTarget(childView);
-                mTranslateHorizontalAnimation.setFloatValues(-childView.getWidth(), 0);
-                mTranslateHorizontalAnimation.clone().start();
-            }
-        }
-
         public int getPosition() {
             return mPosition;
         }
diff --git a/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java b/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
index 40d171c..3e3cacd 100644
--- a/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
+++ b/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
@@ -8,7 +8,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mAdapter = new PhoneFavoritesTileAdapter(getContext(), null, 3, 1);
+        mAdapter = new PhoneFavoritesTileAdapter(getContext(), null, null, 3, 1);
     }
 
     /**