diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/dialer/DialtactsActivity.java | 113 | ||||
-rw-r--r-- | src/com/android/dialer/list/ListsFragment.java | 100 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteFragment.java | 27 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java | 3 | ||||
-rw-r--r-- | src/com/android/dialer/list/ViewPagerTabs.java | 169 |
5 files changed, 345 insertions, 67 deletions
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index c59db95dc..8b9b71ada 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -71,6 +71,7 @@ import com.android.dialer.dialpad.SmartDialPrefix; import com.android.dialer.interactions.PhoneNumberInteraction; import com.android.dialer.list.AllContactsActivity; import com.android.dialer.list.DragDropController; +import com.android.dialer.list.ListsFragment; import com.android.dialer.list.OnDragDropListener; import com.android.dialer.list.OnListFragmentScrolledListener; import com.android.dialer.list.PhoneFavoriteFragment; @@ -94,7 +95,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O DialpadFragment.HostInterface, PhoneFavoriteFragment.OnShowAllContactsListener, PhoneFavoriteFragment.HostInterface, - OnDragDropListener, View.OnLongClickListener { + OnDragDropListener, View.OnLongClickListener, + OnPhoneNumberPickerActionListener { private static final String TAG = "DialtactsActivity"; public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -129,11 +131,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O private static final int ANIMATION_DURATION = 250; /** - * The main fragment displaying the user's favorites and frequent contacts - */ - private PhoneFavoriteFragment mPhoneFavoriteFragment; - - /** * Fragment containing the dialpad that slides into view */ private DialpadFragment mDialpadFragment; @@ -148,6 +145,11 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O */ private SmartDialSearchFragment mSmartDialSearchFragment; + /** + * Fragment containing the speed dial list, recents list, and all contacts list. + */ + private ListsFragment mListsFragment; + private View mFakeActionBar; private View mMenuButton; private View mCallHistoryButton; @@ -188,6 +190,21 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O private DialerDatabaseHelper mDialerDatabaseHelper; + private class OverflowPopupMenu extends PopupMenu { + public OverflowPopupMenu(Context context, View anchor) { + super(context, anchor); + } + + @Override + public void show() { + final Menu menu = getMenu(); + final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents); + // TODO: Check mPhoneFavoriteFragment.hasFrequents() + clearFrequents.setVisible(true); + super.show(); + } + } + /** * Listener used when one of phone numbers in search UI is selected. This will initiate a * phone call using the phone number. @@ -287,7 +304,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O // is null. Otherwise the fragment manager takes care of recreating these fragments. if (savedInstanceState == null) { getFragmentManager().beginTransaction() - .add(R.id.dialtacts_frame, new PhoneFavoriteFragment(), TAG_FAVORITES_FRAGMENT) + .add(R.id.dialtacts_frame, new ListsFragment(), TAG_FAVORITES_FRAGMENT) .add(R.id.dialtacts_container, new DialpadFragment(), TAG_DIALPAD_FRAGMENT) .commit(); } else { @@ -369,12 +386,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O if (mFragmentsFrame != null) { mFragmentsFrame.setAlpha(1.0f); } - } else if (fragment instanceof PhoneFavoriteFragment) { - mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment; - mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener); - if (mFragmentsFrame != null) { - mFragmentsFrame.setAlpha(1.0f); - } + } else if (fragment instanceof ListsFragment) { + mListsFragment = (ListsFragment) fragment; } } @@ -582,7 +595,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O .setInterpolator(hideActionBarInterpolator).setDuration(ANIMATION_DURATION); } - if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isVisible()) { + if (mListsFragment != null && mListsFragment.isVisible()) { // If the favorites fragment is showing, fade to blank. mFragmentsFrame.animate().alpha(0.0f); } @@ -608,12 +621,20 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O .setInterpolator(showActionBarInterpolator).setDuration(ANIMATION_DURATION); } - if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isVisible()) { + if (mListsFragment != null && mListsFragment.isVisible()) { mFragmentsFrame.animate().alpha(1.0f); } getActionBar().show(); } + private void hideInputMethod(View view) { + final InputMethodManager imm = (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); + if (imm != null && view != null) { + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { if (DEBUG) { @@ -711,29 +732,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O return !isDialIntent(getIntent()) ? CALL_ORIGIN_DIALTACTS : null; } - private final PhoneFavoriteFragment.Listener mPhoneFavoriteListener = - new PhoneFavoriteFragment.Listener() { - @Override - public void onContactSelected(Uri contactUri) { - PhoneNumberInteraction.startInteractionForPhoneCall( - DialtactsActivity.this, contactUri, getCallOrigin()); - } - - @Override - public void onCallNumberDirectly(String phoneNumber) { - Intent intent = CallUtil.getCallIntent(phoneNumber, getCallOrigin()); - startActivity(intent); - } - }; - - private void hideInputMethod(View view) { - final InputMethodManager imm = (InputMethodManager) getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm != null && view != null) { - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); - } - } - /** * Shows the search fragment */ @@ -752,12 +750,10 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O final FragmentTransaction transaction = getFragmentManager().beginTransaction(); SearchFragment fragment; - if (mInDialpadSearch) { + if (mInDialpadSearch && mSmartDialSearchFragment != null) { transaction.remove(mSmartDialSearchFragment); - } else if (mInRegularSearch) { + } else if (mInRegularSearch && mRegularSearchFragment != null) { transaction.remove(mRegularSearchFragment); - } else { - transaction.remove(mPhoneFavoriteFragment); } final String tag; @@ -860,19 +856,10 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O @Override public void onListFragmentScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount) { - - // Hide the action bar when scrolling down in the speed dial list, and show it again when - // scrolling back up. - if (firstVisibleItem > mPreviousFirstVisibleItem) { - getActionBar().hide(); - } else if (firstVisibleItem < mPreviousFirstVisibleItem) { - getActionBar().show(); - } - mPreviousFirstVisibleItem = firstVisibleItem; + // TODO: No-op for now. This should eventually show/hide the actionBar based on + // interactions with the ListsFragments. } - private int mPreviousFirstVisibleItem = 0; - @Override public void setDialButtonEnabled(boolean enabled) { if (mDialButton != null) { @@ -943,4 +930,24 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O public void setDragDropController(DragDropController dragController) { mRemoveViewContainer.setDragDropController(dragController); } + + @Override + public void onPickPhoneNumberAction(Uri dataUri) { + mPhoneNumberPickerActionListener.onPickPhoneNumberAction(dataUri); + } + + @Override + public void onCallNumberDirectly(String phoneNumber) { + mPhoneNumberPickerActionListener.onCallNumberDirectly(phoneNumber); + } + + @Override + public void onShortcutIntentCreated(Intent intent) { + mPhoneNumberPickerActionListener.onShortcutIntentCreated(intent); + } + + @Override + public void onHomeInActionBarSelected() { + mPhoneNumberPickerActionListener.onHomeInActionBarSelected(); + } } diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java new file mode 100644 index 000000000..768d3601e --- /dev/null +++ b/src/com/android/dialer/list/ListsFragment.java @@ -0,0 +1,100 @@ +package com.android.dialer.list; + +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.os.Bundle; +import android.support.v13.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; +import com.android.dialer.R; + +/** + * Fragment that is used as the main screen of the Dialer. + * + * Contains a ViewPager that contains various contact lists like the Speed Dial list and the + * All Contacts list. This will also eventually contain the logic that allows sliding the + * ViewPager containing the lists up above the shortcut cards and pin it against the top of the + * screen. + */ +public class ListsFragment extends Fragment { + + private ViewPager mViewPager; + private ViewPagerAdapter mViewPagerAdapter; + private PhoneFavoriteFragment mSpeedDialFragment; + private AllContactsFragment mAllContactsFragment; + + private OnPhoneNumberPickerActionListener mNumberPickerListener; + + private static final int TAB_INDEX_SPEED_DIAL = 0; + private static final int TAB_INDEX_ALL_CONTACTS = 1; + + private String[] mTabTitles; + + private static final int TAB_INDEX_COUNT = 2; + + public class ViewPagerAdapter extends FragmentPagerAdapter { + public ViewPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + switch (position) { + case TAB_INDEX_SPEED_DIAL: + mSpeedDialFragment = new PhoneFavoriteFragment(); + return mSpeedDialFragment; + case TAB_INDEX_ALL_CONTACTS: + mAllContactsFragment = new AllContactsFragment(); + mAllContactsFragment.setOnPhoneNumberPickerActionListener( + mNumberPickerListener); + return mAllContactsFragment; + } + throw new IllegalStateException("No fragment at position " + position); + } + + @Override + public int getCount() { + return TAB_INDEX_COUNT; + } + + @Override + public CharSequence getPageTitle(int position) { + return mTabTitles[position]; + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final View parentView = inflater.inflate(R.layout.lists_fragment, container, false); + mViewPager = (ViewPager) parentView.findViewById(R.id.lists_pager); + mViewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager()); + mViewPager.setAdapter(mViewPagerAdapter); + mViewPager.setOffscreenPageLimit(1); + + mTabTitles = new String[TAB_INDEX_COUNT]; + mTabTitles[TAB_INDEX_SPEED_DIAL] = getResources().getString(R.string.tab_speed_dial); + mTabTitles[TAB_INDEX_ALL_CONTACTS] = getResources().getString(R.string.tab_all_contacts); + + ViewPagerTabs tabs = (ViewPagerTabs) parentView.findViewById(R.id.lists_pager_header); + tabs.setViewPager(mViewPager); + return parentView; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + + try { + mNumberPickerListener = (OnPhoneNumberPickerActionListener) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement OnPhoneNumberPickerActionListener"); + } + } +} diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java index a56c3c546..c0dbd8ca5 100644 --- a/src/com/android/dialer/list/PhoneFavoriteFragment.java +++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java @@ -51,6 +51,7 @@ import com.android.contacts.common.GeoUtil; import com.android.contacts.common.list.ContactEntry; import com.android.contacts.common.list.ContactListItemView; import com.android.contacts.common.list.ContactTileView; +import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; import com.android.dialer.DialtactsActivity; import com.android.dialer.R; import com.android.dialer.calllog.CallLogAdapter; @@ -102,11 +103,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen public void onShowAllContacts(); } - public interface Listener { - public void onContactSelected(Uri contactUri); - public void onCallNumberDirectly(String phoneNumber); - } - public interface HostInterface { public void setDragDropController(DragDropController controller); } @@ -155,15 +151,15 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen private class ContactTileAdapterListener implements ContactTileView.Listener { @Override public void onContactSelected(Uri contactUri, Rect targetRect) { - if (mListener != null) { - mListener.onContactSelected(contactUri); + if (mPhoneNumberPickerActionListener != null) { + mPhoneNumberPickerActionListener.onPickPhoneNumberAction(contactUri); } } @Override public void onCallNumberDirectly(String phoneNumber) { - if (mListener != null) { - mListener.onCallNumberDirectly(phoneNumber); + if (mPhoneNumberPickerActionListener != null) { + mPhoneNumberPickerActionListener.onCallNumberDirectly(phoneNumber); } } @@ -189,7 +185,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen } } - private Listener mListener; + private OnPhoneNumberPickerActionListener mPhoneNumberPickerActionListener; private OnListFragmentScrolledListener mActivityScrollListener; private OnShowAllContactsListener mShowAllContactsListener; @@ -362,6 +358,13 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen + " must implement OnDragDropListener and HostInterface"); } + try { + mPhoneNumberPickerActionListener = (OnPhoneNumberPickerActionListener) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement PhoneFavoritesFragment.listener"); + } + // Use initLoader() instead of restartLoader() to refraining unnecessary reload. // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will // be called, on which we'll check if "all" contacts should be reloaded again or not. @@ -391,10 +394,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mShowAllContactsListener.onShowAllContacts(); } - public void setListener(Listener listener) { - mListener = listener; - } - @Override public void onVoicemailStatusFetched(Cursor statusCursor) { // no-op diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java index 81d682b8b..849d6514a 100644 --- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java @@ -115,6 +115,9 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { mCallLogAdapter.registerDataSetObserver(mObserver); mContactTileAdapter.registerDataSetObserver(mObserver); mPhoneFavoritesMenu = phoneFavoritesMenu; + // Temporary hack to hide the favorites menu because it is not being used. + // It should be removed from this adapter entirely eventually. + mPhoneFavoritesMenu.setVisibility(View.GONE); mTileInteractionTeaserView = tileInteractionTeaserView; mCallLogQueryHandler = new CallLogQueryHandler(mContext.getContentResolver(), mCallLogQueryHandlerListener); diff --git a/src/com/android/dialer/list/ViewPagerTabs.java b/src/com/android/dialer/list/ViewPagerTabs.java new file mode 100644 index 000000000..45f468ddd --- /dev/null +++ b/src/com/android/dialer/list/ViewPagerTabs.java @@ -0,0 +1,169 @@ +package com.android.dialer.list; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.support.v4.view.PagerAdapter; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.dialer.R; + +/** + * Lightweight implementation of ViewPager tabs. This looks similar to traditional actionBar tabs, + * but allows for the view containing the tabs to be placed anywhere on screen. Text-related + * attributes can also be assigned in XML - these will get propogated to the child TextViews + * automatically. + */ +public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener { + + ViewPager mPager; + /** + * Linearlayout that will contain the TextViews serving as tabs. This is the only child + * of the parent HorizontalScrollView. + */ + LinearLayout mChild; + final ColorStateList mTextColor; + final int mTextSize; + final boolean mTextAllCaps; + int mPrevSelected = -1; + int mSidePadding; + + private static final int TAB_SIDE_PADDING_IN_DPS = 10; + + private static final int[] ATTRS = new int[] { + android.R.attr.textAppearance, + android.R.attr.textSize, + android.R.attr.textColor, + android.R.attr.textAllCaps + }; + + /** + * Simulates actionbar tab behavior by showing a toast with the tab title when long clicked. + */ + private class OnTabLongClickListener implements OnLongClickListener { + final int mPosition; + + public OnTabLongClickListener(int position) { + mPosition = position; + } + + @Override + public boolean onLongClick(View v) { + final int[] screenPos = new int[2]; + getLocationOnScreen(screenPos); + + final Context context = getContext(); + final int width = getWidth(); + final int height = getHeight(); + final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; + + Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition), + Toast.LENGTH_SHORT); + + // Show the toast under the tab + toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, + (screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height); + + toast.show(); + return true; + } + } + + public ViewPagerTabs(Context context) { + this(context, null); + } + + public ViewPagerTabs(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setFillViewport(true); + + mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS); + + final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); + mTextSize = a.getDimensionPixelSize(1, 0); + mTextColor = a.getColorStateList(2); + mTextAllCaps = a.getBoolean(3, false); + + mChild = new LinearLayout(context); + addView(mChild, + new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)); + } + + public void setViewPager(ViewPager viewPager) { + mPager = viewPager; + mPager.setOnPageChangeListener(this); + addTabs(mPager.getAdapter()); + } + + private void addTabs(PagerAdapter adapter) { + final int count = adapter.getCount(); + for (int i = 0; i < count; i++) { + addTab(adapter.getPageTitle(i), i); + } + } + + private void addTab(CharSequence tabTitle, final int position) { + final TextView textView = new TextView(getContext()); + textView.setText(tabTitle); + textView.setBackgroundResource(R.drawable.action_bar_tab); + textView.setGravity(Gravity.CENTER); + textView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mPager.setCurrentItem(position); + } + }); + + textView.setOnLongClickListener(new OnTabLongClickListener(position)); + + // Assign various text appearance related attributes to child views. + if (mTextSize > 0) { + textView.setTextSize(mTextSize); + } + if (mTextColor != null) { + textView.setTextColor(mTextColor); + } + textView.setAllCaps(mTextAllCaps); + textView.setPadding(mSidePadding, 0, mSidePadding, 0); + mChild.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT, 1)); + // Default to the first child being selected + if (position == 0) { + mPrevSelected = 0; + textView.setSelected(true); + } + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + if (mPrevSelected >= 0) { + mChild.getChildAt(mPrevSelected).setSelected(false); + } + final View selectedChild = mChild.getChildAt(position); + selectedChild.setSelected(true); + // Update scroll position + final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2; + smoothScrollTo(scrollPos, 0); + mPrevSelected = position; + } + + @Override + public void onPageScrollStateChanged(int state) { + } +}
\ No newline at end of file |