From 026ed57ba679b63d165743a4162f54435449281d Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Tue, 20 Mar 2018 13:49:26 -0700 Subject: Mitigate some of the jank in opening/closeing search. There is still some jank on first open, but it's much less janky on close and consecutive open calls. Test: existing tests confirm no regressions PiperOrigin-RevId: 189802733 Change-Id: I49d6c2def7c33be0fdbb79c89772a5e4513cde3b --- .../dialer/main/impl/MainSearchController.java | 51 +++++++----------- .../dialer/main/impl/OldMainActivityPeer.java | 8 +-- .../dialer/main/impl/res/layout/main_activity.xml | 35 +++++++------ .../dialer/main/impl/toolbar/MainToolbar.java | 60 ++++++++++------------ .../dialer/main/impl/toolbar/SearchBarView.java | 1 - 5 files changed, 69 insertions(+), 86 deletions(-) (limited to 'java/com/android/dialer/main') diff --git a/java/com/android/dialer/main/impl/MainSearchController.java b/java/com/android/dialer/main/impl/MainSearchController.java index 46f6a90b9..c2ff0512a 100644 --- a/java/com/android/dialer/main/impl/MainSearchController.java +++ b/java/com/android/dialer/main/impl/MainSearchController.java @@ -84,6 +84,9 @@ public class MainSearchController implements SearchBarListener { private final MainToolbar toolbar; private final View toolbarShadow; + /** View located underneath the toolbar that needs to animate with it. */ + private final View fragmentContainer; + private final List onSearchShowListenerList = new ArrayList<>(); /** @@ -91,7 +94,6 @@ public class MainSearchController implements SearchBarListener { * want to wait until onPause is called otherwise the transition will look extremely janky. */ private boolean closeSearchOnPause; - private boolean requestingPermission; public MainSearchController( @@ -99,12 +101,14 @@ public class MainSearchController implements SearchBarListener { BottomNavBar bottomNav, FloatingActionButton fab, MainToolbar toolbar, - View toolbarShadow) { + View toolbarShadow, + View fragmentContainer) { this.activity = activity; this.bottomNav = bottomNav; this.fab = fab; this.toolbar = toolbar; this.toolbarShadow = toolbarShadow; + this.fragmentContainer = fragmentContainer; } /** Should be called if we're showing the dialpad because of a new ACTION_DIAL intent. */ @@ -134,9 +138,10 @@ public class MainSearchController implements SearchBarListener { Logger.get(activity).logScreenView(ScreenEvent.Type.MAIN_DIALPAD, activity); fab.hide(); - toolbar.slideUp(animate); + toolbar.slideUp(animate, fragmentContainer); toolbar.expand(animate, Optional.absent()); toolbarShadow.setVisibility(View.VISIBLE); + activity.setTitle(R.string.dialpad_activity_title); FragmentTransaction transaction = activity.getFragmentManager().beginTransaction(); @@ -147,19 +152,13 @@ public class MainSearchController implements SearchBarListener { // TODO(a bug): zero suggest results aren't actually shown but this enabled the nearby // places promo to be shown. searchFragment = NewSearchFragment.newInstance(/* showZeroSuggest=*/ true); - transaction.replace(R.id.fragment_container, searchFragment, SEARCH_FRAGMENT_TAG); - transaction.addToBackStack(null); + transaction.add(R.id.search_fragment_container, searchFragment, SEARCH_FRAGMENT_TAG); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); } else if (!isSearchVisible()) { transaction.show(searchFragment); } searchFragment.setQuery("", CallInitiationType.Type.DIALPAD); - // Split the transactions so that the dialpad fragment isn't popped off the stack when we exit - // search. We do this so that the dialpad actually animates down instead of just disappearing. - transaction.commit(); - transaction = activity.getFragmentManager().beginTransaction(); - // Show Dialpad if (getDialpadFragment() == null) { DialpadFragment dialpadFragment = new DialpadFragment(); @@ -184,12 +183,12 @@ public class MainSearchController implements SearchBarListener { * * @see {@link #closeSearch(boolean)} to "remove" the dialpad. */ - private void hideDialpad(boolean animate, boolean bottomNavVisible) { + private void hideDialpad(boolean animate) { LogUtil.enterBlock("MainSearchController.hideDialpad"); Assert.checkArgument(isDialpadVisible()); fab.show(); - toolbar.slideDown(animate); + toolbar.slideDown(animate, fragmentContainer); toolbar.transferQueryFromDialpad(getDialpadFragment().getQuery()); activity.setTitle(R.string.main_activity_label); @@ -199,15 +198,7 @@ public class MainSearchController implements SearchBarListener { animate, new AnimationListener() { @Override - public void onAnimationStart(Animation animation) { - // Slide the bottom nav on animation start so it's (not) visible when the dialpad - // finishes animating down. - if (bottomNavVisible) { - showBottomNav(); - } else { - hideBottomNav(); - } - } + public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { @@ -257,7 +248,7 @@ public class MainSearchController implements SearchBarListener { } else { Logger.get(activity) .logImpression(DialerImpression.Type.MAIN_TOUCH_DIALPAD_SEARCH_LIST_TO_HIDE_DIALPAD); - hideDialpad(/* animate=*/ true, /* bottomNavVisible=*/ false); + hideDialpad(/* animate=*/ true); } } else if (isSearchVisible()) { if (TextUtils.isEmpty(toolbar.getQuery())) { @@ -282,7 +273,7 @@ public class MainSearchController implements SearchBarListener { LogUtil.i("MainSearchController.onBackPressed", "Dialpad visible with query"); Logger.get(activity) .logImpression(DialerImpression.Type.MAIN_PRESS_BACK_BUTTON_TO_HIDE_DIALPAD); - hideDialpad(/* animate=*/ true, /* bottomNavVisible=*/ false); + hideDialpad(/* animate=*/ true); return true; } else if (isSearchVisible()) { LogUtil.i("MainSearchController.onBackPressed", "Search is visible"); @@ -298,22 +289,19 @@ public class MainSearchController implements SearchBarListener { } } - /** - * Calls {@link #hideDialpad(boolean, boolean)}, removes the search fragment and clears the - * dialpad. - */ + /** Calls {@link #hideDialpad(boolean)}, removes the search fragment and clears the dialpad. */ private void closeSearch(boolean animate) { LogUtil.enterBlock("MainSearchController.closeSearch"); Assert.checkArgument(isSearchVisible()); if (isDialpadVisible()) { - hideDialpad(animate, /* bottomNavVisible=*/ true); + hideDialpad(animate); } else if (!fab.isShown()) { fab.show(); } showBottomNav(); toolbar.collapse(animate); toolbarShadow.setVisibility(View.GONE); - activity.getFragmentManager().popBackStack(); + activity.getFragmentManager().beginTransaction().hide(getSearchFragment()).commit(); // Clear the dialpad so the phone number isn't persisted between search sessions. DialpadFragment dialpadFragment = getDialpadFragment(); @@ -391,8 +379,7 @@ public class MainSearchController implements SearchBarListener { // TODO(a bug): zero suggest results aren't actually shown but this enabled the nearby // places promo to be shown. searchFragment = NewSearchFragment.newInstance(true); - transaction.replace(R.id.fragment_container, searchFragment, SEARCH_FRAGMENT_TAG); - transaction.addToBackStack(null); + transaction.add(R.id.search_fragment_container, searchFragment, SEARCH_FRAGMENT_TAG); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); } else if (!isSearchVisible()) { transaction.show(getSearchFragment()); @@ -519,7 +506,7 @@ public class MainSearchController implements SearchBarListener { toolbar.expand(false, Optional.absent()); } if (savedInstanceState.getBoolean(KEY_IS_TOOLBAR_SLIDE_UP, false)) { - toolbar.slideUp(false); + toolbar.slideUp(false, fragmentContainer); } } diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java index 9f15d28c5..2db331a81 100644 --- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java +++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java @@ -230,7 +230,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen searchController = getNewMainSearchController( - bottomNav, fab, toolbar, activity.findViewById(R.id.toolbar_shadow)); + bottomNav, fab, toolbar, activity.findViewById(R.id.toolbar_shadow), snackbarContainer); toolbar.setSearchBarListener(searchController); onDialpadQueryChangedListener = getNewOnDialpadQueryChangedListener(searchController); @@ -579,8 +579,10 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen BottomNavBar bottomNavBar, FloatingActionButton fab, MainToolbar mainToolbar, - View toolbarShadow) { - return new MainSearchController(activity, bottomNavBar, fab, mainToolbar, toolbarShadow); + View toolbarShadow, + View fragmentContainer) { + return new MainSearchController( + activity, bottomNavBar, fab, mainToolbar, toolbarShadow, fragmentContainer); } public MainOnDialpadQueryChangedListener getNewOnDialpadQueryChangedListener( diff --git a/java/com/android/dialer/main/impl/res/layout/main_activity.xml b/java/com/android/dialer/main/impl/res/layout/main_activity.xml index 0883acebc..a1d6e5372 100644 --- a/java/com/android/dialer/main/impl/res/layout/main_activity.xml +++ b/java/com/android/dialer/main/impl/res/layout/main_activity.xml @@ -21,6 +21,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + android:layout_height="match_parent"/> + + + + - - - - - slideUp(animate)); + ViewUtil.doOnGlobalLayout(this, view -> slideUp(animate, container)); return; } isSlideUp = true; - ValueAnimator animator = ValueAnimator.ofFloat(0, -getHeight()); - animator.setDuration(animate ? SLIDE_DURATION : 0); - animator.setInterpolator(SLIDE_INTERPOLATOR); - animator.addUpdateListener( - new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int val = ((Float) animation.getAnimatedValue()).intValue(); - RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams(); - params.topMargin = val; - requestLayout(); - } - }); - animator.start(); + animate() + .translationY(-getHeight()) + .setDuration(animate ? SLIDE_DURATION : 0) + .setInterpolator(SLIDE_INTERPOLATOR) + .start(); + container + .animate() + .translationY(-getHeight()) + .setDuration(animate ? SLIDE_DURATION : 0) + .setInterpolator(SLIDE_INTERPOLATOR) + .start(); } /** Slides the toolbar down and back onto the screen. */ - public void slideDown(boolean animate) { + public void slideDown(boolean animate, View container) { Assert.checkArgument(isSlideUp); isSlideUp = false; - ValueAnimator animator = ValueAnimator.ofFloat(-getHeight(), 0); - animator.setDuration(animate ? SLIDE_DURATION : 0); - animator.setInterpolator(SLIDE_INTERPOLATOR); - animator.addUpdateListener( - new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int val = ((Float) animation.getAnimatedValue()).intValue(); - RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams(); - params.topMargin = val; - requestLayout(); - } - }); - animator.start(); + animate() + .translationY(0) + .setDuration(animate ? SLIDE_DURATION : 0) + .setInterpolator(SLIDE_INTERPOLATOR) + .start(); + container + .animate() + .translationY(0) + .setDuration(animate ? SLIDE_DURATION : 0) + .setInterpolator(SLIDE_INTERPOLATOR) + .start(); } /** @see SearchBarView#collapse(boolean) */ diff --git a/java/com/android/dialer/main/impl/toolbar/SearchBarView.java b/java/com/android/dialer/main/impl/toolbar/SearchBarView.java index 299985057..0cc76598c 100644 --- a/java/com/android/dialer/main/impl/toolbar/SearchBarView.java +++ b/java/com/android/dialer/main/impl/toolbar/SearchBarView.java @@ -186,7 +186,6 @@ final class SearchBarView extends FrameLayout { params.rightMargin = margin; searchBoxExpanded.getLayoutParams().height = (int) (animationEndHeight - (animationEndHeight - animationStartHeight) * fraction); - requestLayout(); } /* package-private */ void setSearchBarListener(@NonNull SearchBarListener listener) { -- cgit v1.2.3