Add slide up transition when call shortcut is dismissed
Add animations to the favorites list view that occur when
the most recent call shortcut is dismissed.
The previous implementation would call removeAllViews on the
call shortcut once it had been dismissed. This would cause the rest
of the list view to appear to jump up into place instead of animating
smoothly.
Instead, we now use the same animation logic in PhoneFavoritesFragment
by saving the offsets of the rest of the list items once the shortcut
is dismissed, and then assigning animations to the new list items
when a new dataset arrives in onCallsFetched.
Also, additional logic needs to be added to the animation logic because
call shortcuts are taller than regular contacts. The previous code made
the assumption that the removed item would always be the same height as
all other list items, but this is not the case here. We thus save the
height of the removed call shortcut as a special value in mItemIdTopMap
and retrieve it to correctly calculate translation offsets instead.
Bug: 10915363
Change-Id: I81bd711c5a3a34bdb4c4f5a311b91fb6ee1539c0
diff --git a/res/layout/phone_favorites_fragment.xml b/res/layout/phone_favorites_fragment.xml
index f518f0b..363565a 100644
--- a/res/layout/phone_favorites_fragment.xml
+++ b/res/layout/phone_favorites_fragment.xml
@@ -27,7 +27,7 @@
<FrameLayout
android:id="@+id/contact_tile_frame"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index d4fa7d4..8ff9766 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -73,6 +73,15 @@
CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher,
PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener {
+ /**
+ * By default, the animation code assumes that all items in a list view are of the same height
+ * when animating new list items into view (e.g. from the bottom of the screen into view).
+ * This can cause incorrect translation offsets when a item that is larger or smaller than
+ * other list item is removed from the list. This key is used to provide the actual height
+ * of the removed object so that the actual translation appears correct to the user.
+ */
+ private static final long KEY_REMOVED_ITEM_HEIGHT = Long.MAX_VALUE;
+
private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
private static final boolean DEBUG = false;
@@ -378,6 +387,7 @@
@Override
public void onCallsFetched(Cursor cursor) {
+ animateListView();
mCallLogAdapter.setLoading(false);
// Save the date of the most recent call log item
@@ -386,7 +396,6 @@
}
mCallLogAdapter.changeCursor(cursor);
-
mAdapter.notifyDataSetChanged();
}
@@ -409,7 +418,7 @@
* Saves the current view offsets into memory
*/
@SuppressWarnings("unchecked")
- private void saveOffsets(long... idsInPlace) {
+ private void saveOffsets(int removedItemHeight) {
final int firstVisiblePosition = mListView.getFirstVisiblePosition();
if (DEBUG) {
Log.d(TAG, "Child count : " + mListView.getChildCount());
@@ -422,7 +431,7 @@
if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
// This is a tiled row, so save horizontal offsets instead
saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>)
- mAdapter.getItem(position), idsInPlace);
+ mAdapter.getItem(position));
}
if (DEBUG) {
Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: "
@@ -430,10 +439,11 @@
}
mItemIdTopMap.put(itemId, child.getTop());
}
+
+ mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight);
}
- private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list,
- long... idsInPlace) {
+ private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list) {
for (int i = 0; i < list.size(); i++) {
final View child = row.getChildAt(i);
final ContactEntry entry = list.get(i);
@@ -503,6 +513,9 @@
// (dragging, swiping etc) that requires an animation.
return;
}
+
+ final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT);
+
final ViewTreeObserver observer = mListView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@SuppressWarnings("unchecked")
@@ -540,8 +553,14 @@
// 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);
+
+ final int itemHeight;
+ if (removedItemHeight == 0) {
+ itemHeight = child.getHeight() + mListView.getDividerHeight();
+ } else {
+ itemHeight = removedItemHeight;
+ }
+ startTop = top + (i > 0 ? itemHeight : -itemHeight);
delta = startTop - top;
} else {
// In case the first non-square row is pushed down
@@ -591,10 +610,11 @@
@Override
public void cacheOffsetsForDatasetChange() {
- saveOffsets();
+ saveOffsets(0);
}
- public void dismissShortcut() {
+ public void dismissShortcut(int height) {
+ saveOffsets(height);
mLastCallShortcutDate = mCurrentCallShortcutDate;
final SharedPreferences prefs = getActivity().getSharedPreferences(
DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
index 3347437..1f577c1 100644
--- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
@@ -71,7 +71,7 @@
mCallLogQueryHandler.markNewVoicemailsAsOld();
CallLogNotificationsHelper.removeMissedCallNotifications();
CallLogNotificationsHelper.updateVoicemailNotifications(mContext);
- mFragment.dismissShortcut();
+ mFragment.dismissShortcut(((View) view.getParent()).getHeight());
}
@Override
@@ -217,6 +217,10 @@
final View view = mCallLogAdapter.getView(position, convertView == null ?
null : wrapper.getChildAt(0), parent);
wrapper.removeAllViews();
+ final View callLogItem = view.findViewById(R.id.call_log_list_item);
+ // Reset the internal call log item view if it is being recycled
+ callLogItem.setTranslationX(0);
+ callLogItem.setAlpha(1);
wrapper.addView(view);
return wrapper;
}
@@ -319,7 +323,6 @@
if (v != null && mOnItemSwipeListener != null) {
mOnItemSwipeListener.onSwipe(v);
}
- removeAllViews();
}
@Override