From 2a58ab88d23238f252d5ccc6a6798f58b0e9ef56 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Thu, 15 May 2014 02:16:04 -0700 Subject: Cleanup dialpad show/hide logic. This is the first step in cleaning up the DialtactsActivity logic to make it easier to transition between different states, and handle the states in between (hopefully). Originally, I thought to also block show/hide actions if there was already a dialpad transition in progress, but in the end I did not do this because it made the UI seem unresponsive. - Delete custom predraw listener in DialpadFragment; it doesn't appear to be used (?) and made the animation logic more confusing. - Replace the fragment custom animations with our own animations, which seem to perform better. - Changed the animation xmls from objectAnimators to translates. - Replaced isDialpadShowing with uses of mIsDialpadShown. - Reorder show/hide logic. Now it is less parallel, but better reflects the ordering/nature of fragment transactions. - Reorder some methods to group them more logically. - Pull out a helper method for updating the search fragment's yTranslation. - Pull out a helper method for updating the floating action bar. - Delete predraw method in DialpadFragment; doesn't appear to be used and caused. Bug: 14900155 Change-Id: I768324b2293622ea43974f7f566eec9b11fb0d4e --- src/com/android/dialer/DialtactsActivity.java | 193 +++++++++++++-------- .../android/dialer/dialpad/DialpadFragment.java | 31 +--- 2 files changed, 125 insertions(+), 99 deletions(-) (limited to 'src/com') diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index a90f0c8d3..685143ba1 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -48,6 +48,9 @@ import android.view.MenuItem; import android.view.View; import android.view.View.OnDragListener; import android.view.animation.AccelerateInterpolator; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.inputmethod.InputMethodManager; @@ -162,7 +165,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O private boolean mInDialpadSearch; private boolean mInRegularSearch; private boolean mClearSearchOnPause; - private boolean isDialpadShown; + private boolean mIsDialpadShown; /** * The position of the currently selected tab in the attached {@link ListsFragment}. @@ -289,7 +292,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O if (DEBUG) { Log.d(TAG, "onTextChange for mSearchView called with new query: " + newText); } - final boolean dialpadSearch = isDialpadShowing(); + final boolean dialpadSearch = mIsDialpadShown; // Show search result with non-empty text. Show a bare list otherwise. if (TextUtils.isEmpty(newText) && getInSearchUi()) { @@ -323,10 +326,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } }; - private boolean isDialpadShowing() { - return mDialpadFragment != null && mDialpadFragment.isVisible(); - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -460,7 +459,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O public void onClick(View view) { switch (view.getId()) { case R.id.floating_action_button: - if (!isDialpadShown) { + if (!mIsDialpadShown) { mInCallDialpadUp = false; showDialpadFragment(true); } else { @@ -531,7 +530,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O public boolean onLongClick(View view) { switch (view.getId()) { case R.id.floating_action_button: - if (isDialpadShown) { + if (mIsDialpadShown) { // Dial button was pressed; tell the Dialpad fragment mDialpadFragment.dialButtonPressed(); return true; // Consume the event @@ -562,57 +561,97 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O super.onActivityResult(requestCode, resultCode, data); } + /** + * Initiates a fragment transaction to show the dialpad fragment. Animations and other visual + * updates are handled by a callback which is invoked after the dialpad fragment is shown. + * @see #onDialpadShown + */ private void showDialpadFragment(boolean animate) { + if (mIsDialpadShown) { + return; + } + mIsDialpadShown = true; mDialpadFragment.setAnimate(animate); final FragmentTransaction ft = getFragmentManager().beginTransaction(); - if (animate) { - ft.setCustomAnimations(R.anim.slide_in, 0); + ft.show(mDialpadFragment); + ft.commit(); + } + + /** + * Callback from child DialpadFragment when the dialpad is shown. + */ + public void onDialpadShown() { + updateFloatingActionButton(); + if (mDialpadFragment.getAnimate()) { + Animation slideIn = AnimationUtils.loadAnimation(this, R.anim.slide_in); + mDialpadFragment.getView().startAnimation(slideIn); } else { mDialpadFragment.setYFraction(0); } - ft.show(mDialpadFragment); - ft.commit(); + + if (mListsFragment != null && mListsFragment.isResumed() && mListsFragment.isVisible()) { + // If the favorites fragment is showing, fade to blank. + mFragmentsFrame.animate().alpha(0.0f); + parentLayout.setBackgroundColor(mContactListBackgroundColor); + } + + updateSearchFragmentPosition(); + getActionBar().hide(); } + /** + * Initiates animations and other visual updates to hide the dialpad. The fragment is hidden in + * a callback after the hide animation ends. + * @see #commitDialpadFragmentHide + */ public void hideDialpadFragment(boolean animate, boolean clearDialpad) { - if (mDialpadFragment == null) return; + if (mDialpadFragment == null) { + return; + } if (clearDialpad) { mDialpadFragment.clearDialpad(); } - if (!mDialpadFragment.isVisible()) return; + if (!mIsDialpadShown) { + return; + } + mIsDialpadShown = false; mDialpadFragment.setAnimate(animate); - final FragmentTransaction ft = getFragmentManager().beginTransaction(); + + updateFloatingActionButton(); if (animate) { - ft.setCustomAnimations(0, R.anim.slide_out); + Animation slideOut = AnimationUtils.loadAnimation(this, R.anim.slide_out); + slideOut.setAnimationListener(new ActivityAnimationListener() { + @Override + public void onAnimationEnd(Animation animation) { + commitDialpadFragmentHide(); + } + }); + mDialpadFragment.getView().startAnimation(slideOut); + } else { + commitDialpadFragmentHide(); } - ft.hide(mDialpadFragment); - ft.commit(); - } - - private boolean getInSearchUi() { - return mInDialpadSearch || mInRegularSearch; - } - private void setNotInSearchUi() { - mInDialpadSearch = false; - mInRegularSearch = false; - } + if (mListsFragment != null && mListsFragment.isVisible()) { + mFragmentsFrame.animate().alpha(1.0f); + parentLayout.setBackgroundColor(mDialerBackgroundColor); + } - private void hideDialpadAndSearchUi() { - mSearchView.setText(null); - hideDialpadFragment(false, true); + updateSearchFragmentPosition(); + getActionBar().show(); } /** - * Callback from child DialpadFragment when the dialpad is shown. + * Finishes hiding the dialpad fragment after any animations are completed. */ - public void onDialpadShown() { - isDialpadShown = true; - mFloatingActionButton.setImageResource(R.drawable.fab_ic_call); - mFloatingActionButton.setContentDescription( - getResources().getString(R.string.description_dial_button)); + private void commitDialpadFragmentHide() { + final FragmentTransaction ft = getFragmentManager().beginTransaction(); + ft.hide(mDialpadFragment); + ft.commit(); + } + private void updateSearchFragmentPosition() { + int translationValue = mIsDialpadShown ? -mActionBarHeight : 0; SearchFragment fragment = null; if (mInDialpadSearch) { fragment = mSmartDialSearchFragment; @@ -620,46 +659,23 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O fragment = mRegularSearchFragment; } if (fragment != null && fragment.isVisible()) { - fragment.getView().animate().translationY(-mActionBarHeight) + fragment.getView().animate().translationY(translationValue) .setInterpolator(hideActionBarInterpolator).setDuration(ANIMATION_DURATION); } - - if (mListsFragment != null && mListsFragment.isResumed() && mListsFragment.isVisible()) { - // If the favorites fragment is showing, fade to blank. - mFragmentsFrame.animate().alpha(0.0f); - parentLayout.setBackgroundColor(mContactListBackgroundColor); - } - getActionBar().hide(); - alignFloatingActionButtonMiddle(); } - /** - * Callback from child DialpadFragment when the dialpad is hidden. - */ - public void onDialpadHidden() { - isDialpadShown = false; - mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial); - mFloatingActionButton.setContentDescription( - getResources().getString(R.string.action_menu_dialpad_button)); - - SearchFragment fragment = null; - if (mInDialpadSearch) { - fragment = mSmartDialSearchFragment; - } else if (mInRegularSearch) { - fragment = mRegularSearchFragment; - } - if (fragment != null && fragment.isVisible()) { - fragment.getView().animate().translationY(0) - .setInterpolator(showActionBarInterpolator).setDuration(ANIMATION_DURATION); - } + private boolean getInSearchUi() { + return mInDialpadSearch || mInRegularSearch; + } - if (mListsFragment != null && mListsFragment.isVisible()) { - mFragmentsFrame.animate().alpha(1.0f); - parentLayout.setBackgroundColor(mDialerBackgroundColor); + private void setNotInSearchUi() { + mInDialpadSearch = false; + mInRegularSearch = false; + } - } - getActionBar().show(); - alignFloatingActionButtonByTab(mCurrentTabPosition); + private void hideDialpadAndSearchUi() { + mSearchView.setText(null); + hideDialpadFragment(false, true); } private void hideInputMethod(View view) { @@ -839,7 +855,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O getFragmentManager().popBackStack(0, FragmentManager.POP_BACK_STACK_INCLUSIVE); setNotInSearchUi(); - if (isDialpadShowing()) { + if (mIsDialpadShown) { mFragmentsFrame.setAlpha(0); } } @@ -854,7 +870,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O @Override public void onBackPressed() { - if (mDialpadFragment != null && mDialpadFragment.isVisible()) { + if (mIsDialpadShown) { hideDialpadFragment(true, false); } else if (getInSearchUi()) { mSearchView.setText(null); @@ -1008,7 +1024,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O public void onPageSelected(int position) { mCurrentTabPosition = position; // If the dialpad is showing, the floating action button should always be middle aligned. - if (!isDialpadShowing()) { + if (!mIsDialpadShown) { alignFloatingActionButtonByTab(mCurrentTabPosition); } } @@ -1017,6 +1033,20 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O public void onPageScrollStateChanged(int state) { } + private void updateFloatingActionButton() { + if (mIsDialpadShown) { + mFloatingActionButton.setImageResource(R.drawable.fab_ic_call); + mFloatingActionButton.setContentDescription( + getResources().getString(R.string.description_dial_button)); + alignFloatingActionButtonByTab(mCurrentTabPosition); + } else { + mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial); + mFloatingActionButton.setContentDescription( + getResources().getString(R.string.action_menu_dialpad_button)); + alignFloatingActionButtonMiddle(); + } + } + private void alignFloatingActionButtonByTab(int position) { if (position == ListsFragment.TAB_INDEX_SPEED_DIAL) { alignFloatingActionButtonMiddle(); @@ -1040,4 +1070,21 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O params.addRule(RelativeLayout.CENTER_HORIZONTAL); mFloatingActionButtonContainer.setLayoutParams(params); } + + /** + * Convenience class which implements AnimationListener interface as null-op methods. + */ + private class ActivityAnimationListener implements AnimationListener { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + } } diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index 4557bd4b1..418d54a20 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -347,29 +347,6 @@ public class DialpadFragment extends Fragment false); fragmentView.buildLayer(); - final ViewTreeObserver vto = fragmentView.getViewTreeObserver(); - // Adjust the translation of the DialpadFragment in a preDrawListener instead of in - // DialtactsActivity, because at the point in time when the DialpadFragment is added, - // its views have not been laid out yet. - final OnPreDrawListener preDrawListener = new OnPreDrawListener() { - - @Override - public boolean onPreDraw() { - - if (isHidden()) return true; - if (mAnimate && fragmentView.getTranslationY() == 0) { - ((DialpadSlidingLinearLayout) fragmentView).setYFraction( - DIALPAD_SLIDE_FRACTION); - } - final ViewTreeObserver vto = fragmentView.getViewTreeObserver(); - vto.removeOnPreDrawListener(this); - return true; - } - - }; - - vto.addOnPreDrawListener(preDrawListener); - Resources r = getResources(); mDialpadView = (DialpadView) fragmentView.findViewById(R.id.dialpad_view); @@ -1593,9 +1570,7 @@ public class DialpadFragment extends Fragment final DialtactsActivity activity = (DialtactsActivity) getActivity(); final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view); if (activity == null) return; - if (hidden) { - activity.onDialpadHidden(); - } else { + if (!hidden) { if (mAnimate) { dialpadView.animateShow(); } @@ -1608,6 +1583,10 @@ public class DialpadFragment extends Fragment mAnimate = value; } + public boolean getAnimate() { + return mAnimate; + } + public void setYFraction(float yFraction) { ((DialpadSlidingLinearLayout) getView()).setYFraction(yFraction); } -- cgit v1.2.3