diff options
Diffstat (limited to 'src/com/android/dialer/NewDialtactsActivity.java')
-rw-r--r-- | src/com/android/dialer/NewDialtactsActivity.java | 1168 |
1 files changed, 320 insertions, 848 deletions
diff --git a/src/com/android/dialer/NewDialtactsActivity.java b/src/com/android/dialer/NewDialtactsActivity.java index 584c951b3..66cbe8530 100644 --- a/src/com/android/dialer/NewDialtactsActivity.java +++ b/src/com/android/dialer/NewDialtactsActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,9 @@ package com.android.dialer; -import android.app.ActionBar; -import android.app.ActionBar.LayoutParams; -import android.app.ActionBar.Tab; -import android.app.ActionBar.TabListener; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; import android.app.Activity; import android.app.backup.BackupManager; import android.app.Fragment; @@ -33,26 +32,20 @@ import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; -import android.preference.PreferenceManager; import android.provider.CallLog.Calls; +import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Intents.UI; -import android.support.v13.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v4.view.ViewPager.OnPageChangeListener; +import android.provider.Settings; import android.text.TextUtils; -import android.util.DisplayMetrics; import android.util.Log; import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; -import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.view.ViewConfiguration; -import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; +import android.widget.AbsListView.OnScrollListener; import android.widget.PopupMenu; import android.widget.SearchView; import android.widget.SearchView.OnCloseListener; @@ -61,27 +54,30 @@ import android.widget.Toast; import com.android.contacts.common.CallUtil; import com.android.contacts.common.activity.TransactionSafeActivity; -import com.android.contacts.common.list.ContactListFilterController; -import com.android.contacts.common.list.ContactListFilterController.ContactListFilterListener; +import com.android.contacts.common.dialog.ClearFrequentsDialog; +import com.android.contacts.common.interactions.ImportExportDialogFragment; import com.android.contacts.common.list.ContactListItemView; import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; import com.android.contacts.common.list.PhoneNumberPickerFragment; -import com.android.contacts.common.util.AccountFilterUtil; -import com.android.dialer.calllog.CallLogFragment; -import com.android.dialer.dialpad.DialpadFragment; +import com.android.dialer.calllog.NewCallLogActivity; +import com.android.dialer.dialpad.NewDialpadFragment; +import com.android.dialer.dialpad.SmartDialNameMatcher; import com.android.dialer.interactions.PhoneNumberInteraction; -import com.android.dialer.list.PhoneFavoriteFragment; -import com.android.dialer.util.OrientationUtil; +import com.android.dialer.list.NewPhoneFavoriteFragment; +import com.android.dialer.list.OnListFragmentScrolledListener; +import com.android.dialer.list.SmartDialSearchFragment; import com.android.internal.telephony.ITelephony; /** - * The dialer activity that has one tab with the virtual 12key - * dialer, a tab with recent calls in it, a tab with the contacts and - * a tab with the favorite. This is the container and the tabs are - * embedded using intents. * The dialer tab's title is 'phone', a more common name (see strings.xml). + * + * TODO krelease: All classes currently prefixed with New will replace the original classes or + * be renamed more appropriately before shipping. */ -public class NewDialtactsActivity extends TransactionSafeActivity implements View.OnClickListener { +public class NewDialtactsActivity extends TransactionSafeActivity implements View.OnClickListener, + NewDialpadFragment.OnDialpadQueryChangedListener, PopupMenu.OnMenuItemClickListener, + OnListFragmentScrolledListener, + NewPhoneFavoriteFragment.OnPhoneFavoriteFragmentStartedListener { private static final String TAG = "DialtactsActivity"; public static final boolean DEBUG = false; @@ -95,18 +91,16 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie private static final String CALL_ORIGIN_DIALTACTS = "com.android.dialer.DialtactsActivity"; + private static final String TAG_DIALPAD_FRAGMENT = "dialpad"; + private static final String TAG_REGULAR_SEARCH_FRAGMENT = "search"; + private static final String TAG_SMARTDIAL_SEARCH_FRAGMENT = "smartdial"; + private static final String TAG_FAVORITES_FRAGMENT = "favorites"; + /** * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}. */ private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER"; - /** Used both by {@link ActionBar} and {@link ViewPagerAdapter} */ - private static final int TAB_INDEX_DIALER = 0; - private static final int TAB_INDEX_CALL_LOG = 1; - private static final int TAB_INDEX_FAVORITES = 2; - - private static final int TAB_INDEX_COUNT = 3; - private SharedPreferences mPrefs; public static final String SHARED_PREFS_NAME = "com.android.dialer_preferences"; @@ -114,291 +108,51 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie /** Last manually selected tab index */ private static final String PREF_LAST_MANUALLY_SELECTED_TAB = "DialtactsActivity_last_manually_selected_tab"; - private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER; private static final int SUBACTIVITY_ACCOUNT_FILTER = 1; - public class ViewPagerAdapter extends FragmentPagerAdapter { - public ViewPagerAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - switch (position) { - case TAB_INDEX_DIALER: - return new DialpadFragment(); - case TAB_INDEX_CALL_LOG: - return new CallLogFragment(); - case TAB_INDEX_FAVORITES: - return new PhoneFavoriteFragment(); - } - throw new IllegalStateException("No fragment at position " + position); - } - - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - // The parent's setPrimaryItem() also calls setMenuVisibility(), so we want to know - // when it happens. - if (DEBUG) { - Log.d(TAG, "FragmentPagerAdapter#setPrimaryItem(), position: " + position); - } - super.setPrimaryItem(container, position, object); - } - - @Override - public int getCount() { - return TAB_INDEX_COUNT; - } - } + private String mFilterText; /** - * True when the app detects user's drag event. This variable should not become true when - * mUserTabClick is true. - * - * During user's drag or tab click, we shouldn't show fake buttons but just show real - * ActionBar at the bottom of the screen, for transition animation. + * The main fragment displaying the user's favorites and frequent contacts */ - boolean mDuringSwipe = false; + private NewPhoneFavoriteFragment mPhoneFavoriteFragment; + /** - * True when the app detects user's tab click (at the top of the screen). This variable should - * not become true when mDuringSwipe is true. - * - * During user's drag or tab click, we shouldn't show fake buttons but just show real - * ActionBar at the bottom of the screen, for transition animation. + * Fragment containing the dialpad that slides into view */ - boolean mUserTabClick = false; - - private class PageChangeListener implements OnPageChangeListener { - private int mCurrentPosition = -1; - /** - * Used during page migration, to remember the next position {@link #onPageSelected(int)} - * specified. - */ - private int mNextPosition = -1; - - @Override - public void onPageScrolled( - int position, float positionOffset, int positionOffsetPixels) { - } - - @Override - public void onPageSelected(int position) { - if (DEBUG) Log.d(TAG, "onPageSelected: position: " + position); - final ActionBar actionBar = getActionBar(); - if (mDialpadFragment != null) { - if (mDuringSwipe && position == TAB_INDEX_DIALER) { - // TODO: Figure out if we want this or not. Right now - // - with this call, both fake buttons and real action bar overlap - // - without this call, there's tiny flicker happening to search/menu buttons. - // If we can reduce the flicker without this call, it would be much better. - // updateFakeMenuButtonsVisibility(true); - } - } - - if (mCurrentPosition == position) { - Log.w(TAG, "Previous position and next position became same (" + position + ")"); - } - - actionBar.selectTab(actionBar.getTabAt(position)); - mNextPosition = position; - } - - public void setCurrentPosition(int position) { - mCurrentPosition = position; - } - - public int getCurrentPosition() { - return mCurrentPosition; - } - - @Override - public void onPageScrollStateChanged(int state) { - switch (state) { - case ViewPager.SCROLL_STATE_IDLE: { - if (mNextPosition == -1) { - // This happens when the user drags the screen just after launching the - // application, and settle down the same screen without actually swiping it. - // At that moment mNextPosition is apparently -1 yet, and we expect it - // being updated by onPageSelected(), which is *not* called if the user - // settle down the exact same tab after the dragging. - if (DEBUG) { - Log.d(TAG, "Next position is not specified correctly. Use current tab (" - + mViewPager.getCurrentItem() + ")"); - } - mNextPosition = mViewPager.getCurrentItem(); - } - if (DEBUG) { - Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE. " - + "mCurrentPosition: " + mCurrentPosition - + ", mNextPosition: " + mNextPosition); - } - // Interpret IDLE as the end of migration (both swipe and tab click) - mDuringSwipe = false; - mUserTabClick = false; - - updateFakeMenuButtonsVisibility(mNextPosition == TAB_INDEX_DIALER); - sendFragmentVisibilityChange(mCurrentPosition, false); - sendFragmentVisibilityChange(mNextPosition, true); - - invalidateOptionsMenu(); + private NewDialpadFragment mDialpadFragment; - mCurrentPosition = mNextPosition; - break; - } - case ViewPager.SCROLL_STATE_DRAGGING: { - if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_DRAGGING"); - mDuringSwipe = true; - mUserTabClick = false; - break; - } - case ViewPager.SCROLL_STATE_SETTLING: { - if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_SETTLING"); - mDuringSwipe = true; - mUserTabClick = false; - break; - } - default: - break; - } - } - } - - private String mFilterText; + /** + * Fragment for searching phone numbers using the alphanumeric keyboard. + */ + private NewSearchFragment mRegularSearchFragment; - /** Enables horizontal swipe between Fragments. */ - private ViewPager mViewPager; - private final PageChangeListener mPageChangeListener = new PageChangeListener(); - private DialpadFragment mDialpadFragment; - private CallLogFragment mCallLogFragment; - private PhoneFavoriteFragment mPhoneFavoriteFragment; + /** + * Fragment for searching phone numbers using the dialpad. + */ + private SmartDialSearchFragment mSmartDialSearchFragment; - private View mSearchButton; private View mMenuButton; + private View mCallHistoryButton; + private View mDialpadButton; - private final ContactListFilterListener mContactListFilterListener = - new ContactListFilterListener() { - @Override - public void onContactListFilterChanged() { - boolean doInvalidateOptionsMenu = false; - - if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isAdded()) { - mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter()); - doInvalidateOptionsMenu = true; - } - - if (mSearchFragment != null && mSearchFragment.isAdded()) { - mSearchFragment.setFilter(mContactListFilterController.getFilter()); - doInvalidateOptionsMenu = true; - } else { - Log.w(TAG, "Search Fragment isn't available when ContactListFilter is changed"); - } - - if (doInvalidateOptionsMenu) { - invalidateOptionsMenu(); - } - } - }; - - private final TabListener mTabListener = new TabListener() { - @Override - public void onTabUnselected(Tab tab, FragmentTransaction ft) { - if (DEBUG) Log.d(TAG, "onTabUnselected(). tab: " + tab); - } - - @Override - public void onTabSelected(Tab tab, FragmentTransaction ft) { - if (DEBUG) { - Log.d(TAG, "onTabSelected(). tab: " + tab + ", mDuringSwipe: " + mDuringSwipe); - } - // When the user swipes the screen horizontally, this method will be called after - // ViewPager.SCROLL_STATE_DRAGGING and ViewPager.SCROLL_STATE_SETTLING events, while - // when the user clicks a tab at the ActionBar at the top, this will be called before - // them. This logic interprets the order difference as a difference of the user action. - if (!mDuringSwipe) { - if (DEBUG) { - Log.d(TAG, "Tab select. from: " + mPageChangeListener.getCurrentPosition() - + ", to: " + tab.getPosition()); - } - if (mDialpadFragment != null) { - updateFakeMenuButtonsVisibility(tab.getPosition() == TAB_INDEX_DIALER); - } - mUserTabClick = true; - } - - if (mViewPager.getCurrentItem() != tab.getPosition()) { - mViewPager.setCurrentItem(tab.getPosition(), true); - } - - // During the call, we don't remember the tab position. - if (mDialpadFragment == null || !mDialpadFragment.phoneIsInUse()) { - // Remember this tab index. This function is also called, if the tab is set - // automatically in which case the setter (setCurrentTab) has to set this to its old - // value afterwards - mLastManuallySelectedFragment = tab.getPosition(); - } - } - - @Override - public void onTabReselected(Tab tab, FragmentTransaction ft) { - if (DEBUG) Log.d(TAG, "onTabReselected"); - } - }; + // Padding view used to shift the fragments up when the dialpad is shown. + private View mBottomPaddingView; /** - * Fragment for searching phone numbers. Unlike the other Fragments, this doesn't correspond - * to tab but is shown by a search action. - */ - private PhoneNumberPickerFragment mSearchFragment; - /** * True when this Activity is in its search UI (with a {@link SearchView} and * {@link PhoneNumberPickerFragment}). */ private boolean mInSearchUi; private SearchView mSearchView; - private final OnClickListener mFilterOptionClickListener = new OnClickListener() { - @Override - public void onClick(View view) { - final PopupMenu popupMenu = new PopupMenu(NewDialtactsActivity.this, view); - final Menu menu = popupMenu.getMenu(); - popupMenu.inflate(R.menu.dialtacts_search_options); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener); - final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact); - addContactOptionMenuItem.setIntent( - new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI)); - popupMenu.show(); - } - }; - /** * The index of the Fragment (or, the tab) that has last been manually selected. * This value does not keep track of programmatically set Tabs (e.g. Call Log after a Call) */ private int mLastManuallySelectedFragment; - private ContactListFilterController mContactListFilterController; - private OnMenuItemClickListener mFilterOptionsMenuItemClickListener = - new OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - AccountFilterUtil.startAccountFilterActivityForResult( - NewDialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER, - mContactListFilterController.getFilter()); - return true; - } - }; - - private OnMenuItemClickListener mSearchMenuItemClickListener = - new OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - enterSearchUi(); - return true; - } - }; - /** * Listener used when one of phone numbers in search UI is selected. This will initiate a * phone call using the phone number. @@ -410,7 +164,7 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie // Specify call-origin so that users will see the previous tab instead of // CallLog screen (search UI will be automatically exited). PhoneNumberInteraction.startInteractionForPhoneCall( - NewDialtactsActivity.this, dataUri, getCallOrigin()); + NewDialtactsActivity.this, dataUri, getCallOrigin()); } @Override @@ -441,14 +195,29 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie @Override public boolean onQueryTextChange(String newText) { + final boolean smartDialSearch = isDialpadShowing(); + // Show search result with non-empty text. Show a bare list otherwise. - if (mSearchFragment != null) { - mSearchFragment.setQueryString(newText, true); + if (TextUtils.isEmpty(newText) && mInSearchUi) { + exitSearchUi(); + return true; + } else if (!TextUtils.isEmpty(newText) && !mInSearchUi) { + enterSearchUi(smartDialSearch); + } + + if (isDialpadShowing()) { + mSmartDialSearchFragment.setQueryString(newText, false); + } else { + mRegularSearchFragment.setQueryString(newText, false); } return true; } }; + private boolean isDialpadShowing() { + return mDialpadFragment.isVisible(); + } + /** * Listener used to handle the "close" button on the right side of {@link SearchView}. * If some text is in the search view, this will clean it up. Otherwise this will exit @@ -467,135 +236,132 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } }; - private final View.OnLayoutChangeListener mFirstLayoutListener - = new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) { - v.removeOnLayoutChangeListener(this); // Unregister self. - addSearchFragment(); - } - }; - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); final Intent intent = getIntent(); fixIntent(intent); - setContentView(R.layout.dialtacts_activity); - - mContactListFilterController = ContactListFilterController.getInstance(this); - mContactListFilterController.addListener(mContactListFilterListener); + setContentView(R.layout.new_dialtacts_activity); - findViewById(R.id.dialtacts_frame).addOnLayoutChangeListener(mFirstLayoutListener); + getActionBar().hide(); - mViewPager = (ViewPager) findViewById(R.id.pager); - mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager())); - mViewPager.setOnPageChangeListener(mPageChangeListener); - mViewPager.setOffscreenPageLimit(2); + mPhoneFavoriteFragment = new NewPhoneFavoriteFragment(); + mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener); - // Do same width calculation as ActionBar does - DisplayMetrics dm = getResources().getDisplayMetrics(); - int minCellSize = getResources().getDimensionPixelSize(R.dimen.fake_menu_button_min_width); - int cellCount = dm.widthPixels / minCellSize; - int fakeMenuItemWidth = dm.widthPixels / cellCount; - if (DEBUG) Log.d(TAG, "The size of fake menu buttons (in pixel): " + fakeMenuItemWidth); + mRegularSearchFragment = new NewSearchFragment(); + mSmartDialSearchFragment = new SmartDialSearchFragment(); + mDialpadFragment = new NewDialpadFragment(); - // Soft menu button should appear only when there's no hardware menu button. - mMenuButton = findViewById(R.id.overflow_menu); - if (mMenuButton != null) { - mMenuButton.setMinimumWidth(fakeMenuItemWidth); - if (ViewConfiguration.get(this).hasPermanentMenuKey()) { - // This is required for dialpad button's layout, so must not use GONE here. - mMenuButton.setVisibility(View.INVISIBLE); - } else { - mMenuButton.setOnClickListener(this); - } - } - mSearchButton = findViewById(R.id.searchButton); - if (mSearchButton != null) { - mSearchButton.setMinimumWidth(fakeMenuItemWidth); - mSearchButton.setOnClickListener(this); - } - - // Setup the ActionBar tabs (the order matches the tab-index contants TAB_INDEX_*) - setupDialer(); - setupCallLog(); - setupFavorites(); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); - getActionBar().setDisplayShowTitleEnabled(false); - getActionBar().setDisplayShowHomeEnabled(false); + // TODO krelease: load fragments on demand instead of creating all of them at run time + final FragmentTransaction ft = getFragmentManager().beginTransaction(); + ft.add(R.id.dialtacts_frame, mPhoneFavoriteFragment, TAG_FAVORITES_FRAGMENT); + ft.add(R.id.dialtacts_frame, mRegularSearchFragment, TAG_REGULAR_SEARCH_FRAGMENT); + ft.add(R.id.dialtacts_frame, mSmartDialSearchFragment, TAG_SMARTDIAL_SEARCH_FRAGMENT); + ft.add(R.id.dialtacts_container, mDialpadFragment, TAG_DIALPAD_FRAGMENT); + ft.hide(mRegularSearchFragment); + ft.hide(mDialpadFragment); + ft.hide(mSmartDialSearchFragment); + ft.commit(); + + mBottomPaddingView = findViewById(R.id.dialtacts_bottom_padding); + prepareSearchView(); // Load the last manually loaded tab mPrefs = this.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE); - mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB, - PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT); - if (mLastManuallySelectedFragment >= TAB_INDEX_COUNT) { - // Stored value may have exceeded the number of current tabs. Reset it. - mLastManuallySelectedFragment = PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT; - } - setCurrentTab(intent); + /* + * TODO krelease : Remember which fragment was last displayed, and then redisplay it as + * necessary. mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB, + * PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT); if (mLastManuallySelectedFragment >= + * TAB_INDEX_COUNT) { // Stored value may have exceeded the number of current tabs. Reset + * it. mLastManuallySelectedFragment = PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT; } + */ if (UI.FILTER_CONTACTS_ACTION.equals(intent.getAction()) - && icicle == null) { + && savedInstanceState == null) { setupFilterText(intent); } } @Override - public void onStart() { - super.onStart(); - if (mPhoneFavoriteFragment != null) { - mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter()); - } - if (mSearchFragment != null) { - mSearchFragment.setFilter(mContactListFilterController.getFilter()); - } - - if (mDuringSwipe || mUserTabClick) { - if (DEBUG) Log.d(TAG, "reset buggy flag state.."); - mDuringSwipe = false; - mUserTabClick = false; + protected void onResume() { + super.onResume(); + final FragmentManager fm = getFragmentManager(); + mPhoneFavoriteFragment = (NewPhoneFavoriteFragment) fm.findFragmentByTag( + TAG_FAVORITES_FRAGMENT); + mDialpadFragment = (NewDialpadFragment) fm.findFragmentByTag(TAG_DIALPAD_FRAGMENT); + + mRegularSearchFragment = (NewSearchFragment) fm.findFragmentByTag( + TAG_REGULAR_SEARCH_FRAGMENT); + mRegularSearchFragment.setOnPhoneNumberPickerActionListener( + mPhoneNumberPickerActionListener); + if (!mRegularSearchFragment.isHidden()) { + final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.hide(mRegularSearchFragment); + transaction.commit(); } - final int currentPosition = mPageChangeListener.getCurrentPosition(); - if (DEBUG) { - Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition() - + ". Reset all menu visibility state."); - } - updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi); - for (int i = 0; i < TAB_INDEX_COUNT; i++) { - sendFragmentVisibilityChange(i, i == currentPosition); + mSmartDialSearchFragment = (SmartDialSearchFragment) fm.findFragmentByTag( + TAG_SMARTDIAL_SEARCH_FRAGMENT); + mSmartDialSearchFragment.setOnPhoneNumberPickerActionListener( + mPhoneNumberPickerActionListener); + if (!mSmartDialSearchFragment.isHidden()) { + final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.hide(mSmartDialSearchFragment); + transaction.commit(); } } @Override - public void onDestroy() { - super.onDestroy(); - mContactListFilterController.removeListener(mContactListFilterListener); + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_import_export: + // We hard-code the "contactsAreAvailable" argument because doing it properly would + // involve querying a {@link ProviderStatusLoader}, which we don't want to do right + // now in Dialtacts for (potential) performance reasons. Compare with how it is + // done in {@link PeopleActivity}. + ImportExportDialogFragment.show(getFragmentManager(), true, + DialtactsActivity.class); + return true; + case R.id.menu_clear_frequents: + ClearFrequentsDialog.show(getFragmentManager()); + return true; + case R.id.add_contact: + try { + startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI)); + } catch (ActivityNotFoundException e) { + Toast toast = Toast.makeText(this, R.string.add_contact_not_available, + Toast.LENGTH_SHORT); + toast.show(); + } + return true; + case R.id.menu_call_settings: + final Intent settingsIntent = DialtactsActivity.getCallSettingsIntent(); + startActivity(settingsIntent); + } + return false; } @Override public void onClick(View view) { switch (view.getId()) { - case R.id.searchButton: { - enterSearchUi(); - break; - } case R.id.overflow_menu: { - if (mDialpadFragment != null) { - PopupMenu popup = mDialpadFragment.constructPopupMenu(view); - if (popup != null) { - popup.show(); - } - } else { - Log.w(TAG, "DialpadFragment is null during onClick() event for " + view); - } + final PopupMenu popupMenu = new PopupMenu(NewDialtactsActivity.this, view); + final Menu menu = popupMenu.getMenu(); + popupMenu.inflate(R.menu.dialtacts_options_new); + popupMenu.setOnMenuItemClickListener(this); + popupMenu.show(); break; } + case R.id.dialpad_button: + showDialpadFragment(); + break; + case R.id.call_history_button: + final Intent intent = new Intent(this, NewCallLogActivity.class); + startActivity(intent); + break; default: { Log.wtf(TAG, "Unexpected onClick event from " + view); break; @@ -603,33 +369,22 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } } - /** - * Add search fragment. Note this is called during onLayout, so there's some restrictions, - * such as executePendingTransaction can't be used in it. - */ - private void addSearchFragment() { - // In order to take full advantage of "fragment deferred start", we need to create the - // search fragment after all other fragments are created. - // The other fragments are created by the ViewPager on the first onMeasure(). - // We use the first onLayout call, which is after onMeasure(). - - // Just return if the fragment is already created, which happens after configuration - // changes. - if (mSearchFragment != null) return; - + private void showDialpadFragment() { final FragmentTransaction ft = getFragmentManager().beginTransaction(); - final Fragment searchFragment = new PhoneNumberPickerFragment(); + ft.setCustomAnimations(R.anim.slide_in, 0); + ft.show(mDialpadFragment); + ft.commit(); + } - searchFragment.setUserVisibleHint(false); - ft.add(R.id.dialtacts_frame, searchFragment); - ft.hide(searchFragment); - ft.commitAllowingStateLoss(); + private void hideDialpadFragment() { + final FragmentTransaction ft = getFragmentManager().beginTransaction(); + ft.setCustomAnimations(0, R.anim.slide_out); + ft.hide(mDialpadFragment); + ft.commit(); } private void prepareSearchView() { - final View searchViewLayout = - getLayoutInflater().inflate(R.layout.dialtacts_custom_action_bar, null); - mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view); + mSearchView = (SearchView) findViewById(R.id.search_view); mSearchView.setOnQueryTextListener(mPhoneSearchQueryTextListener); mSearchView.setOnCloseListener(mPhoneSearchCloseListener); // Since we're using a custom layout for showing SearchView instead of letting the @@ -639,8 +394,9 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie // - it should not be iconified at this time // See also comments for onActionViewExpanded()/onActionViewCollapsed() mSearchView.setIconifiedByDefault(true); - mSearchView.setQueryHint(getString(R.string.hint_findContacts)); + mSearchView.setQueryHint(getString(R.string.dialer_hint_find_contact)); mSearchView.setIconified(false); + mSearchView.clearFocus(); mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFocus) { @@ -649,69 +405,87 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } } }); + } + + private void hideDialpadFragmentIfNecessary() { + if (mDialpadFragment.isVisible()) { + hideDialpadFragment(); + } + } - if (!ViewConfiguration.get(this).hasPermanentMenuKey()) { - // Filter option menu should be shown on the right side of SearchView. - final View filterOptionView = searchViewLayout.findViewById(R.id.search_option); - filterOptionView.setVisibility(View.VISIBLE); - filterOptionView.setOnClickListener(mFilterOptionClickListener); + final AnimatorListener mHideListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mSearchView.setVisibility(View.GONE); } + }; + + public void hideSearchBar() { + mSearchView.animate().cancel(); + mSearchView.setAlpha(1); + mSearchView.setTranslationY(0); + mSearchView.animate().withLayer().alpha(0).translationY(-mSearchView.getHeight()). + setDuration(200).setListener(mHideListener); + + mPhoneFavoriteFragment.getView().animate().withLayer() + .translationY(-mSearchView.getHeight()).setDuration(200).setListener( + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mBottomPaddingView.setVisibility(View.VISIBLE); + mPhoneFavoriteFragment.getView().setTranslationY(0); + } + }); + } + + public void showSearchBar() { + mSearchView.animate().cancel(); + mSearchView.setAlpha(0); + mSearchView.setTranslationY(-mSearchView.getHeight()); + mSearchView.animate().withLayer().alpha(1).translationY(0).setDuration(200) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + mSearchView.setVisibility(View.VISIBLE); + } + }); - getActionBar().setCustomView(searchViewLayout, - new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + mPhoneFavoriteFragment.getView().setTranslationY(-mSearchView.getHeight()); + mPhoneFavoriteFragment.getView().animate().withLayer().translationY(0).setDuration(200) + .setListener( + new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + mBottomPaddingView.setVisibility(View.GONE); + } + }); } - @Override - public void onAttachFragment(Fragment fragment) { - // This method can be called before onCreate(), at which point we cannot rely on ViewPager. - // In that case, we will setup the "current position" soon after the ViewPager is ready. - final int currentPosition = mViewPager != null ? mViewPager.getCurrentItem() : -1; - - if (fragment instanceof DialpadFragment) { - mDialpadFragment = (DialpadFragment) fragment; - } else if (fragment instanceof CallLogFragment) { - mCallLogFragment = (CallLogFragment) fragment; - } else if (fragment instanceof PhoneFavoriteFragment) { - mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment; - mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener); - if (mContactListFilterController != null - && mContactListFilterController.getFilter() != null) { - mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter()); - } - } else if (fragment instanceof PhoneNumberPickerFragment) { - mSearchFragment = (PhoneNumberPickerFragment) fragment; - mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener); - mSearchFragment.setQuickContactEnabled(true); - mSearchFragment.setDarkTheme(true); - mSearchFragment.setPhotoPosition(ContactListItemView.getDefaultPhotoPosition( - true /* opposite */)); - mSearchFragment.setUseCallableUri(true); - if (mContactListFilterController != null - && mContactListFilterController.getFilter() != null) { - mSearchFragment.setFilter(mContactListFilterController.getFilter()); - } - // Here we assume that we're not on the search mode, so let's hide the fragment. - // - // We get here either when the fragment is created (normal case), or after configuration - // changes. In the former case, we're not in search mode because we can only - // enter search mode if the fragment is created. (see enterSearchUi()) - // In the latter case we're not in search mode either because we don't retain - // mInSearchUi -- ideally we should but at this point it's not supported. - mSearchFragment.setUserVisibleHint(false); - // After configuration changes fragments will forget their "hidden" state, so make - // sure to hide it. - if (!mSearchFragment.isHidden()) { - final FragmentTransaction transaction = getFragmentManager().beginTransaction(); - transaction.hide(mSearchFragment); - transaction.commitAllowingStateLoss(); + + public void setupFakeActionBarItems() { + mMenuButton = findViewById(R.id.overflow_menu); + if (mMenuButton != null) { + // mMenuButton.setMinimumWidth(fakeMenuItemWidth); + if (ViewConfiguration.get(this).hasPermanentMenuKey()) { + // This is required for dialpad button's layout, so must not use GONE here. + mMenuButton.setVisibility(View.INVISIBLE); + } else { + mMenuButton.setOnClickListener(this); } } + + mCallHistoryButton = findViewById(R.id.call_history_button); + // mCallHistoryButton.setMinimumWidth(fakeMenuItemWidth); + mCallHistoryButton.setOnClickListener(this); + + mDialpadButton = findViewById(R.id.dialpad_button); + // DialpadButton.setMinimumWidth(fakeMenuItemWidth); + mDialpadButton.setOnClickListener(this); } @Override protected void onPause() { super.onPause(); - mPrefs.edit().putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment) .apply(); requestBackup(); @@ -733,30 +507,6 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } } - private void setupDialer() { - final Tab tab = getActionBar().newTab(); - tab.setContentDescription(R.string.dialerIconLabel); - tab.setTabListener(mTabListener); - tab.setIcon(R.drawable.ic_tab_dialer); - getActionBar().addTab(tab); - } - - private void setupCallLog() { - final Tab tab = getActionBar().newTab(); - tab.setContentDescription(R.string.recentCallsIconLabel); - tab.setIcon(R.drawable.ic_tab_recent); - tab.setTabListener(mTabListener); - getActionBar().addTab(tab); - } - - private void setupFavorites() { - final Tab tab = getActionBar().newTab(); - tab.setContentDescription(R.string.contactsFavoritesLabel); - tab.setIcon(R.drawable.ic_tab_all); - tab.setTabListener(mTabListener); - getActionBar().addTab(tab); - } - /** * Returns true if the intent is due to hitting the green send key (hardware call button: * KEYCODE_CALL) while in a call. @@ -765,8 +515,7 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie * @param recentCallsRequest true if the intent is requesting to view recent calls * @return true if the intent is due to hitting the green send key while in a call */ - private boolean isSendKeyWhileInCall(final Intent intent, - final boolean recentCallsRequest) { + private boolean isSendKeyWhileInCall(Intent intent, boolean recentCallsRequest) { // If there is a call in progress go to the call screen if (recentCallsRequest) { final boolean callKey = intent.getBooleanExtra("call_key", false); @@ -789,7 +538,10 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie * * @param intent Intent that contains information about which tab should be selected */ - private void setCurrentTab(Intent intent) { + private void displayFragment(Intent intent) { + // TODO krelease: Make navigation via intent work by displaying the correct fragment + // as appropriate. + // If we got here by hitting send and we're in call forward along to the in-call activity boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.resolveType( getContentResolver())); @@ -797,61 +549,30 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie finish(); return; } - - // Remember the old manually selected tab index so that it can be restored if it is - // overwritten by one of the programmatic tab selections - final int savedTabIndex = mLastManuallySelectedFragment; - - final int tabIndex; - if ((mDialpadFragment != null && mDialpadFragment.phoneIsInUse()) - || isDialIntent(intent)) { - tabIndex = TAB_INDEX_DIALER; - } else if (recentCallsRequest) { - tabIndex = TAB_INDEX_CALL_LOG; - } else { - tabIndex = mLastManuallySelectedFragment; - } - - final int previousItemIndex = mViewPager.getCurrentItem(); - mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */); - if (previousItemIndex != tabIndex) { - sendFragmentVisibilityChange(previousItemIndex, false /* not visible */ ); - } - mPageChangeListener.setCurrentPosition(tabIndex); - sendFragmentVisibilityChange(tabIndex, true /* visible */ ); - - // Restore to the previous manual selection - mLastManuallySelectedFragment = savedTabIndex; - mDuringSwipe = false; - mUserTabClick = false; } @Override public void onNewIntent(Intent newIntent) { setIntent(newIntent); fixIntent(newIntent); - setCurrentTab(newIntent); + displayFragment(newIntent); final String action = newIntent.getAction(); if (UI.FILTER_CONTACTS_ACTION.equals(action)) { setupFilterText(newIntent); } - if (mInSearchUi || (mSearchFragment != null && mSearchFragment.isVisible())) { + if (mInSearchUi || (mRegularSearchFragment != null && mRegularSearchFragment.isVisible())) { exitSearchUi(); } - if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) { - if (mDialpadFragment != null) { - mDialpadFragment.setStartedFromNewIntent(true); - } else { - Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected."); - } - } else if (mViewPager.getCurrentItem() == TAB_INDEX_CALL_LOG) { - if (mCallLogFragment != null) { - mCallLogFragment.configureScreenFromIntent(newIntent); - } else { - Log.e(TAG, "CallLogFragment isn't ready yet when the tab is already selected."); - } - } + // TODO krelease: Handle onNewIntent for all other fragments + /* + *if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) { if (mDialpadFragment != null) { + * mDialpadFragment.setStartedFromNewIntent(true); } else { Log.e(TAG, + * "DialpadFragment isn't ready yet when the tab is already selected."); } } else if + * (mViewPager.getCurrentItem() == TAB_INDEX_CALL_LOG) { if (mCallLogFragment != null) { + * mCallLogFragment.configureScreenFromIntent(newIntent); } else { Log.e(TAG, + * "CallLogFragment isn't ready yet when the tab is already selected."); } } + */ invalidateOptionsMenu(); } @@ -911,28 +632,12 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } } - @Override - public void onBackPressed() { - if (mInSearchUi) { - // We should let the user go back to usual screens with tabs. - exitSearchUi(); - } else if (isTaskRoot()) { - // Instead of stopping, simply push this to the back of the stack. - // This is only done when running at the top of the stack; - // otherwise, we have been launched by someone else so need to - // allow the user to go back to the caller. - moveTaskToBack(false); - } else { - super.onBackPressed(); - } - } - - private final PhoneFavoriteFragment.Listener mPhoneFavoriteListener = - new PhoneFavoriteFragment.Listener() { + private final NewPhoneFavoriteFragment.Listener mPhoneFavoriteListener = + new NewPhoneFavoriteFragment.Listener() { @Override public void onContactSelected(Uri contactUri) { PhoneNumberInteraction.startInteractionForPhoneCall( - NewDialtactsActivity.this, contactUri, getCallOrigin()); + NewDialtactsActivity.this, contactUri, getCallOrigin()); } @Override @@ -942,151 +647,14 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } }; - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.dialtacts_options, menu); - - // set up intents and onClick listeners - final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings); - final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - - callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent()); - searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener); - filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - if (mInSearchUi) { - prepareOptionsMenuInSearchMode(menu); - } else { - // get reference to the currently selected tab - final Tab tab = getActionBar().getSelectedTab(); - if (tab != null) { - switch(tab.getPosition()) { - case TAB_INDEX_DIALER: - prepareOptionsMenuForDialerTab(menu); - break; - case TAB_INDEX_CALL_LOG: - prepareOptionsMenuForCallLogTab(menu); - break; - case TAB_INDEX_FAVORITES: - prepareOptionsMenuForFavoritesTab(menu); - break; - } - } - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.add_contact: - try { - startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI)); - } catch (ActivityNotFoundException e) { - Toast toast = Toast.makeText(this, R.string.add_contact_not_available, - Toast.LENGTH_SHORT); - toast.show(); - } - return true; - } - return super.onOptionsItemSelected(item); - } - - private void prepareOptionsMenuInSearchMode(Menu menu) { - // get references to menu items - final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact); - final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings); - final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item); - - // prepare the menu items - searchMenuItem.setVisible(false); - filterOptionMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey()); - addContactOptionMenuItem.setVisible(false); - callSettingsMenuItem.setVisible(false); - emptyRightMenuItem.setVisible(false); - } - - private void prepareOptionsMenuForDialerTab(Menu menu) { - if (DEBUG) { - Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe - + ", user tab click: " + mUserTabClick); - } - - // get references to menu items - final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact); - final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings); - final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item); - - // prepare the menu items - filterOptionMenuItem.setVisible(false); - addContactOptionMenuItem.setVisible(false); - if (mDuringSwipe || mUserTabClick) { - // During horizontal movement, the real ActionBar menu items are shown - searchMenuItem.setVisible(true); - callSettingsMenuItem.setVisible(true); - // When there is a permanent menu key, there is no overflow icon on the right of - // the action bar which would force the search menu item (if it is visible) to the - // left. This is the purpose of showing the emptyRightMenuItem. - emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey()); - } else { - // This is when the user is looking at the dialer pad. In this case, the real - // ActionBar is hidden and fake menu items are shown. - // Except in landscape, in which case the real search menu item is shown. - searchMenuItem.setVisible(OrientationUtil.isLandscape(this)); - // If a permanent menu key is available, then we need to show the call settings item - // so that the call settings item can be invoked by the permanent menu key. - callSettingsMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey()); - emptyRightMenuItem.setVisible(false); - } - } - - private void prepareOptionsMenuForCallLogTab(Menu menu) { - // get references to menu items - final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact); - final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings); - final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item); - - // prepare the menu items - searchMenuItem.setVisible(true); - filterOptionMenuItem.setVisible(false); - addContactOptionMenuItem.setVisible(false); - callSettingsMenuItem.setVisible(true); - emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey()); - } - - private void prepareOptionsMenuForFavoritesTab(Menu menu) { - // get references to menu items - final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar); - final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option); - final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact); - final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings); - final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item); - - // prepare the menu items - searchMenuItem.setVisible(true); - filterOptionMenuItem.setVisible(true); - addContactOptionMenuItem.setVisible(true); - callSettingsMenuItem.setVisible(true); - emptyRightMenuItem.setVisible(false); - } + /* TODO krelease: This is only relevant for phones that have a hard button search key (i.e. + * Nexus S). Supporting it is a little more tricky because of the dialpad fragment might + * be showing when the search key is pressed so there is more state management involved. @Override public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData, boolean globalSearch) { - if (mSearchFragment != null && mSearchFragment.isAdded() && !globalSearch) { + if (mRegularSearchFragment != null && mRegularSearchFragment.isAdded() && !globalSearch) { if (mInSearchUi) { if (mSearchView.hasFocus()) { showInputMethod(mSearchView.findFocus()); @@ -1099,173 +667,52 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } else { super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch); } - } - - /** - * Hides every tab and shows search UI for phone lookup. - */ - private void enterSearchUi() { - if (mSearchFragment == null) { - // We add the search fragment dynamically in the first onLayoutChange() and - // mSearchFragment is set sometime later when the fragment transaction is actually - // executed, which means there's a window when users are able to hit the (physical) - // search key but mSearchFragment is still null. - // It's quite hard to handle this case right, so let's just ignore the search key - // in this case. Users can just hit it again and it will work this time. - return; - } - if (mSearchView == null) { - prepareSearchView(); - } - - final ActionBar actionBar = getActionBar(); - - final Tab tab = actionBar.getSelectedTab(); - - // User can search during the call, but we don't want to remember the status. - if (tab != null && (mDialpadFragment == null || - !mDialpadFragment.phoneIsInUse())) { - mLastManuallySelectedFragment = tab.getPosition(); - } - - mSearchView.setQuery(null, true); - - actionBar.setDisplayShowCustomEnabled(true); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - actionBar.setDisplayShowHomeEnabled(true); - actionBar.setDisplayHomeAsUpEnabled(true); - - updateFakeMenuButtonsVisibility(false); - - for (int i = 0; i < TAB_INDEX_COUNT; i++) { - sendFragmentVisibilityChange(i, false /* not visible */ ); - } - - // Show the search fragment and hide everything else. - mSearchFragment.setUserVisibleHint(true); - final FragmentTransaction transaction = getFragmentManager().beginTransaction(); - transaction.show(mSearchFragment); - transaction.commitAllowingStateLoss(); - mViewPager.setVisibility(View.GONE); - - // We need to call this and onActionViewCollapsed() manually, since we are using a custom - // layout instead of asking the search menu item to take care of SearchView. - mSearchView.onActionViewExpanded(); - mInSearchUi = true; - } + }*/ private void showInputMethod(View view) { - InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); if (imm != null) { - if (!imm.showSoftInput(view, 0)) { - Log.w(TAG, "Failed to show soft input method."); - } + imm.showSoftInput(view, 0); } } private void hideInputMethod(View view) { - InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); if (imm != null && view != null) { imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } } /** - * Goes back to usual Phone UI with tags. Previously selected Tag and associated Fragment - * should be automatically focused again. + * Shows the search fragment */ - private void exitSearchUi() { - final ActionBar actionBar = getActionBar(); - - // Hide the search fragment, if exists. - if (mSearchFragment != null) { - mSearchFragment.setUserVisibleHint(false); - - final FragmentTransaction transaction = getFragmentManager().beginTransaction(); - transaction.hide(mSearchFragment); - transaction.commitAllowingStateLoss(); - } - - // We want to hide SearchView and show Tabs. Also focus on previously selected one. - actionBar.setDisplayShowCustomEnabled(false); - actionBar.setDisplayShowHomeEnabled(false); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); - - for (int i = 0; i < TAB_INDEX_COUNT; i++) { - sendFragmentVisibilityChange(i, i == mViewPager.getCurrentItem()); - } - - // Before exiting the search screen, reset swipe state. - mDuringSwipe = false; - mUserTabClick = false; - - mViewPager.setVisibility(View.VISIBLE); - - hideInputMethod(getCurrentFocus()); - - // Request to update option menu. - invalidateOptionsMenu(); - - // See comments in onActionViewExpanded() - mSearchView.onActionViewCollapsed(); - mInSearchUi = false; - } - - private Fragment getFragmentAt(int position) { - switch (position) { - case TAB_INDEX_DIALER: - return mDialpadFragment; - case TAB_INDEX_CALL_LOG: - return mCallLogFragment; - case TAB_INDEX_FAVORITES: - return mPhoneFavoriteFragment; - default: - throw new IllegalStateException("Unknown fragment index: " + position); + private void enterSearchUi(boolean smartDialSearch) { + final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); + transaction.hide(mPhoneFavoriteFragment); + if (smartDialSearch) { + transaction.show(mSmartDialSearchFragment); + } else { + transaction.show(mRegularSearchFragment); } - } + transaction.commit(); - private void sendFragmentVisibilityChange(int position, boolean visibility) { - if (DEBUG) { - Log.d(TAG, "sendFragmentVisibiltyChange(). position: " + position - + ", visibility: " + visibility); - } - // Position can be -1 initially. See PageChangeListener. - if (position >= 0) { - final Fragment fragment = getFragmentAt(position); - if (fragment != null) { - fragment.setMenuVisibility(visibility); - fragment.setUserVisibleHint(visibility); - } - } + mInSearchUi = true; } /** - * Update visibility of the search button and menu button at the bottom. - * They should be invisible when bottom ActionBar's real items are available, and be visible - * otherwise. - * - * @param visible True when visible. + * Hides the search fragment */ - private void updateFakeMenuButtonsVisibility(boolean visible) { - // Note: Landscape mode does not have the fake menu and search buttons. - if (DEBUG) { - Log.d(TAG, "updateFakeMenuButtonVisibility(" + visible + ")"); - } - - if (mSearchButton != null) { - if (visible) { - mSearchButton.setVisibility(View.VISIBLE); - } else { - mSearchButton.setVisibility(View.INVISIBLE); - } - } - if (mMenuButton != null) { - if (visible && !ViewConfiguration.get(this).hasPermanentMenuKey()) { - mMenuButton.setVisibility(View.VISIBLE); - } else { - mMenuButton.setVisibility(View.INVISIBLE); - } - } + private void exitSearchUi() { + final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); + transaction.hide(mRegularSearchFragment); + transaction.hide(mSmartDialSearchFragment); + transaction.show(mPhoneFavoriteFragment); + transaction.commit(); + mInSearchUi = false; } /** Returns an Intent to launch Call Settings screen */ @@ -1277,16 +724,41 @@ public class NewDialtactsActivity extends TransactionSafeActivity implements Vie } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode != Activity.RESULT_OK) { - return; + public void onBackPressed() { + if (mDialpadFragment.isVisible()) { + hideDialpadFragment(); + } else if (mInSearchUi) { + mSearchView.setQuery(null, false); + } else if (isTaskRoot()) { + // Instead of stopping, simply push this to the back of the stack. + // This is only done when running at the top of the stack; + // otherwise, we have been launched by someone else so need to + // allow the user to go back to the caller. + moveTaskToBack(false); + } else { + super.onBackPressed(); } - switch (requestCode) { - case SUBACTIVITY_ACCOUNT_FILTER: { - AccountFilterUtil.handleAccountFilterResult( - mContactListFilterController, resultCode, data); - } - break; + } + + @Override + public void onDialpadQueryChanged(String query) { + final String normalizedQuery = SmartDialNameMatcher.normalizeNumber(query, + SmartDialNameMatcher.LATIN_SMART_DIAL_MAP); + if (!TextUtils.equals(mSearchView.getQuery(), normalizedQuery)) { + mSearchView.setQuery(normalizedQuery, false); + } + } + + @Override + public void onListFragmentScrollStateChange(int scrollState) { + if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { + hideDialpadFragmentIfNecessary(); + hideInputMethod(getCurrentFocus()); } } + + @Override + public void onPhoneFavoriteFragmentStarted() { + setupFakeActionBarItems(); + } } |