[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.");
+ }
+ }
}