diff options
-rw-r--r-- | res/drawable/background_favorites_menu.xml | 29 | ||||
-rw-r--r-- | res/layout/phone_favorites_menu.xml | 58 | ||||
-rw-r--r-- | res/values/colors.xml | 13 | ||||
-rw-r--r-- | res/values/dimens.xml | 13 | ||||
-rw-r--r-- | res/values/strings.xml | 18 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteFragment.java | 45 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java | 146 |
7 files changed, 228 insertions, 94 deletions
diff --git a/res/drawable/background_favorites_menu.xml b/res/drawable/background_favorites_menu.xml new file mode 100644 index 000000000..fc2669b10 --- /dev/null +++ b/res/drawable/background_favorites_menu.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2014 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. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="false"> + <shape android:shape="rectangle" > + <solid android:color="@color/background_dialer_list_items" /> + </shape> + </item> + <item android:state_pressed="true"> + <shape android:shape="rectangle" > + <solid android:color="@color/favorites_menu_pressed_color" /> + </shape> + </item> +</selector>
\ No newline at end of file diff --git a/res/layout/phone_favorites_menu.xml b/res/layout/phone_favorites_menu.xml new file mode 100644 index 000000000..d8f2f32c7 --- /dev/null +++ b/res/layout/phone_favorites_menu.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2014 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. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<!-- The phone favorites menu appears on the main dialer screen above the favorite callers area, + and provides access to the All Contacts list. --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/phone_favorites_menu" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingLeft="@dimen/favorites_menu_margin" + android:paddingRight="@dimen/favorites_menu_margin" + android:paddingTop="@dimen/favorites_menu_margin" + android:paddingBottom="@dimen/favorites_menu_margin" + android:background="@drawable/background_favorites_menu" + android:addStatesFromChildren="true" + > + <TextView + android:layout_width="wrap_content" + android:layout_height="@dimen/favorites_menu_speed_dial_height" + android:fontFamily="@string/favorites_menu_speed_dial_font_family" + android:text="@string/favorites_menu_speed_dial" + android:textSize="@dimen/favorites_menu_speed_dial_text_size" + android:textColor="@color/speed_dial_text_color" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:gravity="center" + /> + <TextView + android:id="@+id/all_contacts_button" + android:fontFamily="@string/favorites_menu_all_contacts_font_family" + android:layout_width="wrap_content" + android:layout_height="@dimen/favorites_menu_all_contacts_height" + android:paddingLeft="@dimen/favorites_menu_padding" + android:paddingRight="@dimen/favorites_menu_padding" + android:text="@string/favorites_menu_all_contacts" + android:textSize="@dimen/favorites_menu_all_contacts_text_size" + android:background="@color/all_contacts_button_color" + android:textColor="@color/all_contacts_button_text_color" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:gravity="center" + android:focusable="true" + /> +</RelativeLayout>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index a8ddf2be7..e0e48ee92 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -70,4 +70,17 @@ <!-- Text color for no favorites message --> <color name="nofavorite_text_color">#777777</color> + + <!-- Text color for the "speed dial" label in the favorites menu. --> + <color name="speed_dial_text_color">#555555</color> + + <!-- Background color for the "All Contacts" button in the favorites menu. --> + <color name="all_contacts_button_color">#999999</color> + + <!-- Background color for the favorites menu when pressed. --> + <color name="favorites_menu_pressed_color">#d6d6d6</color> + + <!-- Text color for the "All Contacts" button above the favorite callers --> + <color name="all_contacts_button_text_color">#ffffff</color> + </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index e84b18a6a..b87b25ae6 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -82,4 +82,17 @@ <!-- Padding for the tooltip --> <dimen name="dismiss_button_padding_start">20dip</dimen> <dimen name="dismiss_button_padding_end">28dip</dimen> + + <!-- Margin around the favorites menu. --> + <dimen name="favorites_menu_margin">6dp</dimen> + <!-- Padding within the favorites menu. --> + <dimen name="favorites_menu_padding">4dp</dimen> + <!-- Text size for the "speed dial" text in the favorites menu. --> + <dimen name="favorites_menu_speed_dial_text_size">18sp</dimen> + <!-- Height of the speed dial TextView in the favorites menu. --> + <dimen name="favorites_menu_speed_dial_height">24dp</dimen> + <!-- Text size for the "All Contacts" text in the favorites menu. --> + <dimen name="favorites_menu_all_contacts_text_size">12sp</dimen> + <!-- Height of the all contacts Button in the favorites menu. --> + <dimen name="favorites_menu_all_contacts_height">24dp</dimen> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index c8aa37f7e..a61e0bc4a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -725,4 +725,22 @@ <!-- Content description for dismiss button on badge. [CHAR LIMIT=NONE] --> <string name="description_dismiss">Dismiss</string> + + <!-- Header text displayed on the main dialer screen above the list of favorite phone numbers. + [CHAR LIMIT=21] --> + <string name="favorites_menu_speed_dial">Speed Dial</string> + + <!-- Button text for the "all contacts" button displayed on the main dialer screen above the + list of favorite phone numbers. Navigates the user to the "All Contacts" list. + This text represents the same action as the text in string "menu_allContacts". + [CHAR LIMIT=21] --> + <string name="favorites_menu_all_contacts">ALL CONTACTS</string> + + <!-- The font-family to use for the "speed dial" label on the favorites menu. + Do not translate. --> + <string name="favorites_menu_speed_dial_font_family">sans-serif-light</string> + + <!-- The font-family to use for the "all contacts" label on the favorites menu. + Do not translate. --> + <string name="favorites_menu_all_contacts_font_family">sans-serif</string> </resources> diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java index 2791f1569..9a39b3af4 100644 --- a/src/com/android/dialer/list/PhoneFavoriteFragment.java +++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java @@ -17,9 +17,7 @@ package com.android.dialer.list; import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; import android.app.Activity; import android.app.Fragment; import android.app.LoaderManager; @@ -27,7 +25,6 @@ import android.content.Context; import android.content.CursorLoader; import android.content.Loader; import android.content.SharedPreferences; -import android.content.res.Resources; import android.database.Cursor; import android.graphics.Rect; import android.net.Uri; @@ -42,6 +39,7 @@ import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.RelativeLayout; @@ -197,8 +195,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen private PhoneFavoriteListView mListView; - private View mShowAllContactsButton; - private View mShowAllContactsInEmptyViewButton; + private View mPhoneFavoritesMenu; private View mContactTileFrame; private TileInteractionTeaserView mTileInteractionTeaserView; @@ -290,14 +287,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view); - mShowAllContactsInEmptyViewButton = mParentView.findViewById( - R.id.show_all_contact_button_in_nofav); - prepareAllContactsButton(mShowAllContactsInEmptyViewButton); - - mShowAllContactsButton = inflater.inflate(R.layout.show_all_contact_button, mListView, - false); - - prepareAllContactsButton(mShowAllContactsButton); + mPhoneFavoritesMenu = inflater.inflate(R.layout.phone_favorites_menu, mListView, false); + prepareFavoritesMenu(mPhoneFavoritesMenu); mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame); @@ -305,7 +296,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen R.layout.tile_interactions_teaser_view, mListView, false); mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter, - mCallLogAdapter, mShowAllContactsButton, mTileInteractionTeaserView); + mCallLogAdapter, mPhoneFavoritesMenu, mTileInteractionTeaserView); mTileInteractionTeaserView.setAdapter(mAdapter); @@ -637,31 +628,17 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen } /** - * Returns a view that is laid out and styled to look like a regular contact, with the correct - * click behavior (to launch the all contacts activity when it is clicked). + * Prepares the favorites menu which contains the static label "Speed Dial" and the + * "All Contacts" button. Taps anywhere in the view take the user to "All Contacts". + * This emulates how the headers in Play Store work. */ - private View prepareAllContactsButton(View v) { - final ContactListItemView view = (ContactListItemView) v; - view.setOnClickListener(new OnClickListener() { + private void prepareFavoritesMenu(View favoritesMenu) { + // Set the onClick listener for the view to bring up the all contacts view. + favoritesMenu.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { showAllContacts(); } }); - - view.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT); - final Resources resources = getResources(); - view.setBackgroundResource(R.drawable.contact_list_item_background); - - view.setPaddingRelative( - resources.getDimensionPixelSize(R.dimen.favorites_row_start_padding), - resources.getDimensionPixelSize(R.dimen.favorites_row_end_padding), - resources.getDimensionPixelSize(R.dimen.favorites_row_top_padding), - resources.getDimensionPixelSize(R.dimen.favorites_row_bottom_padding)); - - view.setDisplayName(resources.getString(R.string.show_all_contacts_button_text)); - view.setDrawableResource(R.drawable.list_item_avatar_bg, - R.drawable.ic_menu_all_contacts_dk); - return view; } } diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java index e7190c52f..7d5dba25e 100644 --- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java @@ -49,12 +49,12 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { private static final String TAG = PhoneFavoriteMergedAdapter.class.getSimpleName(); - private static final int TILE_INTERACTION_TEASER_VIEW_POSITION = 2; + private static final int TILE_INTERACTION_TEASER_VIEW_POSITION = 3; private static final int TILE_INTERACTION_TEASER_VIEW_ID = -2; - private static final int ALL_CONTACTS_BUTTON_ITEM_ID = -1; + private static final int FAVORITES_MENU_ITEM_ID = -3; private final PhoneFavoritesTileAdapter mContactTileAdapter; private final CallLogAdapter mCallLogAdapter; - private final View mShowAllContactsButton; + private final View mPhoneFavoritesMenu; private final PhoneFavoriteFragment mFragment; private final TileInteractionTeaserView mTileInteractionTeaserView; @@ -103,7 +103,7 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { PhoneFavoriteFragment fragment, PhoneFavoritesTileAdapter contactTileAdapter, CallLogAdapter callLogAdapter, - View showAllContactsButton, + View phoneFavoritesMenu, TileInteractionTeaserView tileInteractionTeaserView) { final Resources resources = context.getResources(); mContext = context; @@ -114,20 +114,24 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { mObserver = new CustomDataSetObserver(); mCallLogAdapter.registerDataSetObserver(mObserver); mContactTileAdapter.registerDataSetObserver(mObserver); - mShowAllContactsButton = showAllContactsButton; + mPhoneFavoritesMenu = phoneFavoritesMenu; mTileInteractionTeaserView = tileInteractionTeaserView; mCallLogQueryHandler = new CallLogQueryHandler(mContext.getContentResolver(), mCallLogQueryHandlerListener); } + /** + * Determines the number of items in the adapter. + * mCallLogAdapter contains the item for the most recent caller. + * mContactTileAdapter contains the starred contacts. + * The +1 is to account for the presence of the favorites menu. + * + * @return Number of items in the adapter. + */ @Override public int getCount() { - if (mContactTileAdapter.getCount() > 0) { - return mContactTileAdapter.getCount() + mCallLogAdapter.getCount() + 1 + - getTeaserViewCount(); - } else { - return mCallLogAdapter.getCount(); - } + return mContactTileAdapter.getCount() + mCallLogAdapter.getCount() + getTeaserViewCount() + + 1; } @Override @@ -151,9 +155,9 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { * * These are the ranges of IDs reserved for each item type. * - * -(N + 1) to -3: CallLogAdapterItems, where N is equal to the number of call log items + * -4 and lower: CallLogAdapterItems representing most recent call. + * -3: Favorites menu * -2: Teaser - * -1: All contacts button * 0 to (N -1): Rows of tiled contacts, where N is equal to the max rows of tiled contacts * N to infinity: Rows of regular contacts. Their item id is calculated by N + contact_id, * where contact_id is guaranteed to never be negative. @@ -163,17 +167,19 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { final int callLogAdapterCount = mCallLogAdapter.getCount(); if (position < callLogAdapterCount) { // Call log items are not animated, so reusing their position for IDs is fine. - return ALL_CONTACTS_BUTTON_ITEM_ID - 2 - position; + return FAVORITES_MENU_ITEM_ID - 1 - position; } else if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount && - mTileInteractionTeaserView.getShouldDisplayInList()){ + mTileInteractionTeaserView.getShouldDisplayInList()) { return TILE_INTERACTION_TEASER_VIEW_ID; + } else if (position == callLogAdapterCount) { + return FAVORITES_MENU_ITEM_ID; } else if (position < (callLogAdapterCount + mContactTileAdapter.getCount() + - getTeaserViewCount())) { + getTeaserViewCount() + 1)) { return mContactTileAdapter.getItemId( getAdjustedFavoritePosition(position, callLogAdapterCount)); } else { - // All contacts button - return ALL_CONTACTS_BUTTON_ITEM_ID; + // Default fallback. We don't normally get here. + return FAVORITES_MENU_ITEM_ID; } } @@ -182,12 +188,15 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { return true; } + /** + * Determine the number of view types present. + */ @Override public int getViewTypeCount() { return (mContactTileAdapter.getViewTypeCount() + /* Favorite and frequent */ mCallLogAdapter.getViewTypeCount() + /* Recent call log */ getTeaserViewCount() + /* Teaser */ - 1); /* Show all contacts button. */ + 1); /* Favorites menu. */ } @Override @@ -200,60 +209,66 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { return mContactTileAdapter.getViewTypeCount(); } else if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount && mTileInteractionTeaserView.getShouldDisplayInList()) { - // View type of the teaser row is the last view type of the contact tile adapter + 3 + // View type of the teaser row is the last view type of the contact tile adapter +2 return mContactTileAdapter.getViewTypeCount() + 2; - } else if (position < getCount() - 1) { + } else if (position == callLogAdapterCount) { + // View type of the favorites menu is last view type of contact tile adapter +3 + return mContactTileAdapter.getViewTypeCount() + 3; + } else if (position < getCount()) { return mContactTileAdapter.getItemViewType( getAdjustedFavoritePosition(position, callLogAdapterCount)); } else { - // View type of the show all contact button is the last view type of the contact tile - // adapter + 2 - return mContactTileAdapter.getViewTypeCount() + 1; + // Catch-all - we shouldn't get here but if we do use the same as the favorites menu. + return mContactTileAdapter.getViewTypeCount() + 3; } } + /** + * Determines the view for a specified position. + * + * @param position Position for which to retrieve view. + * @return view corresponding to position. + */ @Override public View getView(int position, View convertView, ViewGroup parent) { final int callLogAdapterCount = mCallLogAdapter.getCount(); - if ((position == getCount() - 1) && (mContactTileAdapter.getCount() > 0)) { - return mShowAllContactsButton; - } - - if (mTileInteractionTeaserView.getShouldDisplayInList()) { - if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount) { - return mTileInteractionTeaserView; + // Get the view for the "teaser view" which describes how to re-arrange favorites. + if (mTileInteractionTeaserView.getShouldDisplayInList() + && position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount) { + return mTileInteractionTeaserView; + } else if (callLogAdapterCount > 0 && position < callLogAdapterCount) { + // Handle case where we are requesting the view for the "most recent caller". + + final SwipeableCallLogRow wrapper; + if (convertView == null) { + wrapper = new SwipeableCallLogRow(mContext); + wrapper.setOnItemSwipeListener(mCallLogOnItemSwipeListener); + } else { + wrapper = (SwipeableCallLogRow) convertView; } - } - if (callLogAdapterCount > 0) { - if (position == 0) { - final SwipeableCallLogRow wrapper; - if (convertView == null) { - wrapper = new SwipeableCallLogRow(mContext); - wrapper.setOnItemSwipeListener(mCallLogOnItemSwipeListener); - } else { - wrapper = (SwipeableCallLogRow) convertView; - } - - // Special case wrapper view for the most recent call log item. This allows - // us to create a card-like effect for the more recent call log item in - // the PhoneFavoriteMergedAdapter, but keep the original look of the item in - // the CallLogAdapter. - final View view = mCallLogAdapter.getView(position, convertView == null ? - null : wrapper.getChildAt(0), parent); - wrapper.removeAllViews(); - final View callLogItem = view.findViewById(R.id.call_log_list_item); - // Reset the internal call log item view if it is being recycled - callLogItem.setTranslationX(0); - callLogItem.setAlpha(1); - wrapper.addView(view); - return wrapper; - } + // Special case wrapper view for the most recent call log item. This allows + // us to create a card-like effect for the more recent call log item in + // the PhoneFavoriteMergedAdapter, but keep the original look of the item in + // the CallLogAdapter. + final View view = mCallLogAdapter.getView(position, convertView == null ? + null : wrapper.getChildAt(0), parent); + wrapper.removeAllViews(); + final View callLogItem = view.findViewById(R.id.call_log_list_item); + // Reset the internal call log item view if it is being recycled + callLogItem.setTranslationX(0); + callLogItem.setAlpha(1); + wrapper.addView(view); + return wrapper; + } else if (position == callLogAdapterCount) { + // If position is just after the entries in the mCallLogAdapter (most recent call), + // return the favorites menu. + return mPhoneFavoritesMenu; } - // Set position to the position of the actual favorite contact in the - // favorites adapter + // Set position to the position of the actual favorite contact in the favorites adapter. + // Adjusts based on the presence of other views, such as the favorites menu. position = getAdjustedFavoritePosition(position, callLogAdapterCount); // Favorites section @@ -285,15 +300,26 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { } } + /** + * Determines the index into the mContactTileAdapter for the current position. + * + * @param position current position in the overall adapter. + * @param callLogAdapterCount number of entries in "last calls" list (ie 0 or 1). + * @return position in the mContactTileAdapter. + */ private int getAdjustedFavoritePosition(int position, int callLogAdapterCount) { if (position - callLogAdapterCount > TILE_INTERACTION_TEASER_VIEW_POSITION && mTileInteractionTeaserView.getShouldDisplayInList()) { - return position - callLogAdapterCount - 1; + return position - callLogAdapterCount - 2; } else { - return position - callLogAdapterCount; + return position - callLogAdapterCount - 1; } } + /** + * Determines the number of teaser views visible. + * @return 1 or 0 depending on if the teaser view is showing. + */ private int getTeaserViewCount() { return (mContactTileAdapter.getCount() > TILE_INTERACTION_TEASER_VIEW_POSITION && mTileInteractionTeaserView.getShouldDisplayInList() ? 1 : 0); |