Merge "Remove "TODO use syncadapter package instead""
diff --git a/src/com/android/contacts/common/list/ContactEntryListAdapter.java b/src/com/android/contacts/common/list/ContactEntryListAdapter.java
index 92048b8..900cffc 100644
--- a/src/com/android/contacts/common/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/common/list/ContactEntryListAdapter.java
@@ -36,7 +36,6 @@
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.R;
-import com.android.contacts.common.list.ContactListAdapter.ContactQuery;
import com.android.contacts.common.util.SearchUtil;
import java.util.HashSet;
@@ -101,29 +100,21 @@
}
@Override
+ protected ContactListItemView newView(
+ Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
+ final ContactListItemView view = new ContactListItemView(context, null);
+ view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
+ return view;
+ }
+
+ @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);
- }
-
- @Override
- protected void setPinnedHeaderContactsCount(View header) {
- // Update the header with the contacts count only if a profile header exists
- // otherwise, the contacts count are shown in the empty profile header view
- if (mProfileExists) {
- ((ContactListPinnedHeaderView)header).setCountView(mContactsCount);
- } else {
- clearPinnedHeaderContactsCount(header);
- }
- }
-
- @Override
- protected void clearPinnedHeaderContactsCount(View header) {
- ((ContactListPinnedHeaderView)header).setCountView(null);
+ ((ContactListPinnedHeaderView) pinnedHeaderView).setSectionHeaderTitle(title);
}
protected void addPartitions() {
diff --git a/src/com/android/contacts/common/list/ContactListAdapter.java b/src/com/android/contacts/common/list/ContactListAdapter.java
index 0750459..4bfbdcf 100644
--- a/src/com/android/contacts/common/list/ContactListAdapter.java
+++ b/src/com/android/contacts/common/list/ContactListAdapter.java
@@ -194,9 +194,9 @@
}
@Override
- protected View newView(Context context, int partition, Cursor cursor, int position,
- ViewGroup parent) {
- ContactListItemView view = new ContactListItemView(context, null);
+ protected ContactListItemView newView(
+ Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
+ ContactListItemView view = super.newView(context, partition, cursor, position, parent);
view.setUnknownNameText(mUnknownNameText);
view.setQuickContactEnabled(isQuickContactEnabled());
view.setActivatedStateSupported(isSelectionVisible());
@@ -210,19 +210,9 @@
Cursor cursor) {
if (isSectionHeaderDisplayEnabled()) {
Placement placement = getItemPlacementInSection(position);
-
- // First position, set the contacts number string
- if (position == 0 && cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1) {
- view.setCountView(getContactsCount());
- } else {
- view.setCountView(null);
- }
view.setSectionHeader(placement.sectionHeader);
- view.setDividerVisible(!placement.lastInSection);
} else {
view.setSectionHeader(null);
- view.setDividerVisible(true);
- view.setCountView(null);
}
}
diff --git a/src/com/android/contacts/common/list/ContactListItemView.java b/src/com/android/contacts/common/list/ContactListItemView.java
index b6aa800..462889c 100644
--- a/src/com/android/contacts/common/list/ContactListItemView.java
+++ b/src/com/android/contacts/common/list/ContactListItemView.java
@@ -22,20 +22,17 @@
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
-import android.telephony.PhoneNumberUtils;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
-import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -86,14 +83,8 @@
private int mGapBetweenLabelAndData = 0;
private int mPresenceIconMargin = 4;
private int mPresenceIconSize = 16;
- private int mHeaderTextColor = Color.BLACK;
- private int mHeaderTextIndent = 0;
- private int mHeaderTextSize = 12;
- private int mHeaderUnderlineHeight = 1;
- private int mHeaderUnderlineColor = 0;
- private int mCountViewTextSize = 12;
- private int mContactsCountTextColor = Color.BLACK;
private int mTextIndent = 0;
+ private int mHeaderWidth;
private Drawable mActivatedBackgroundDrawable;
/**
@@ -105,15 +96,6 @@
*/
private int mDataViewWidthWeight = 5;
- // Will be used with adjustListItemSelectionBounds().
- private int mSelectionBoundsMarginLeft;
- private int mSelectionBoundsMarginRight;
-
- // Horizontal divider between contact views.
- private boolean mHorizontalDividerVisible = true;
- private Drawable mHorizontalDividerDrawable;
- private int mHorizontalDividerHeight;
-
protected static class HighlightSequence {
private final int start;
private final int end;
@@ -145,20 +127,19 @@
final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
switch (layoutDirection) {
case View.LAYOUT_DIRECTION_RTL:
- return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT);
+ return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT);
case View.LAYOUT_DIRECTION_LTR:
default:
- return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT);
+ return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT);
}
}
private PhotoPosition mPhotoPosition = getDefaultPhotoPosition(false /* normal/non opposite */);
// Header layout data
- private boolean mHeaderVisible;
- private View mHeaderDivider;
- private int mHeaderBackgroundHeight = 30;
+ private int mHeaderBackgroundHeight;
private TextView mHeaderTextView;
+ private boolean mIsSectionHeaderEnabled;
// The views inside the contact view
private boolean mQuickContactEnabled = true;
@@ -170,7 +151,6 @@
private TextView mDataView;
private TextView mSnippetView;
private TextView mStatusView;
- private TextView mCountView;
private ImageView mPresenceIcon;
private ColorStateList mSecondaryTextColor;
@@ -250,8 +230,6 @@
R.styleable.ContactListItemView_list_item_height, mPreferredHeight);
mActivatedBackgroundDrawable = a.getDrawable(
R.styleable.ContactListItemView_activated_background);
- mHorizontalDividerDrawable = a.getDrawable(
- R.styleable.ContactListItemView_list_item_divider);
mGapBetweenImageAndText = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_gap_between_image_and_text,
@@ -266,28 +244,8 @@
R.styleable.ContactListItemView_list_item_presence_icon_size, mPresenceIconSize);
mDefaultPhotoViewSize = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize);
- mHeaderTextIndent = a.getDimensionPixelOffset(
- R.styleable.ContactListItemView_list_item_header_text_indent, mHeaderTextIndent);
- mHeaderTextColor = a.getColor(
- R.styleable.ContactListItemView_list_item_header_text_color, mHeaderTextColor);
- mHeaderTextSize = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_header_text_size, mHeaderTextSize);
- mHeaderBackgroundHeight = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_header_height, mHeaderBackgroundHeight);
- mHeaderUnderlineHeight = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_header_underline_height,
- mHeaderUnderlineHeight);
- mHeaderUnderlineColor = a.getColor(
- R.styleable.ContactListItemView_list_item_header_underline_color,
- mHeaderUnderlineColor);
mTextIndent = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_text_indent, mTextIndent);
- mCountViewTextSize = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_contacts_count_text_size,
- mCountViewTextSize);
- mContactsCountTextColor = a.getColor(
- R.styleable.ContactListItemView_list_item_contacts_count_text_color,
- mContactsCountTextColor);
mDataViewWidthWeight = a.getInteger(
R.styleable.ContactListItemView_list_item_data_width_weight, mDataViewWidthWeight);
mLabelViewWidthWeight = a.getInteger(
@@ -312,7 +270,8 @@
mSecondaryTextColor = a.getColorStateList(R.styleable.Theme_android_textColorSecondary);
a.recycle();
- mHorizontalDividerHeight = mHorizontalDividerDrawable.getIntrinsicHeight();
+ mHeaderWidth =
+ getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width);
if (mActivatedBackgroundDrawable != null) {
mActivatedBackgroundDrawable.setCallback(this);
@@ -335,12 +294,7 @@
// We will match parent's width and wrap content vertically, but make sure
// height is no less than listPreferredItemHeight.
final int specWidth = resolveSize(0, widthMeasureSpec);
- final int preferredHeight;
- if (mHorizontalDividerVisible) {
- preferredHeight = mPreferredHeight + mHorizontalDividerHeight;
- } else {
- preferredHeight = mPreferredHeight;
- }
+ final int preferredHeight = mPreferredHeight;
mNameTextViewHeight = 0;
mPhoneticNameTextViewHeight = 0;
@@ -353,7 +307,7 @@
ensurePhotoViewSize();
// Width each TextView is able to use.
- final int effectiveWidth;
+ int effectiveWidth;
// All the other Views will honor the photo, so available width for them may be shrunk.
if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) {
effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight()
@@ -362,11 +316,15 @@
effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight();
}
+ if (mIsSectionHeaderEnabled) {
+ effectiveWidth -= mHeaderWidth + mGapBetweenImageAndText;
+ }
+
// Go over all visible text views and measure actual width of each of them.
// Also calculate their heights to get the total height for this entire view.
if (isVisible(mNameTextView)) {
- // Caculate width for name text - this parallels similar measurement in onLayout.
+ // Claculate width for name text - this parallels similar measurement in onLayout.
int nameTextWidth = effectiveWidth;
if (mPhotoPosition != PhotoPosition.LEFT) {
nameTextWidth -= mTextIndent;
@@ -463,29 +421,15 @@
// Make sure the height is at least as high as the photo
height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop());
- // Add horizontal divider height
- if (mHorizontalDividerVisible) {
- height += mHorizontalDividerHeight;
- }
-
// Make sure height is at least the preferred height
height = Math.max(height, preferredHeight);
- // Add the height of the header if visible
- if (mHeaderVisible) {
- final int headerWidth = specWidth -
- getPaddingLeft() - getPaddingRight() - mHeaderTextIndent;
+ // Measure the header if it is visible.
+ if (mHeaderTextView != null && mHeaderTextView.getVisibility() == VISIBLE) {
mHeaderTextView.measure(
- MeasureSpec.makeMeasureSpec(headerWidth, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
- if (mCountView != null) {
- mCountView.measure(
- MeasureSpec.makeMeasureSpec(headerWidth, MeasureSpec.AT_MOST),
- MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
- }
- mHeaderBackgroundHeight = Math.max(mHeaderBackgroundHeight,
- mHeaderTextView.getMeasuredHeight());
- height += (mHeaderBackgroundHeight + mHeaderUnderlineHeight);
+ MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+ mHeaderBackgroundHeight = Math.min(height, mHeaderTextView.getMeasuredHeight());
}
setMeasuredDimension(specWidth, height);
@@ -504,36 +448,31 @@
final boolean isLayoutRtl = ViewUtil.isViewLayoutRtl(this);
- // Put the header in the top of the contact view (Text + underline view)
- if (mHeaderVisible) {
- mHeaderTextView.layout(isLayoutRtl ? leftBound : leftBound + mHeaderTextIndent,
- 0,
- isLayoutRtl ? rightBound - mHeaderTextIndent : rightBound,
- mHeaderBackgroundHeight);
- if (mCountView != null) {
- mCountView.layout(rightBound - mCountView.getMeasuredWidth(),
- 0,
- rightBound,
+ // Put the section header on the left side of the contact view.
+ if (mIsSectionHeaderEnabled) {
+ if (mHeaderTextView != null) {
+ mHeaderTextView.layout(
+ isLayoutRtl ? rightBound - mHeaderWidth : leftBound,
+ topBound,
+ isLayoutRtl ? rightBound : leftBound + mHeaderWidth,
mHeaderBackgroundHeight);
}
- mHeaderDivider.layout(leftBound,
- mHeaderBackgroundHeight,
- rightBound,
- mHeaderBackgroundHeight + mHeaderUnderlineHeight);
- topBound += (mHeaderBackgroundHeight + mHeaderUnderlineHeight);
+ if (isLayoutRtl) {
+ rightBound -= mHeaderWidth;
+ } else {
+ leftBound += mHeaderWidth;
+ }
}
- // Put horizontal divider at the bottom
- if (mHorizontalDividerVisible) {
- mHorizontalDividerDrawable.setBounds(
- leftBound,
- height - mHorizontalDividerHeight,
- rightBound,
- height);
- bottomBound -= mHorizontalDividerHeight;
- }
+ mBoundsWithoutHeader.set(leftBound, topBound, rightBound, bottomBound);
- mBoundsWithoutHeader.set(0, topBound, width, bottomBound);
+ if (mIsSectionHeaderEnabled) {
+ if (isLayoutRtl) {
+ rightBound -= mGapBetweenImageAndText;
+ } else {
+ leftBound += mGapBetweenImageAndText;
+ }
+ }
if (mActivatedStateSupported && isActivated()) {
mActivatedBackgroundDrawable.setBounds(mBoundsWithoutHeader);
@@ -685,8 +624,8 @@
public void adjustListItemSelectionBounds(Rect bounds) {
bounds.top += mBoundsWithoutHeader.top;
bounds.bottom = bounds.top + mBoundsWithoutHeader.height();
- bounds.left += mSelectionBoundsMarginLeft;
- bounds.right -= mSelectionBoundsMarginRight;
+ bounds.left = mBoundsWithoutHeader.left;
+ bounds.right = mBoundsWithoutHeader.right;
}
protected boolean isVisible(View view) {
@@ -712,10 +651,6 @@
}
}
- protected void setDefaultPhotoViewSize(int pixels) {
- mDefaultPhotoViewSize = pixels;
- }
-
protected int getDefaultPhotoViewSize() {
return mDefaultPhotoViewSize;
}
@@ -758,56 +693,34 @@
if (mActivatedStateSupported && isActivated()) {
mActivatedBackgroundDrawable.draw(canvas);
}
- if (mHorizontalDividerVisible) {
- mHorizontalDividerDrawable.draw(canvas);
- }
super.dispatchDraw(canvas);
}
/**
- * Sets the flag that determines whether a divider should drawn at the bottom
- * of the view.
- */
- public void setDividerVisible(boolean visible) {
- mHorizontalDividerVisible = visible;
- }
-
- /**
* Sets section header or makes it invisible if the title is null.
*/
public void setSectionHeader(String title) {
if (!TextUtils.isEmpty(title)) {
if (mHeaderTextView == null) {
mHeaderTextView = new TextView(getContext());
- mHeaderTextView.setTextColor(mHeaderTextColor);
- mHeaderTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mHeaderTextSize);
mHeaderTextView.setTextAppearance(getContext(), R.style.SectionHeaderStyle);
- mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL);
- mHeaderTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+ mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL |
+ (ViewUtil.isViewLayoutRtl(this) ? Gravity.RIGHT : Gravity.LEFT));
addView(mHeaderTextView);
}
- if (mHeaderDivider == null) {
- mHeaderDivider = new View(getContext());
- mHeaderDivider.setBackgroundColor(mHeaderUnderlineColor);
- addView(mHeaderDivider);
- }
setMarqueeText(mHeaderTextView, title);
mHeaderTextView.setVisibility(View.VISIBLE);
- mHeaderDivider.setVisibility(View.VISIBLE);
mHeaderTextView.setAllCaps(true);
- mHeaderVisible = true;
- } else {
- if (mHeaderTextView != null) {
- mHeaderTextView.setVisibility(View.GONE);
- }
- if (mHeaderDivider != null) {
- mHeaderDivider.setVisibility(View.GONE);
- }
- mHeaderVisible = false;
+ } else if (mHeaderTextView != null) {
+ mHeaderTextView.setVisibility(View.GONE);
}
}
+ public void setIsSectionHeaderEnabled(boolean isSectionHeaderEnabled) {
+ mIsSectionHeaderEnabled = isSectionHeaderEnabled;
+ }
+
/**
* Returns the quick contact badge, creating it if necessary.
*/
@@ -987,7 +900,6 @@
mLabelView.setEllipsize(getTextEllipsis());
mLabelView.setTextAppearance(getContext(), R.style.TextAppearanceSmall);
if (mPhotoPosition == PhotoPosition.LEFT) {
- //mLabelView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mCountViewTextSize);
mLabelView.setAllCaps(true);
mLabelView.setGravity(Gravity.END);
} else {
@@ -1134,39 +1046,6 @@
}
/**
- * Returns the text view for the contacts count, creating it if necessary.
- */
- public TextView getCountView() {
- if (mCountView == null) {
- mCountView = new TextView(getContext());
- mCountView.setSingleLine(true);
- mCountView.setEllipsize(getTextEllipsis());
- mCountView.setTextAppearance(getContext(), android.R.style.TextAppearance_Medium);
- mCountView.setTextColor(R.color.people_app_theme_color);
- addView(mCountView);
- }
- return mCountView;
- }
-
- /**
- * Adds or updates a text view for the contacts count.
- */
- public void setCountView(CharSequence text) {
- if (TextUtils.isEmpty(text)) {
- if (mCountView != null) {
- mCountView.setVisibility(View.GONE);
- }
- } else {
- getCountView();
- setMarqueeText(mCountView, text);
- mCountView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCountViewTextSize);
- mCountView.setGravity(Gravity.CENTER_VERTICAL);
- mCountView.setTextColor(mContactsCountTextColor);
- mCountView.setVisibility(VISIBLE);
- }
- }
-
- /**
* Adds or updates a text view for the status.
*/
public void setStatus(CharSequence text) {
@@ -1510,15 +1389,6 @@
}
/**
- * Specifies left and right margin for selection bounds. See also
- * {@link #adjustListItemSelectionBounds(Rect)}.
- */
- public void setSelectionBoundsHorizontalMargin(int left, int right) {
- mSelectionBoundsMarginLeft = left;
- mSelectionBoundsMarginRight = right;
- }
-
- /**
* Set drawable resources directly for both the background and the drawable resource
* of the photo view
*
diff --git a/src/com/android/contacts/common/list/ContactListPinnedHeaderView.java b/src/com/android/contacts/common/list/ContactListPinnedHeaderView.java
index 401b3e3..e0c3e1a 100644
--- a/src/com/android/contacts/common/list/ContactListPinnedHeaderView.java
+++ b/src/com/android/contacts/common/list/ContactListPinnedHeaderView.java
@@ -19,13 +19,11 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
-import android.view.ViewGroup;
+import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import com.android.contacts.common.R;
@@ -34,169 +32,34 @@
/**
* 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 final int mHeaderUnderlineHeight;
- private final int mHeaderUnderlineColor;
- private final int mPaddingRight;
- private final int mPaddingLeft;
- private final int mContactsCountTextColor;
- private final int mCountViewTextSize;
-
- private int mHeaderBackgroundHeight;
- private TextView mHeaderTextView;
- private TextView mCountTextView = null;
- private View mHeaderDivider;
+public class ContactListPinnedHeaderView extends TextView {
public ContactListPinnedHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
- mContext = context;
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
-
- 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);
- mHeaderUnderlineHeight = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_header_underline_height, 1);
- mHeaderUnderlineColor = a.getColor(
- R.styleable.ContactListItemView_list_item_header_underline_color, 0);
- mHeaderBackgroundHeight = a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_header_height, 30);
- mPaddingLeft = a.getDimensionPixelOffset(
- R.styleable.ContactListItemView_list_item_padding_left, 0);
- mPaddingRight = a.getDimensionPixelOffset(
- R.styleable.ContactListItemView_list_item_padding_right, 0);
- mContactsCountTextColor = a.getColor(
- R.styleable.ContactListItemView_list_item_contacts_count_text_color, Color.BLACK);
- mCountViewTextSize = (int)a.getDimensionPixelSize(
- R.styleable.ContactListItemView_list_item_contacts_count_text_size, 12);
-
+ int backgroundColor = a.getColor(
+ R.styleable.ContactListItemView_list_item_background_color, Color.WHITE);
a.recycle();
- mHeaderTextView = new TextView(mContext);
- mHeaderTextView.setTextColor(mHeaderTextColor);
- mHeaderTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mHeaderTextSize);
- mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL);
- mHeaderTextView.setTextAppearance(mContext, R.style.DirectoryHeaderStyle);
- mHeaderTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
- addView(mHeaderTextView);
- mHeaderDivider = new View(mContext);
- mHeaderDivider.setBackgroundColor(mHeaderUnderlineColor);
- addView(mHeaderDivider);
- }
-
- @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.AT_MOST),
- MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
- if (isViewMeasurable(mCountTextView)) {
- mCountTextView.measure(
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
- MeasureSpec.makeMeasureSpec(mHeaderBackgroundHeight, MeasureSpec.EXACTLY));
- }
-
- setMeasuredDimension(width, mHeaderBackgroundHeight + mHeaderUnderlineHeight);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- int width = right - left;
-
- final int leftHeaderTextView;
- final int rightHeaderTextView;
- final int topTextView = 0;
- final int bottomTextView = mHeaderBackgroundHeight;
-
- int leftCountTextView = 0;
- int rightCountTextView = 0;
-
- if (ViewUtil.isViewLayoutRtl(this)) {
- rightHeaderTextView = width - mPaddingRight - mHeaderTextIndent;
- leftHeaderTextView = rightHeaderTextView - mHeaderTextView.getMeasuredWidth();
-
- leftCountTextView = mHeaderTextIndent + mPaddingLeft;
- rightCountTextView = mCountTextView.getMeasuredWidth() + leftCountTextView;
- } else {
- leftHeaderTextView = mHeaderTextIndent + mPaddingLeft;
- rightHeaderTextView = mHeaderTextView.getMeasuredWidth() + leftHeaderTextView;
-
- // Order of statements matters
- rightCountTextView = width - mPaddingRight;
- leftCountTextView = rightCountTextView - mCountTextView.getMeasuredWidth();
- }
-
- // Take into account left and right padding when laying out the below views.
- mHeaderTextView.layout(leftHeaderTextView,
- topTextView,
- rightHeaderTextView,
- bottomTextView);
-
- if (isViewMeasurable(mCountTextView)) {
- mCountTextView.layout(leftCountTextView,
- topTextView,
- rightCountTextView,
- bottomTextView);
- }
-
- mHeaderDivider.layout(mPaddingLeft,
- mHeaderBackgroundHeight,
- width - mPaddingRight,
- mHeaderBackgroundHeight + mHeaderUnderlineHeight);
+ setBackgroundColor(backgroundColor);
+ setTextAppearance(getContext(), R.style.SectionHeaderStyle);
+ setLayoutParams(new LayoutParams(
+ getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width),
+ LayoutParams.WRAP_CONTENT));
+ setGravity(Gravity.CENTER_VERTICAL |
+ (ViewUtil.isViewLayoutRtl(this) ? Gravity.RIGHT : Gravity.LEFT));
}
/**
* Sets section header or makes it invisible if the title is null.
*/
- public void setSectionHeader(String title) {
+ public void setSectionHeaderTitle(String title) {
if (!TextUtils.isEmpty(title)) {
- mHeaderTextView.setText(title);
- mHeaderTextView.setVisibility(View.VISIBLE);
- mHeaderDivider.setVisibility(View.VISIBLE);
+ setText(title);
+ setVisibility(View.VISIBLE);
} else {
- mHeaderTextView.setVisibility(View.GONE);
- mHeaderDivider.setVisibility(View.GONE);
+ 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();
- }
-
- public void setCountView(String count) {
- if (mCountTextView == null) {
- mCountTextView = new TextView(mContext);
- mCountTextView.setTextColor(mContactsCountTextColor);
- mCountTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCountViewTextSize);
- mCountTextView.setGravity(Gravity.CENTER_VERTICAL);
- addView(mCountTextView);
- }
- mCountTextView.setText(count);
- if (count == null || count.isEmpty()) {
- mCountTextView.setVisibility(View.GONE);
- } else {
- mCountTextView.setVisibility(View.VISIBLE);
- }
- }
-
- private boolean isViewMeasurable(View view) {
- return (view != null && view.getVisibility() == View.VISIBLE);
- }
}
diff --git a/src/com/android/contacts/common/list/ContactTileAdapter.java b/src/com/android/contacts/common/list/ContactTileAdapter.java
index d9fbeac..9dab6b4 100644
--- a/src/com/android/contacts/common/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/common/list/ContactTileAdapter.java
@@ -164,6 +164,10 @@
mPhoneNumberLabelIndex = ContactTileLoaderFactory.PHONE_NUMBER_LABEL;
}
+ private static boolean cursorIsValid(Cursor cursor) {
+ return cursor != null && !cursor.isClosed();
+ }
+
/**
* Gets the number of frequents from the passed in cursor.
*
@@ -180,10 +184,11 @@
break;
case STREQUENT:
case STREQUENT_PHONE_ONLY:
- mNumFrequents = cursor.getCount() - mDividerPosition;
+ mNumFrequents = cursorIsValid(cursor) ?
+ cursor.getCount() - mDividerPosition : 0;
break;
case FREQUENT_ONLY:
- mNumFrequents = cursor.getCount();
+ mNumFrequents = cursorIsValid(cursor) ? cursor.getCount() : 0;
break;
default:
throw new IllegalArgumentException("Unrecognized DisplayType " + mDisplayType);
@@ -212,20 +217,22 @@
* Returns 0 if {@link DisplayType#FREQUENT_ONLY}
*/
protected int getDividerPosition(Cursor cursor) {
- if (cursor == null || cursor.isClosed()) {
- throw new IllegalStateException("Unable to access cursor");
- }
-
switch (mDisplayType) {
case STREQUENT:
case STREQUENT_PHONE_ONLY:
+ if (!cursorIsValid(cursor)) {
+ return 0;
+ }
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
if (cursor.getInt(mStarredIndex) == 0) {
return cursor.getPosition();
}
}
- break;
+
+ // There are not NON Starred contacts in cursor
+ // Set divider positon to end
+ return cursor.getCount();
case STARRED_ONLY:
// There is no divider
return -1;
@@ -235,16 +242,14 @@
default:
throw new IllegalStateException("Unrecognized DisplayType " + mDisplayType);
}
-
- // There are not NON Starred contacts in cursor
- // Set divider positon to end
- return cursor.getCount();
}
protected ContactEntry createContactEntryFromCursor(Cursor cursor, int position) {
// If the loader was canceled we will be given a null cursor.
// In that case, show an empty list of contacts.
- if (cursor == null || cursor.isClosed() || cursor.getCount() <= position) return null;
+ if (!cursorIsValid(cursor) || cursor.getCount() <= position) {
+ return null;
+ }
cursor.moveToPosition(position);
long id = cursor.getLong(mIdIndex);
@@ -302,7 +307,7 @@
@Override
public int getCount() {
- if (mContactCursor == null || mContactCursor.isClosed()) {
+ if (!cursorIsValid(mContactCursor)) {
return 0;
}
diff --git a/src/com/android/contacts/common/list/IndexerListAdapter.java b/src/com/android/contacts/common/list/IndexerListAdapter.java
index 14243ce..91d02f0 100644
--- a/src/com/android/contacts/common/list/IndexerListAdapter.java
+++ b/src/com/android/contacts/common/list/IndexerListAdapter.java
@@ -70,16 +70,6 @@
*/
protected abstract void setPinnedSectionTitle(View pinnedHeaderView, String title);
- /**
- * Sets the contacts count in the pinned header.
- */
- protected abstract void setPinnedHeaderContactsCount(View header);
-
- /**
- * clears the contacts count in the pinned header and makes the view invisible.
- */
- protected abstract void clearPinnedHeaderContactsCount(View header);
-
public boolean isSectionHeaderDisplayEnabled() {
return mSectionHeaderDisplayEnabled;
}
@@ -184,12 +174,13 @@
if (section == -1) {
listView.setHeaderInvisible(index, false);
} else {
- setPinnedSectionTitle(mHeader, (String)mIndexer.getSections()[section]);
- if (section == 0) {
- setPinnedHeaderContactsCount(mHeader);
- } else {
- clearPinnedHeaderContactsCount(mHeader);
+ View topChild = listView.getChildAt(listPosition);
+ if (topChild != null) {
+ // Match the pinned header's height to the height of the list item.
+ mHeader.setMinimumHeight(topChild.getMeasuredHeight());
}
+ setPinnedSectionTitle(mHeader, (String)mIndexer.getSections()[section]);
+
// Compute the item position where the current partition begins
int partitionStart = getPositionForPartition(mIndexedPartition);
if (hasHeader(mIndexedPartition)) {
diff --git a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
index a6d67ce..861f739 100644
--- a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
@@ -276,9 +276,9 @@
}
@Override
- protected View newView(Context context, int partition, Cursor cursor, int position,
- ViewGroup parent) {
- final ContactListItemView view = new ContactListItemView(context, null);
+ protected ContactListItemView newView(
+ Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
+ ContactListItemView view = super.newView(context, partition, cursor, position, parent);
view.setUnknownNameText(mUnknownNameText);
view.setQuickContactEnabled(isQuickContactEnabled());
view.setPhotoPosition(mPhotoPosition);
@@ -363,7 +363,6 @@
final DirectoryPartition directory = (DirectoryPartition) getPartition(partition);
bindPhoneNumber(view, cursor, directory.isDisplayNumber());
- view.setDividerVisible(showBottomDivider);
}
protected void bindPhoneNumber(ContactListItemView view, Cursor cursor, boolean displayNumber) {
@@ -396,10 +395,8 @@
if (isSectionHeaderDisplayEnabled()) {
Placement placement = getItemPlacementInSection(position);
view.setSectionHeader(placement.firstInSection ? placement.sectionHeader : null);
- view.setDividerVisible(!placement.lastInSection);
} else {
view.setSectionHeader(null);
- view.setDividerVisible(true);
}
}
diff --git a/src/com/android/contacts/common/list/PinnedHeaderListView.java b/src/com/android/contacts/common/list/PinnedHeaderListView.java
index 8d34981..8c05b26 100644
--- a/src/com/android/contacts/common/list/PinnedHeaderListView.java
+++ b/src/com/android/contacts/common/list/PinnedHeaderListView.java
@@ -99,7 +99,6 @@
private int mSize;
private PinnedHeader[] mHeaders;
private RectF mBounds = new RectF();
- private Rect mClipRect = new Rect();
private OnScrollListener mOnScrollListener;
private OnItemSelectedListener mOnItemSelectedListener;
private int mScrollState;
@@ -134,10 +133,6 @@
mHeaderWidth = r - l - mHeaderPaddingStart - getPaddingEnd();
}
- public void setPinnedHeaderAnimationDuration(int duration) {
- mAnimationDuration = duration;
- }
-
@Override
public void setAdapter(ListAdapter adapter) {
mAdapter = (PinnedHeaderAdapter)adapter;
@@ -362,9 +357,18 @@
private void ensurePinnedHeaderLayout(int viewIndex) {
View view = mHeaders[viewIndex].view;
if (view.isLayoutRequested()) {
- int widthSpec = View.MeasureSpec.makeMeasureSpec(mHeaderWidth, View.MeasureSpec.EXACTLY);
- int heightSpec;
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+ int widthSpec;
+ int heightSpec;
+
+ if (layoutParams != null && layoutParams.width > 0) {
+ widthSpec = View.MeasureSpec
+ .makeMeasureSpec(layoutParams.width, View.MeasureSpec.EXACTLY);
+ } else {
+ widthSpec = View.MeasureSpec
+ .makeMeasureSpec(mHeaderWidth, View.MeasureSpec.EXACTLY);
+ }
+
if (layoutParams != null && layoutParams.height > 0) {
heightSpec = View.MeasureSpec
.makeMeasureSpec(layoutParams.height, View.MeasureSpec.EXACTLY);
@@ -374,7 +378,7 @@
view.measure(widthSpec, heightSpec);
int height = view.getMeasuredHeight();
mHeaders[viewIndex].height = height;
- view.layout(0, 0, mHeaderWidth, height);
+ view.layout(0, 0, view.getMeasuredWidth(), height);
}
}
@@ -423,7 +427,7 @@
// side.
final int padding = getPaddingLeft();
if (header.visible && header.y <= y && header.y + header.height > y &&
- x >= padding && padding + mHeaderWidth >= x) {
+ x >= padding && padding + header.view.getWidth() >= x) {
mHeaderTouched = true;
if (mScrollToSectionOnHeaderTouch &&
ev.getAction() == MotionEvent.ACTION_DOWN) {
@@ -483,6 +487,7 @@
long currentTime = mAnimating ? System.currentTimeMillis() : 0;
int top = 0;
+ int right = 0;
int bottom = getBottom();
boolean hasVisibleHeaders = false;
for (int i = 0; i < mSize; i++) {
@@ -502,8 +507,6 @@
if (hasVisibleHeaders) {
canvas.save();
- mClipRect.set(0, top, getWidth(), bottom);
- canvas.clipRect(mClipRect);
}
super.dispatchDraw(canvas);
@@ -545,11 +548,12 @@
if (header.visible) {
View view = header.view;
int saveCount = canvas.save();
- canvas.translate(ViewUtil.isViewLayoutRtl(this) ?
- getWidth() - mHeaderPaddingStart - mHeaderWidth : mHeaderPaddingStart,
- header.y);
+ int translateX = ViewUtil.isViewLayoutRtl(this) ?
+ getWidth() - mHeaderPaddingStart - header.view.getWidth() :
+ mHeaderPaddingStart;
+ canvas.translate(translateX, header.y);
if (header.state == FADING) {
- mBounds.set(0, 0, mHeaderWidth, view.getHeight());
+ mBounds.set(0, 0, header.view.getWidth(), view.getHeight());
canvas.saveLayerAlpha(mBounds, header.alpha, Canvas.ALL_SAVE_FLAG);
}
view.draw(canvas);
diff --git a/src/com/android/contacts/common/util/ViewUtil.java b/src/com/android/contacts/common/util/ViewUtil.java
index fadb3de..1dfe427 100644
--- a/src/com/android/contacts/common/util/ViewUtil.java
+++ b/src/com/android/contacts/common/util/ViewUtil.java
@@ -16,9 +16,13 @@
package com.android.contacts.common.util;
+import android.content.res.Resources;
+import android.graphics.Outline;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.common.R;
+
/**
* Provides static functions to work with views
*/
@@ -49,4 +53,29 @@
public static boolean isViewLayoutRtl(View view) {
return view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
+
+ /**
+ * Configures the floating action button, clipping it to a circle and setting its translation z.
+ * @param view The float action button's view.
+ * @param res The resources file.
+ */
+ public static void setupFloatingActionButton(View view, Resources res) {
+ // Once layout is complete and the floating action button has been assigned a width and
+ // height, assign the outline.
+ view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ final Outline outline = new Outline();
+ final int minDimension = Math.min(right - left, bottom - top);
+ if (minDimension <= 0) {
+ return;
+ }
+ outline.setRoundRect(0, 0, right - left, bottom - top, minDimension / 2);
+ v.setOutline(outline);
+ }
+ });
+ view.setTranslationZ(
+ res.getDimensionPixelSize(R.dimen.floating_action_button_translation_z));
+ }
}