New search fragment now animates and moves with the search box and dialpad.

video: https://drive.google.com/open?id=0B2Hce9qilHmvYTlqVGU0OTNxNjQ
Bug: 37209462
Test: SearchFragmentIntegrationTest
PiperOrigin-RevId: 164319452
Change-Id: Icc5669be87e97ba5d0e23fc99bada28ca7d2335a
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index 1c9718e..99a16d9 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -678,6 +678,7 @@
       mListsFragment.addOnPageChangeListener(this);
     } else if (fragment instanceof NewSearchFragment) {
       mNewSearchFragment = (NewSearchFragment) fragment;
+      updateSearchFragmentPosition();
     }
     if (fragment instanceof SearchFragment) {
       final SearchFragment searchFragment = (SearchFragment) fragment;
@@ -951,6 +952,12 @@
       // available immediately which is required to update position. By forcing an animation,
       // position will be updated after a delay by when the dialpad height would be available.
       fragment.updatePosition(true /* animate */);
+    } else if (mNewSearchFragment != null) {
+      int animationDuration = getResources().getInteger(R.integer.dialpad_slide_in_duration);
+      int shadowHeight = getResources().getDrawable(R.drawable.search_shadow).getIntrinsicHeight();
+      int start = isDialpadShown() ? mActionBarHeight - shadowHeight : 0;
+      int end = isDialpadShown() ? 0 : mActionBarHeight - shadowHeight;
+      mNewSearchFragment.animatePosition(start, end, animationDuration);
     }
   }
 
diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
index d20bb1f..566ba77 100644
--- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
+++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java
@@ -27,10 +27,13 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.Interpolator;
 import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor;
+import com.android.dialer.animation.AnimUtils;
 import com.android.dialer.common.concurrent.ThreadUtil;
 import com.android.dialer.searchfragment.cp2.SearchContactsCursorLoader;
 import com.android.dialer.searchfragment.nearbyplaces.NearbyPlacesCursorLoader;
+import com.android.dialer.util.ViewUtil;
 
 /** Fragment used for searching contacts. */
 public final class NewSearchFragment extends Fragment implements LoaderCallbacks<Cursor> {
@@ -49,6 +52,8 @@
   private final Runnable loadNearbyPlacesRunnable =
       () -> getLoaderManager().restartLoader(NEARBY_PLACES_ID, null, this);
 
+  private Runnable updatePositionRunnable;
+
   @Nullable
   @Override
   public View onCreateView(
@@ -62,6 +67,10 @@
 
     getLoaderManager().initLoader(CONTACTS_LOADER_ID, null, this);
     loadNearbyPlacesCursor();
+
+    if (updatePositionRunnable != null) {
+      ViewUtil.doOnPreDraw(view, false, updatePositionRunnable);
+    }
     return view;
   }
 
@@ -102,6 +111,19 @@
     }
   }
 
+  public void animatePosition(int start, int end, int duration) {
+    // Called before the view is ready, prepare a runnable to run in onCreateView
+    if (getView() == null) {
+      updatePositionRunnable = () -> animatePosition(start, end, 0);
+      return;
+    }
+    boolean slideUp = start > end;
+    Interpolator interpolator = slideUp ? AnimUtils.EASE_IN : AnimUtils.EASE_OUT;
+    getView().setTranslationY(start);
+    getView().animate().translationY(end).setInterpolator(interpolator).setDuration(duration);
+    updatePositionRunnable = null;
+  }
+
   @Override
   public void onDestroy() {
     super.onDestroy();