Adjusting section header layout according to UI design
Change-Id: Ia027d807798eb4c2619f5ee542d6c802a62b545f
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
index e616582..1ced586 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-xlarge/styles.xml
@@ -30,9 +30,11 @@
<item name="list_item_call_button_padding">14dip</item>
<item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">5dip</item>
- <item name="list_item_header_text_width">56dip</item>
<item name="list_item_photo_size">64dip</item>
<item name="list_item_prefix_highlight_color">#729a27</item>
+ <item name="list_item_header_text_indent">77dip</item>
+ <item name="list_item_header_text_color">?color/section_header_text_color</item>
+ <item name="list_item_header_text_size">14sp</item>
<item name="contact_filter_popup_width">320dip</item>
</style>
@@ -48,11 +50,11 @@
<item name="list_item_call_button_padding">14dip</item>
<item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">5dip</item>
- <item name="list_item_header_text_width">56dip</item>
<item name="list_item_photo_size">64dip</item>
+ <item name="list_item_header_text_indent">77dip</item>
+ <item name="list_item_header_text_color">?color/section_header_text_color</item>
+ <item name="list_item_header_text_size">14sp</item>
</style>
-
-
<style name="ContactsPreferencesTheme" parent="@android:Theme.Light.Holo">
</style>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9bb9728..2c1d250 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -103,9 +103,11 @@
<attr name="list_item_call_button_padding" format="dimension"/>
<attr name="list_item_vertical_divider_margin" format="dimension"/>
<attr name="list_item_presence_icon_margin" format="dimension"/>
- <attr name="list_item_header_text_width" format="dimension"/>
<attr name="list_item_photo_size" format="dimension"/>
<attr name="list_item_prefix_highlight_color" format="color"/>
+ <attr name="list_item_header_text_indent" format="dimension" />
+ <attr name="list_item_header_text_color" format="color" />
+ <attr name="list_item_header_text_size" format="dimension" />
</declare-styleable>
<declare-styleable name="MultiplePhonePickerItemView">
@@ -127,9 +129,11 @@
<item name="list_item_call_button_padding">14dip</item>
<item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">5dip</item>
- <item name="list_item_header_text_width">56dip</item>
<item name="list_item_photo_size">56dip</item>
<item name="list_item_prefix_highlight_color">#729a27</item>
+ <item name="list_item_header_text_indent">56dip</item>
+ <item name="list_item_header_text_color">?color/section_header_text_color</item>
+ <item name="list_item_header_text_size">14sp</item>
<item name="contact_filter_popup_width">320dip</item>
</style>
@@ -145,12 +149,14 @@
<item name="list_item_call_button_padding">14dip</item>
<item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">5dip</item>
- <item name="list_item_header_text_width">56dip</item>
<item name="list_item_photo_size">56dip</item>
<item name="list_item_prefix_highlight_color">#729a27</item>
<item name="list_item_header_chip_width">4dip</item>
<item name="list_item_header_chip_right_margin">4dip</item>
<item name="list_item_header_checkbox_margin">5dip</item>
+ <item name="list_item_header_text_indent">56dip</item>
+ <item name="list_item_header_text_color">?color/section_header_text_color</item>
+ <item name="list_item_header_text_size">14sp</item>
</style>
<style name="JoinContactActivityTheme" parent="ContactPickerTheme">
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 41136d4..7cfd672 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -71,10 +71,20 @@
private boolean mSelectionVisible;
public ContactEntryListAdapter(Context context) {
- super(context, R.layout.list_section, R.id.header_text);
+ super(context);
addPartitions();
}
+ @Override
+ protected View createPinnedSectionHeaderView(Context context, ViewGroup parent) {
+ return new ContactListPinnedHeaderView(context, null);
+ }
+
+ @Override
+ protected void setPinnedSectionTitle(View pinnedHeaderView, String title) {
+ ((ContactListPinnedHeaderView)pinnedHeaderView).setSectionHeader(title);
+ }
+
protected void addPartitions() {
addPartition(createDefaultDirectoryPartition());
}
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index ded0651..e16972a 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -66,8 +66,10 @@
private final int mGapBetweenLabelAndData;
private final int mCallButtonPadding;
private final int mPresenceIconMargin;
- private final int mHeaderTextWidth;
private final int mPrefixHightlightColor;
+ private final int mHeaderTextColor;
+ private final int mHeaderTextIndent;
+ private final int mHeaderTextSize;
private Drawable mPressedBackgroundDrawable;
private Drawable mActivatedBackgroundDrawable;
@@ -151,7 +153,7 @@
a.getDimensionPixelSize(android.R.styleable.Theme_listPreferredItemHeight, 0);
a.recycle();
- a = getContext().obtainStyledAttributes(attrs,R.styleable.ContactListItemView);
+ a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
mPressedBackgroundDrawable = a.getDrawable(
R.styleable.ContactListItemView_pressedBackground);
mHeaderBackgroundDrawable = a.getDrawable(
@@ -176,12 +178,16 @@
R.styleable.ContactListItemView_list_item_call_button_padding, 0);
mPresenceIconMargin = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_presence_icon_margin, 0);
- mHeaderTextWidth = a.getDimensionPixelOffset(
- R.styleable.ContactListItemView_list_item_header_text_width, 0);
mDefaultPhotoViewSize = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_photo_size, 0);
mPrefixHightlightColor = a.getColor(
R.styleable.ContactListItemView_list_item_prefix_highlight_color, Color.GREEN);
+ mHeaderTextIndent = a.getDimensionPixelOffset(
+ R.styleable.ContactListItemView_list_item_header_text_indent, 0);
+ mHeaderTextColor = a.getColor(
+ R.styleable.ContactListItemView_list_item_header_text_color, Color.BLACK);
+ mHeaderTextSize = a.getDimensionPixelSize(
+ R.styleable.ContactListItemView_list_item_header_text_size, 12);
a.recycle();
@@ -268,7 +274,7 @@
if (mHeaderVisible) {
mHeaderTextView.measure(
- MeasureSpec.makeMeasureSpec(mHeaderTextWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
height += mHeaderBackgroundHeight;
}
@@ -291,7 +297,7 @@
0,
width,
mHeaderBackgroundHeight);
- mHeaderTextView.layout(0, 0, width, mHeaderBackgroundHeight);
+ mHeaderTextView.layout(mHeaderTextIndent, 0, width, mHeaderBackgroundHeight);
topBound += mHeaderBackgroundHeight;
}
@@ -519,11 +525,10 @@
if (!TextUtils.isEmpty(title)) {
if (mHeaderTextView == null) {
mHeaderTextView = new TextView(mContext);
+ mHeaderTextView.setTextColor(mHeaderTextColor);
+ mHeaderTextView.setTextSize(mHeaderTextSize);
mHeaderTextView.setTypeface(mHeaderTextView.getTypeface(), Typeface.BOLD);
- mHeaderTextView.setTextColor(mContext.getResources()
- .getColor(R.color.section_header_text_color));
- mHeaderTextView.setTextSize(14);
- mHeaderTextView.setGravity(Gravity.CENTER);
+ mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL);
addView(mHeaderTextView);
}
mHeaderTextView.setText(title);
diff --git a/src/com/android/contacts/list/ContactListPinnedHeaderView.java b/src/com/android/contacts/list/ContactListPinnedHeaderView.java
new file mode 100644
index 0000000..e850511
--- /dev/null
+++ b/src/com/android/contacts/list/ContactListPinnedHeaderView.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package com.android.contacts.list;
+
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * A custom view for the pinned section header shown at the top of the contact list.
+ */
+public class ContactListPinnedHeaderView extends ViewGroup {
+
+ protected final Context mContext;
+
+ private final int mHeaderTextColor;
+ private final int mHeaderTextIndent;
+ private final int mHeaderTextSize;
+
+ private Drawable mHeaderBackgroundDrawable;
+ private int mHeaderBackgroundHeight;
+ private TextView mHeaderTextView;
+
+ public ContactListPinnedHeaderView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+
+ TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
+
+ mHeaderBackgroundDrawable = a.getDrawable(
+ R.styleable.ContactListItemView_section_header_background);
+ mHeaderTextIndent = a.getDimensionPixelOffset(
+ R.styleable.ContactListItemView_list_item_header_text_indent, 0);
+ mHeaderTextColor = a.getColor(
+ R.styleable.ContactListItemView_list_item_header_text_color, Color.BLACK);
+ mHeaderTextSize = a.getDimensionPixelSize(
+ R.styleable.ContactListItemView_list_item_header_text_size, 12);
+
+ a.recycle();
+
+ mHeaderBackgroundHeight = mHeaderBackgroundDrawable.getIntrinsicHeight();
+
+ mHeaderTextView = new TextView(mContext);
+ mHeaderTextView.setTextColor(mHeaderTextColor);
+ mHeaderTextView.setTextSize(mHeaderTextSize);
+ mHeaderTextView.setTypeface(mHeaderTextView.getTypeface(), Typeface.BOLD);
+ mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL);
+ addView(mHeaderTextView);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+ // We will match parent's width and wrap content vertically.
+ int width = resolveSize(0, widthMeasureSpec);
+
+ mHeaderTextView.measure(
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
+
+ setMeasuredDimension(width, mHeaderBackgroundHeight);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ int width = right - left;
+ mHeaderBackgroundDrawable.setBounds(0, 0, width, mHeaderBackgroundHeight);
+ mHeaderTextView.layout(mHeaderTextIndent, 0, width, mHeaderBackgroundHeight);
+ }
+
+ @Override
+ public void dispatchDraw(Canvas canvas) {
+ mHeaderBackgroundDrawable.draw(canvas);
+ super.dispatchDraw(canvas);
+ }
+
+ /**
+ * Sets section header or makes it invisible if the title is null.
+ */
+ public void setSectionHeader(String title) {
+ if (!TextUtils.isEmpty(title)) {
+ mHeaderTextView.setText(title);
+ mHeaderTextView.setVisibility(View.VISIBLE);
+ } else {
+ mHeaderTextView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void requestLayout() {
+ // We will assume that once measured this will not need to resize
+ // itself, so there is no need to pass the layout request to the parent
+ // view (ListView).
+ forceLayout();
+ }
+}
diff --git a/src/com/android/contacts/widget/IndexerListAdapter.java b/src/com/android/contacts/widget/IndexerListAdapter.java
index b26c2dc..d264254 100644
--- a/src/com/android/contacts/widget/IndexerListAdapter.java
+++ b/src/com/android/contacts/widget/IndexerListAdapter.java
@@ -16,7 +16,6 @@
package com.android.contacts.widget;
import android.content.Context;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
@@ -28,15 +27,11 @@
*/
public abstract class IndexerListAdapter extends PinnedHeaderListAdapter implements SectionIndexer {
- private final int mSectionHeaderTextViewId;
- private final int mSectionHeaderLayoutResId;
-
protected Context mContext;
private SectionIndexer mIndexer;
private int mIndexedPartition = 0;
private boolean mSectionHeaderDisplayEnabled;
private View mHeader;
- private TextView mTitleView;
/**
* An item view is displayed differently depending on whether it is placed
@@ -59,19 +54,23 @@
/**
* Constructor.
- *
- * @param context
- * @param sectionHeaderLayoutResourceId section header layout resource ID
- * @param sectionHeaderTextViewId section header text view ID
*/
- public IndexerListAdapter(Context context, int sectionHeaderLayoutResourceId,
- int sectionHeaderTextViewId) {
+ public IndexerListAdapter(Context context) {
super(context);
mContext = context;
- mSectionHeaderLayoutResId = sectionHeaderLayoutResourceId;
- mSectionHeaderTextViewId = sectionHeaderTextViewId;
}
+ /**
+ * Creates a section header view that will be pinned at the top of the list
+ * as the user scrolls.
+ */
+ protected abstract View createPinnedSectionHeaderView(Context context, ViewGroup parent);
+
+ /**
+ * Sets the title in the pinned header as the user scrolls.
+ */
+ protected abstract void setPinnedSectionTitle(View pinnedHeaderView, String title);
+
public boolean isSectionHeaderDisplayEnabled() {
return mSectionHeaderDisplayEnabled;
}
@@ -140,9 +139,7 @@
public View getPinnedHeaderView(int viewIndex, View convertView, ViewGroup parent) {
if (isSectionHeaderDisplayEnabled() && viewIndex == getPinnedHeaderCount() - 1) {
if (mHeader == null) {
- mHeader = LayoutInflater.from(mContext).
- inflate(mSectionHeaderLayoutResId, parent, false);
- mTitleView = (TextView)mHeader.findViewById(mSectionHeaderTextViewId);
+ mHeader = createPinnedSectionHeaderView(mContext, parent);
}
return mHeader;
} else {
@@ -177,8 +174,7 @@
if (section == -1) {
listView.setHeaderInvisible(index, false);
} else {
- String title = (String)mIndexer.getSections()[section];
- mTitleView.setText(title);
+ setPinnedSectionTitle(mHeader, (String)mIndexer.getSections()[section]);
// Compute the item position where the current partition begins
int partitionStart = getPositionForPartition(mIndexedPartition);
diff --git a/src/com/android/contacts/widget/PinnedHeaderListView.java b/src/com/android/contacts/widget/PinnedHeaderListView.java
index a533927..35291bf 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListView.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListView.java
@@ -25,6 +25,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
@@ -344,9 +345,9 @@
if (view.isLayoutRequested()) {
int widthSpec = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY);
int heightSpec;
- int lpHeight = view.getLayoutParams().height;
- if (lpHeight > 0) {
- heightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
+ ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+ if (layoutParams != null && layoutParams.height > 0) {
+ heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
} else {
heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}