[Phone] Fix layout for phone favorite screen

- Have additional padding between headers
- Use blue color for filter header in phone favorite
- Have bigger texts for A-Z section header
- Have photos on left in "phone search" screen
- Add "New Contacts" menu in favorite screen

Because LayoutFilter isn't ready on Fragment#onAttach(),
we need to have initAdapters() on onCreateView(), which looks
strange. However it will need much work to move every layout
logic to PhoneFavoriteMergedAdapter, let's just have a TODO
for that.

Bug: 5432231
Change-Id: I19b0849a6ec1fd38bec259859753dab13b88cc12
diff --git a/res/layout/list_separator.xml b/res/layout/list_separator.xml
index 2aeb1ba..3ffaca7 100644
--- a/res/layout/list_separator.xml
+++ b/res/layout/list_separator.xml
@@ -33,4 +33,4 @@
         android:singleLine="true"
         android:ellipsize="end" />
 
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/res/layout/phone_favorite_account_filter_header.xml b/res/layout/phone_favorite_account_filter_header.xml
new file mode 100644
index 0000000..d63382a
--- /dev/null
+++ b/res/layout/phone_favorite_account_filter_header.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Layout showing the type of account filter in phone favorite screen.
+
+     Note: This xml is based on account_filter_header.xml and list_separator.xml.
+     Some configurations (e.g. padding) are from account_filter_header.xml, while
+     some other configurations (e.g. background, height, text style) are from
+     list_separator.xml. See also bug 5432231. -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/account_filter_header_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="32dip"
+    android:paddingTop="@dimen/contact_browser_list_top_margin"
+    android:layout_marginLeft="@dimen/contact_browser_list_header_left_margin"
+    android:layout_marginRight="@dimen/contact_browser_list_header_right_margin"
+    android:background="?android:attr/selectableItemBackground"
+    android:visibility="gone">
+    <TextView
+        android:id="@+id/account_filter_header"
+        style="?android:attr/listSeparatorTextViewStyle"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textStyle="bold"
+        android:textAllCaps="true"
+        android:textColor="@color/people_app_theme_color"
+        android:paddingLeft="@dimen/contact_browser_list_item_text_indent"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:background="@drawable/list_section_divider_holo_custom" />
+</FrameLayout>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f33f2a6..dd62594 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -40,7 +40,7 @@
         <item name="list_item_prefix_highlight_color">#729a27</item>
         <item name="list_item_header_text_indent">8dip</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
-        <item name="list_item_header_text_size">12sp</item>
+        <item name="list_item_header_text_size">14sp</item>
         <item name="list_item_header_height">24dip</item>
         <item name="list_item_header_underline_height">1dip</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index f06b227..05951d6 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -24,8 +24,7 @@
 import com.android.contacts.list.ContactListFilter;
 import com.android.contacts.list.ContactListFilterController;
 import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
-import com.android.contacts.list.ContactTileAdapter.DisplayType;
-import com.android.contacts.list.ContactTileListFragment;
+import com.android.contacts.list.ContactListItemView;
 import com.android.contacts.list.OnPhoneNumberPickerActionListener;
 import com.android.contacts.list.PhoneFavoriteFragment;
 import com.android.contacts.list.PhoneNumberPickerFragment;
@@ -505,6 +504,7 @@
             mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener);
             mSearchFragment.setQuickContactEnabled(true);
             mSearchFragment.setDarkTheme(true);
+            mSearchFragment.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
             final FragmentTransaction transaction = getFragmentManager().beginTransaction();
             if (mInSearchUi) {
                 transaction.show(mSearchFragment);
@@ -769,10 +769,13 @@
                 filterOptionMenuItem.setVisible(true);
                 filterOptionMenuItem.setOnMenuItemClickListener(
                         mFilterOptionsMenuItemClickListener);
+                addContactOptionMenuItem.setVisible(true);
+                addContactOptionMenuItem.setIntent(
+                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
             } else {
                 filterOptionMenuItem.setVisible(false);
+                addContactOptionMenuItem.setVisible(false);
             }
-            addContactOptionMenuItem.setVisible(false);
 
             if (showCallSettingsMenu) {
                 callSettingsMenuItem.setVisible(true);
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 860e368..41be5fa 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -213,27 +213,47 @@
 
         mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
         mContactsPrefs = new ContactsPreferences(activity);
+    }
 
-        // Create the account filter header but keep it hidden until "all" contacts are loaded.
-        mAccountFilterHeaderContainer = View.inflate(
-                activity, R.layout.account_filter_header, null);
-        mAccountFilterHeaderView =
-                (TextView) mAccountFilterHeaderContainer.findViewById(R.id.account_filter_header);
-        mAccountFilterHeaderContainer.setOnClickListener(mFilterHeaderClickListener);
-        mAccountFilterHeaderContainer.setVisibility(View.GONE);
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        final View listLayout = inflater.inflate(R.layout.contact_tile_list, container, false);
 
-        initAdapters(activity);
+        mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list);
+        mListView.setItemsCanFocus(true);
+        mListView.setOnItemClickListener(this);
+        mListView.setFastScrollEnabled(true);
+        // We want to hide the scroll bar after a while.
+        mListView.setFastScrollAlwaysVisible(false);
+        mListView.setVerticalScrollBarEnabled(true);
+        mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
+        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
 
-        mAllContactsAdapter.setFilter(mFilter);
-        mAllContactsForceReload = true;
+        initAdapters(getActivity(), inflater);
+
+        mListView.setAdapter(mAdapter);
+
+        mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty);
+        mEmptyView.setText(getString(R.string.listTotalAllContactsZero));
+        mListView.setEmptyView(mEmptyView);
+
         updateFilterHeaderView();
+
+        return listLayout;
     }
 
     /**
      * Constructs and initializes {@link #mContactTileAdapter}, {@link #mAllContactsAdapter}, and
      * {@link #mAllContactsAdapter}.
+     *
+     * TODO: Move all the code here to {@link PhoneFavoriteMergedAdapter} if possible.
+     * There are two problems: account header (whose content changes depending on filter settings)
+     * and OnClickListener (which initiates {@link Activity#startActivityForResult(Intent, int)}).
+     * See also issue 5429203, 5269692, and 5432286. If we are able to have a singleton for filter,
+     * this work will become easier.
      */
-    private void initAdapters(Context context) {
+    private void initAdapters(Context context, LayoutInflater inflater) {
         mContactTileAdapter = new ContactTileAdapter(context, mContactTileAdapterListener,
                 getResources().getInteger(R.integer.contact_tile_column_count),
                 ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
@@ -257,8 +277,21 @@
         // Put photos on left for consistency with "frequent" contacts section.
         mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
 
-        mAdapter = new PhoneFavoriteMergedAdapter(
-                context, mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
+        if (mFilter != null) {
+            mAllContactsAdapter.setFilter(mFilter);
+        }
+
+        // Create the account filter header but keep it hidden until "all" contacts are loaded.
+        mAccountFilterHeaderContainer = inflater.inflate(
+                R.layout.phone_favorite_account_filter_header, mListView, false);
+        mAccountFilterHeaderView =
+                (TextView) mAccountFilterHeaderContainer.findViewById(R.id.account_filter_header);
+        mAccountFilterHeaderContainer.setOnClickListener(mFilterHeaderClickListener);
+        mAccountFilterHeaderContainer.setVisibility(View.GONE);
+
+        mAdapter = new PhoneFavoriteMergedAdapter(context,
+                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
+
     }
 
     @Override
@@ -268,32 +301,6 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        final View listLayout = inflater.inflate(R.layout.contact_tile_list, container, false);
-
-        mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list);
-
-        mListView.setItemsCanFocus(true);
-        mListView.setAdapter(mAdapter);
-        mListView.setOnItemClickListener(this);
-        mListView.setFastScrollEnabled(true);
-        // We want to hide the scroll bar after a while.
-        mListView.setFastScrollAlwaysVisible(false);
-        mListView.setVerticalScrollBarEnabled(true);
-        mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
-        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
-
-        mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty);
-        mEmptyView.setText(getString(R.string.listTotalAllContactsZero));
-        mListView.setEmptyView(mEmptyView);
-
-        updateFilterHeaderView();
-
-        return listLayout;
-    }
-
-    @Override
     public void onStart() {
         super.onStart();
 
@@ -425,9 +432,11 @@
             ContactListFilter.storeToPreferences(mPrefs, mFilter);
         }
 
-        mAllContactsAdapter.setFilter(mFilter);
-        requestReloadAllContacts();
-        updateFilterHeaderView();
+        if (mAllContactsAdapter != null) {
+            mAllContactsAdapter.setFilter(mFilter);
+            requestReloadAllContacts();
+            updateFilterHeaderView();
+        }
     }
 
     public void setListener(Listener listener) {
diff --git a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
index c3c96ec..668bd6c 100644
--- a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
@@ -53,6 +53,9 @@
     private final int mItemPaddingLeft;
     private final int mItemPaddingRight;
 
+    // Make frequent header consistent with account filter header.
+    private final int mFrequentHeaderPaddingTop;
+
     private final DataSetObserver mObserver;
 
     public PhoneFavoriteMergedAdapter(Context context,
@@ -62,6 +65,8 @@
         Resources resources = context.getResources();
         mItemPaddingLeft = resources.getDimensionPixelSize(R.dimen.detail_item_side_margin);
         mItemPaddingRight = resources.getDimensionPixelSize(R.dimen.list_visible_scrollbar_padding);
+        mFrequentHeaderPaddingTop = resources.getDimensionPixelSize(
+                R.dimen.contact_browser_list_top_margin);
         mContactTileAdapter = contactTileAdapter;
         mContactEntryListAdapter = contactEntryListAdapter;
 
@@ -140,7 +145,7 @@
             if (position < frequentHeaderPosition) {  // "starred" contacts
                 // No padding adjustment.
             } else if (position == frequentHeaderPosition) {
-                view.setPadding(mItemPaddingLeft, view.getPaddingTop(),
+                view.setPadding(mItemPaddingLeft, mFrequentHeaderPaddingTop,
                         mItemPaddingRight, view.getPaddingBottom());
             } else {
                 // Views for "frequent" contacts use FrameLayout's margins instead of padding.
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index 015a364..dd53b4b 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -58,6 +58,9 @@
     /** true if the loader has started at least once. */
     private boolean mLoaderStarted;
 
+    private ContactListItemView.PhotoPosition mPhotoPosition =
+            ContactListItemView.DEFAULT_PHOTO_POSITION;
+
     // A complete copy from DefaultContactBrowserListFragment
     // TODO: should be able to share logic around filter header.
     private class FilterHeaderClickListener implements OnClickListener {
@@ -191,11 +194,11 @@
     protected void onItemClick(int position, long id) {
         final Uri phoneUri;
         if (!isLegacyCompatibilityMode()) {
-            PhoneNumberListAdapter adapter = (PhoneNumberListAdapter)getAdapter();
+            PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
             phoneUri = adapter.getDataUri(position);
 
         } else {
-            LegacyPhoneNumberListAdapter adapter = (LegacyPhoneNumberListAdapter)getAdapter();
+            LegacyPhoneNumberListAdapter adapter = (LegacyPhoneNumberListAdapter) getAdapter();
             phoneUri = adapter.getPhoneUri(position);
         }
 
@@ -229,7 +232,7 @@
     protected void configureAdapter() {
         super.configureAdapter();
 
-        ContactEntryListAdapter adapter = getAdapter();
+        final ContactEntryListAdapter adapter = getAdapter();
         if (adapter == null) {
             return;
         }
@@ -237,6 +240,10 @@
         if (!isSearchMode() && mFilter != null) {
             adapter.setFilter(mFilter);
         }
+
+        if (!isLegacyCompatibilityMode()) {
+            ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
+        }
     }
 
     @Override
@@ -288,4 +295,16 @@
         }
         updateFilterHeaderView();
     }
+
+    public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
+        mPhotoPosition = photoPosition;
+        if (!isLegacyCompatibilityMode()) {
+            final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
+            if (adapter != null) {
+                adapter.setPhotoPosition(photoPosition);
+            }
+        } else {
+            Log.w(TAG, "setPhotoPosition() is ignored in legacy compatibility mode.");
+        }
+    }
 }