Fix FAB state and transitions.
+ Change to dialpad FAB in search (used to stay as add contact
FAB, if we were in the Contacts list).
+ Position dialpad to align end in search (used to stay in the
center, if we opened the search from Speed Dial).
+ Restore correct position/icon when exiting search.
+ Add correct FAB scale in/out behaviors in for transitions
between lists fragment and search UI, search UI and dialpad,
in particular for when the FAB changes position from END to
MIDDLE when going from search UI back to Speed Dial.
+ Add FAB scale in/outs for showing/hiding the soft keyboard.
Bug: 21161760
Change-Id: Idbddbac161e459e3708d43395850d80927d5e448
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 47e5234..fc0f1fb 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -84,7 +84,7 @@
import com.android.dialer.util.DialerUtils;
import com.android.dialer.widget.ActionBarController;
import com.android.dialer.widget.SearchEditTextLayout;
-import com.android.dialer.widget.SearchEditTextLayout.OnBackButtonClickedListener;
+import com.android.dialer.widget.SearchEditTextLayout.Callback;
import com.android.dialerbind.DatabaseHelperManager;
import com.android.phone.common.animation.AnimUtils;
import com.android.phone.common.animation.AnimationListenerAdapter;
@@ -136,6 +136,8 @@
private static final int ACTIVITY_REQUEST_CODE_VOICE_SEARCH = 1;
+ private static final int FAB_SCALE_IN_DELAY_MS = 300;
+
private FrameLayout mParentLayout;
/**
@@ -338,14 +340,19 @@
};
/**
- * If the search term is empty and the user closes the soft keyboard, close the search UI.
+ * Handles the user closing the soft keyboard.
*/
private final View.OnKeyListener mSearchEditTextLayoutListener = new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN &&
- TextUtils.isEmpty(mSearchView.getText().toString())) {
- maybeExitSearchUi();
+ if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+ if (TextUtils.isEmpty(mSearchView.getText().toString())) {
+ // If the search term is empty, close the search UI.
+ maybeExitSearchUi();
+ } else {
+ // If the search term is not empty, show the dialpad fab.
+ showFabInSearchUi();
+ }
}
return false;
}
@@ -394,11 +401,17 @@
.setOnClickListener(mSearchViewOnClickListener);
searchEditTextLayout.findViewById(R.id.search_box_start_search)
.setOnClickListener(mSearchViewOnClickListener);
- searchEditTextLayout.setOnBackButtonClickedListener(new OnBackButtonClickedListener() {
+ searchEditTextLayout.setCallback(new SearchEditTextLayout.Callback() {
@Override
public void onBackButtonClicked() {
onBackPressed();
}
+
+ @Override
+ public void onSearchViewClicked() {
+ // Hide FAB, as the keyboard is shown.
+ mFloatingActionButtonController.scaleOut();
+ }
});
mIsLandscape = getResources().getConfiguration().orientation
@@ -463,7 +476,8 @@
observer.removeOnGlobalLayoutListener(this);
int screenWidth = mParentLayout.getWidth();
mFloatingActionButtonController.setScreenWidth(screenWidth);
- updateFloatingActionButtonControllerAlignment(false /* animate */);
+ mFloatingActionButtonController.align(
+ getFabAlignment(), false /* animate */);
}
});
@@ -527,7 +541,7 @@
}
prepareVoiceSearchButton();
mDialerDatabaseHelper.startSmartDialUpdateThread();
- updateFloatingActionButtonControllerAlignment(false /* animate */);
+ mFloatingActionButtonController.align(getFabAlignment(), false /* animate */);
Trace.endSection();
}
@@ -744,7 +758,7 @@
updateSearchFragmentPosition();
- updateFloatingActionButtonControllerAlignment(animate);
+ mFloatingActionButtonController.align(getFabAlignment(), animate);
if (animate) {
mDialpadFragment.getView().startAnimation(mSlideOut);
} else {
@@ -948,6 +962,8 @@
mInDialpadSearch = smartDialSearch;
mInRegularSearch = !smartDialSearch;
+ mFloatingActionButtonController.scaleOut();
+
SearchFragment fragment = (SearchFragment) getFragmentManager().findFragmentByTag(tag);
if (animate) {
transaction.setCustomAnimations(android.R.animator.fade_in, 0);
@@ -959,6 +975,15 @@
fragment = new SmartDialSearchFragment();
} else {
fragment = new RegularSearchFragment();
+ fragment.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ // Show the FAB when the user touches the lists fragment and the soft
+ // keyboard is hidden.
+ showFabInSearchUi();
+ return false;
+ }
+ });
}
transaction.add(R.id.dialtacts_frame, fragment, tag);
} else {
@@ -995,6 +1020,14 @@
setNotInSearchUi();
+ // Restore the FAB for the lists fragment.
+ if (getFabAlignment() != FloatingActionButtonController.ALIGN_END) {
+ mFloatingActionButtonController.setVisible(false);
+ }
+ mFloatingActionButtonController.scaleIn(FAB_SCALE_IN_DELAY_MS);
+ onPageScrolled(mListsFragment.getCurrentTabIndex(), 0 /* offset */, 0 /* pixelOffset */);
+ onPageSelected(mListsFragment.getCurrentTabIndex());
+
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
if (mSmartDialSearchFragment != null) {
transaction.remove(mSmartDialSearchFragment);
@@ -1055,6 +1088,14 @@
return false;
}
+ private void showFabInSearchUi() {
+ mFloatingActionButtonController.changeIcon(
+ getResources().getDrawable(R.drawable.fab_ic_dial),
+ getResources().getString(R.string.action_menu_dialpad_button));
+ mFloatingActionButtonController.align(getFabAlignment(), false /* animate */);
+ mFloatingActionButtonController.scaleIn(FAB_SCALE_IN_DELAY_MS);
+ }
+
@Override
public void onDialpadQueryChanged(String query) {
if (mSmartDialSearchFragment != null) {
@@ -1251,16 +1292,12 @@
return mActionBarHeight;
}
- /**
- * Updates controller based on currently known information.
- *
- * @param animate Whether or not to animate the transition.
- */
- private void updateFloatingActionButtonControllerAlignment(boolean animate) {
- int align = (!mIsLandscape &&
- mListsFragment.getCurrentTabIndex() == ListsFragment.TAB_INDEX_SPEED_DIAL) ?
- FloatingActionButtonController.ALIGN_MIDDLE :
- FloatingActionButtonController.ALIGN_END;
- mFloatingActionButtonController.align(align, 0 /* offsetX */, 0 /* offsetY */, animate);
+
+ private int getFabAlignment() {
+ if (!mIsLandscape && !isInSearchUi() &&
+ mListsFragment.getCurrentTabIndex() == ListsFragment.TAB_INDEX_SPEED_DIAL) {
+ return FloatingActionButtonController.ALIGN_MIDDLE;
+ }
+ return FloatingActionButtonController.ALIGN_END;
}
}
diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java
index f86c0e5..78c3ad3 100644
--- a/src/com/android/dialer/list/SearchFragment.java
+++ b/src/com/android/dialer/list/SearchFragment.java
@@ -50,6 +50,7 @@
private static final String TAG = SearchFragment.class.getSimpleName();
private OnListFragmentScrolledListener mActivityScrollListener;
+ private View.OnTouchListener mActivityOnTouchListener;
/*
* Stores the untouched user-entered string that is used to populate the add to contacts
@@ -123,6 +124,9 @@
int totalItemCount) {
}
});
+ if (mActivityOnTouchListener != null) {
+ listView.setOnTouchListener(mActivityOnTouchListener);
+ }
updatePosition(false /* animate */);
}
@@ -298,4 +302,8 @@
getAdapter().setQueryString(null);
}
}
+
+ public void setOnTouchListener(View.OnTouchListener onTouchListener) {
+ mActivityOnTouchListener = onTouchListener;
+ }
}
diff --git a/src/com/android/dialer/widget/SearchEditTextLayout.java b/src/com/android/dialer/widget/SearchEditTextLayout.java
index f1fa986..544749f 100644
--- a/src/com/android/dialer/widget/SearchEditTextLayout.java
+++ b/src/com/android/dialer/widget/SearchEditTextLayout.java
@@ -61,13 +61,14 @@
private ValueAnimator mAnimator;
- private OnBackButtonClickedListener mOnBackButtonClickedListener;
+ private Callback mCallback;
/**
* Listener for the back button next to the search view being pressed
*/
- public interface OnBackButtonClickedListener {
+ public interface Callback {
public void onBackButtonClicked();
+ public void onSearchViewClicked();
}
public SearchEditTextLayout(Context context, AttributeSet attrs) {
@@ -78,8 +79,8 @@
mPreImeKeyListener = listener;
}
- public void setOnBackButtonClickedListener(OnBackButtonClickedListener listener) {
- mOnBackButtonClickedListener = listener;
+ public void setCallback(Callback listener) {
+ mCallback = listener;
}
@Override
@@ -126,6 +127,15 @@
}
});
+ mSearchView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mCallback != null) {
+ mCallback.onSearchViewClicked();
+ }
+ }
+ });
+
mSearchView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -151,8 +161,8 @@
findViewById(R.id.search_back_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- if (mOnBackButtonClickedListener != null) {
- mOnBackButtonClickedListener.onBackButtonClicked();
+ if (mCallback != null) {
+ mCallback.onBackButtonClicked();
}
}
});