1d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/* 2d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Copyright (C) 2010 The Android Open Source Project 3d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 4d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * you may not use this file except in compliance with the License. 6d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * You may obtain a copy of the License at 7d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 8d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 9d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 10d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Unless required by applicable law or agreed to in writing, software 11d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * See the License for the specific language governing permissions and 14d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * limitations under the License. 15d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 16d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 17d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpackage com.android.contacts.common.list; 18d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 19d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.Context; 20d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.res.ColorStateList; 21d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.res.TypedArray; 22d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.CharArrayBuffer; 23d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.Cursor; 24d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.graphics.Canvas; 2558a793ee1253f8f46dd7f754a51f61a6bbcdce60Andrew Leeimport android.graphics.Color; 26d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.graphics.Rect; 27d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.graphics.Typeface; 28d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.graphics.drawable.Drawable; 29d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.os.Bundle; 30d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract; 31d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Contacts; 3273f41231df9868953047cbbcce529ee5687de7f2Walter Jangimport android.provider.ContactsContract.SearchSnippets; 333181b8ffaa6af370268acee97903e98a6b94138fWenyi Wangimport android.support.v4.content.ContextCompat; 34e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wangimport android.support.v4.graphics.drawable.DrawableCompat; 35d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.Spannable; 36d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.SpannableString; 37d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils; 38d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils.TruncateAt; 39d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.util.AttributeSet; 403bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapatiimport android.util.TypedValue; 41d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.Gravity; 4210349f190691f802b8935175dbf38bff74a8a703Yorke Leeimport android.view.MotionEvent; 43d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.View; 44d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.ViewGroup; 45d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.AbsListView.SelectionBoundsAdjuster; 464ad6cc6d88af85a069a948a27b344465619b5ad8Wenyi Wangimport android.widget.CheckBox; 47d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ImageView; 48d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ImageView.ScaleType; 49d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.QuickContactBadge; 50d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.TextView; 51d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 52d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.ContactPresenceIconUtil; 53d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.ContactStatusUtil; 54d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.R; 55e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wangimport com.android.contacts.common.compat.CompatUtils; 563abf10065b24373b3d6e46ed3c7f34af2b4639fbWenyi Wangimport com.android.contacts.common.compat.PhoneNumberUtilsCompat; 57a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport com.android.contacts.common.format.TextHighlighter; 58d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jangimport com.android.contacts.common.util.ContactDisplayUtils; 59cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Chengimport com.android.contacts.common.util.SearchUtil; 60864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Leeimport com.android.contacts.common.util.ViewUtil; 61864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Lee 6205897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport com.google.common.collect.Lists; 6305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 6405897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.ArrayList; 6505897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.List; 669f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglioimport java.util.Locale; 6705897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.regex.Matcher; 6805897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.regex.Pattern; 69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/** 71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * A custom view for an item in the contact list. 72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The view contains the contact's photo, a set of text views (for name, status, etc...) and 73d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * icons for presence and call. 74d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The view uses no XML file for layout and all the measurements and layouts are done 75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * in the onMeasure and onLayout methods. 76d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 77d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The layout puts the contact's photo on the right side of the view, the call icon (if present) 78d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * to the left of the photo, the text lines are aligned to the left and the presence icon (if 79d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * present) is set to the left of the status line. 80d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 81d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The layout also supports a header (used as a header of a group of contacts) that is above the 82d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * contact's data and a divider between contact view. 83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 84d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 85d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic class ContactListItemView extends ViewGroup 86d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng implements SelectionBoundsAdjuster { 87d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 88e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private static final String TAG = "ContactListItemView"; 89e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Style values for layout and appearance 91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // The initialized values are defaults if none is provided through xml. 92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPreferredHeight = 0; 93d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mGapBetweenImageAndText = 0; 94d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mGapBetweenLabelAndData = 0; 95d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPresenceIconMargin = 4; 96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPresenceIconSize = 16; 97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mTextIndent = 0; 987961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee private int mTextOffsetTop; 993bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati private int mNameTextViewTextSize; 1001f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee private int mHeaderWidth; 101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private Drawable mActivatedBackgroundDrawable; 102e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private int mVideoCallIconSize = 32; 103e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private int mVideoCallIconMargin = 16; 104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 105f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati // Set in onLayout. Represent left and right position of the View on the screen. 106f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati private int mLeftOffset; 107f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati private int mRightOffset; 108f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati 109d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 110d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Used with {@link #mLabelView}, specifying the width ratio between label and data. 111d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 112d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelViewWidthWeight = 3; 113d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 114d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Used with {@link #mDataView}, specifying the width ratio between label and data. 115d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 116d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDataViewWidthWeight = 5; 117d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 118f99a990be713ed35afe64ba8133c5428816390c6Christine Chen protected static class HighlightSequence { 119f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private final int start; 120f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private final int end; 121f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 122f99a990be713ed35afe64ba8133c5428816390c6Christine Chen HighlightSequence(int start, int end) { 123f99a990be713ed35afe64ba8133c5428816390c6Christine Chen this.start = start; 124f99a990be713ed35afe64ba8133c5428816390c6Christine Chen this.end = end; 125f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 126f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 127f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 128f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private ArrayList<HighlightSequence> mNameHighlightSequence; 129f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private ArrayList<HighlightSequence> mNumberHighlightSequence; 130a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 131a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Highlighting prefix for names. 132a81953a2b1818066ef5e44817f374ac288bab343Christine Chen private String mHighlightedPrefix; 133a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 135e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * Used to notify listeners when a video call icon is clicked. 136e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn */ 137e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private PhoneNumberListAdapter.Listener mPhoneNumberListAdapterListener; 138e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 139e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn /** 140e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * Indicates whether to show the "video call" icon, used to initiate a video call. 141e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn */ 142e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private boolean mShowVideoCallIcon = false; 143e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 144e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn /** 145e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * Indicates whether the view should leave room for the "video call" icon. 146e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn */ 147e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private boolean mSupportVideoCallIcon = false; 148e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 149e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn /** 150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Where to put contact photo. This affects the other Views' layout or look-and-feel. 1519f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio * 1529f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio * TODO: replace enum with int constants 153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public enum PhotoPosition { 155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng LEFT, 156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng RIGHT 157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1589f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 1599f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio static public final PhotoPosition getDefaultPhotoPosition(boolean opposite) { 1609f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio final Locale locale = Locale.getDefault(); 1619f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale); 1629f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio switch (layoutDirection) { 1639f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio case View.LAYOUT_DIRECTION_RTL: 164a9950433dc469d24b314204075a6250d2410e01bAndrew Lee return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT); 1659f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio case View.LAYOUT_DIRECTION_LTR: 1669f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio default: 167a9950433dc469d24b314204075a6250d2410e01bAndrew Lee return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT); 1689f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1699f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1709f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 1719f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio private PhotoPosition mPhotoPosition = getDefaultPhotoPosition(false /* normal/non opposite */); 172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Header layout data 174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mHeaderTextView; 1751f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee private boolean mIsSectionHeaderEnabled; 176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // The views inside the contact view 178d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mQuickContactEnabled = true; 179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private QuickContactBadge mQuickContact; 180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ImageView mPhotoView; 181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mNameTextView; 182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mPhoneticNameTextView; 183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mLabelView; 184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mDataView; 185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mSnippetView; 186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mStatusView; 187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ImageView mPresenceIcon; 1884ad6cc6d88af85a069a948a27b344465619b5ad8Wenyi Wang private CheckBox mCheckBox; 189e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private ImageView mVideoCallIcon; 190d19d35ef8347038f5296ed7020cab79396874937Victor Chang private ImageView mWorkProfileIcon; 191d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 192d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ColorStateList mSecondaryTextColor; 193d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 194d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDefaultPhotoViewSize = 0; 195d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 196d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Can be effective even when {@link #mPhotoView} is null, as we want to have horizontal padding 197d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * to align other data in this View. 198d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 199d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhotoViewWidth; 200d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 201d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Can be effective even when {@link #mPhotoView} is null, as we want to have vertical padding. 202d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 203d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhotoViewHeight; 204d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 205d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 206d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Only effective when {@link #mPhotoView} is null. 207d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * When true all the Views on the right side of the photo should have horizontal padding on 208d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * those left assuming there is a photo. 209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mKeepHorizontalPaddingForPhotoView; 211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 212d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Only effective when {@link #mPhotoView} is null. 213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mKeepVerticalPaddingForPhotoView; 215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * True when {@link #mPhotoViewWidth} and {@link #mPhotoViewHeight} are ready for being used. 218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * False indicates those values should be updated before being used in position calculation. 219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mPhotoViewWidthAndHeightAreReady = false; 221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mNameTextViewHeight; 22358a793ee1253f8f46dd7f754a51f61a6bbcdce60Andrew Lee private int mNameTextViewTextColor = Color.BLACK; 224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhoneticNameTextViewHeight; 225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelViewHeight; 226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDataViewHeight; 227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mSnippetTextViewHeight; 228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mStatusTextViewHeight; 22908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell private int mCheckBoxHeight; 23008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell private int mCheckBoxWidth; 231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 232d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Holds Math.max(mLabelTextViewHeight, mDataViewHeight), assuming Label and Data share the 233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // same row. 234d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelAndDataViewMaxHeight; 235d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 236d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO: some TextView fields are using CharArrayBuffer while some are not. Determine which is 237d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // more efficient for each case or in general, and simplify the whole implementation. 238d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Note: if we're sure MARQUEE will be used every time, there's no reason to use 239d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // CharArrayBuffer, since MARQUEE requires Span and thus we need to copy characters inside the 240d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // buffer to Spannable once, while CharArrayBuffer is for directly applying char array to 241d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TextView without any modification. 242d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private final CharArrayBuffer mDataBuffer = new CharArrayBuffer(128); 243d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private final CharArrayBuffer mPhoneticNameBuffer = new CharArrayBuffer(128); 244d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 245d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mActivatedStateSupported; 246fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee private boolean mAdjustSelectionBoundsEnabled = true; 247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private Rect mBoundsWithoutHeader = new Rect(); 249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 250d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** A helper used to highlight a prefix in a text field. */ 251a81953a2b1818066ef5e44817f374ac288bab343Christine Chen private final TextHighlighter mTextHighlighter; 252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private CharSequence mUnknownNameText; 253e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private int mPosition; 254d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 255d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactListItemView(Context context) { 256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super(context); 257d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 25842210256d3d584783ac2fb2742088ce57d9da766Yorke Lee mTextHighlighter = new TextHighlighter(Typeface.BOLD); 259bb67024ef64a7853f5ec320652d80f0cdf7b660fYorke Lee mNameHighlightSequence = new ArrayList<HighlightSequence>(); 260bb67024ef64a7853f5ec320652d80f0cdf7b660fYorke Lee mNumberHighlightSequence = new ArrayList<HighlightSequence>(); 261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 263e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public ContactListItemView(Context context, AttributeSet attrs, boolean supportVideoCallIcon) { 264e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn this(context, attrs); 265e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 266e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mSupportVideoCallIcon = supportVideoCallIcon; 267e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 268e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactListItemView(Context context, AttributeSet attrs) { 270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super(context, attrs); 271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 27225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee TypedArray a; 27325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 27425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee if (R.styleable.ContactListItemView != null) { 27525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee // Read all style values 27625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView); 27725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPreferredHeight = a.getDimensionPixelSize( 27825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_height, mPreferredHeight); 27925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mActivatedBackgroundDrawable = a.getDrawable( 28025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_activated_background); 28125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 28225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenImageAndText = a.getDimensionPixelOffset( 28325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_gap_between_image_and_text, 28425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenImageAndText); 28525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenLabelAndData = a.getDimensionPixelOffset( 28625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_gap_between_label_and_data, 28725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenLabelAndData); 28825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconMargin = a.getDimensionPixelOffset( 28925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_presence_icon_margin, 29025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconMargin); 29125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconSize = a.getDimensionPixelOffset( 29225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_presence_icon_size, 29325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconSize); 29425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDefaultPhotoViewSize = a.getDimensionPixelOffset( 29525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize); 29625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mTextIndent = a.getDimensionPixelOffset( 29725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_text_indent, mTextIndent); 29825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mTextOffsetTop = a.getDimensionPixelOffset( 29925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_text_offset_top, mTextOffsetTop); 30025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDataViewWidthWeight = a.getInteger( 30125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_data_width_weight, 30225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDataViewWidthWeight); 30325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mLabelViewWidthWeight = a.getInteger( 30425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_label_width_weight, 30525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mLabelViewWidthWeight); 30625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextColor = a.getColor( 30725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_name_text_color, 30825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextColor); 30925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextSize = (int) a.getDimension( 31025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_name_text_size, 31125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee (int) getResources().getDimension(R.dimen.contact_browser_list_item_text_size)); 312e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIconSize = a.getDimensionPixelOffset( 313e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn R.styleable.ContactListItemView_list_item_video_call_icon_size, 314e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIconSize); 315e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIconMargin = a.getDimensionPixelOffset( 316e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn R.styleable.ContactListItemView_list_item_video_call_icon_margin, 317e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIconMargin); 318e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 31925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 32025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee setPaddingRelative( 32125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 32225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_left, 0), 32325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 32425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_top, 0), 32525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 32625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_right, 0), 32725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 32825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_bottom, 0)); 32925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 33025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.recycle(); 33125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee } 332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 33342210256d3d584783ac2fb2742088ce57d9da766Yorke Lee mTextHighlighter = new TextHighlighter(Typeface.BOLD); 33442210256d3d584783ac2fb2742088ce57d9da766Yorke Lee 33525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee if (R.styleable.Theme != null) { 33625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a = getContext().obtainStyledAttributes(R.styleable.Theme); 33725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mSecondaryTextColor = a.getColorStateList(R.styleable.Theme_android_textColorSecondary); 33825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.recycle(); 33925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee } 340d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 3411f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderWidth = 3421f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width); 3431f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee 344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedBackgroundDrawable != null) { 345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setCallback(this); 346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 347f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 348f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence = new ArrayList<HighlightSequence>(); 349f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence = new ArrayList<HighlightSequence>(); 35053c7dc1e9691b5b427395642a4274d37a1a15bb4Yorke Lee 35153c7dc1e9691b5b427395642a4274d37a1a15bb4Yorke Lee setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE); 352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 353d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 354d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setUnknownNameText(CharSequence unknownNameText) { 355d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mUnknownNameText = unknownNameText; 356d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 357d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 358d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setQuickContactEnabled(boolean flag) { 359d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContactEnabled = flag; 360d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 361d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 362e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn /** 363e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * Sets whether the video calling icon is shown. For the video calling icon to be shown, 364e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * {@link #mSupportVideoCallIcon} must be {@code true}. 365e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * 366e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * @param showVideoCallIcon {@code true} if the video calling icon is shown, {@code false} 367e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * otherwise. 368e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * @param listener Listener to notify when the video calling icon is clicked. 369e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * @param position The position in the adapater of the video calling icon. 370e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn */ 371e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public void setShowVideoCallIcon(boolean showVideoCallIcon, 372e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn PhoneNumberListAdapter.Listener listener, int position) { 373e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mShowVideoCallIcon = showVideoCallIcon; 374e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mPhoneNumberListAdapterListener = listener; 375e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mPosition = position; 376e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 377e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mShowVideoCallIcon) { 378e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mVideoCallIcon == null) { 379e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon = new ImageView(getContext()); 380e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn addView(mVideoCallIcon); 381e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 382e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setContentDescription(getContext().getString( 383e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn R.string.description_search_video_call)); 384e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setImageResource(R.drawable.ic_search_video_call); 385e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setScaleType(ScaleType.CENTER); 386e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setVisibility(View.VISIBLE); 387e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setOnClickListener(new OnClickListener() { 388e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn @Override 389e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public void onClick(View v) { 390e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn // Inform the adapter that the video calling icon was clicked. 391e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mPhoneNumberListAdapterListener != null) { 392e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mPhoneNumberListAdapterListener.onVideoCallIconClicked(mPosition); 393e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 394e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 395e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn }); 396e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } else { 397e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mVideoCallIcon != null) { 398e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.setVisibility(View.GONE); 399e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 400e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 401e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 402e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 403e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn /** 404e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * Sets whether the view supports a video calling icon. This is independent of whether the view 405e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * is actually showing an icon. Support for the video calling icon ensures that the layout 406e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * leaves space for the video icon, should it be shown. 407e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * 408e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * @param supportVideoCallIcon {@code true} if the video call icon is supported, {@code false} 409e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn * otherwise. 410e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn */ 411e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public void setSupportVideoCallIcon(boolean supportVideoCallIcon) { 412e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mSupportVideoCallIcon = supportVideoCallIcon; 413e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 414e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 415d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 416d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 417d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // We will match parent's width and wrap content vertically, but make sure 418d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // height is no less than listPreferredItemHeight. 419d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int specWidth = resolveSize(0, widthMeasureSpec); 420f4fcd3def28e5b1168f5160e476c05ad69339adcAndrew Lee final int preferredHeight = mPreferredHeight; 421d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 422d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextViewHeight = 0; 423d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextViewHeight = 0; 424d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelViewHeight = 0; 425d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataViewHeight = 0; 426d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight = 0; 427d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight = 0; 428d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = 0; 42908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxWidth = 0; 43008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxHeight = 0; 431d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 432d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ensurePhotoViewSize(); 433d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 434d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Width each TextView is able to use. 435ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee int effectiveWidth; 436d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // All the other Views will honor the photo, so available width for them may be shrunk. 437d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) { 438d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight() 439d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng - (mPhotoViewWidth + mGapBetweenImageAndText); 440d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 441d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight(); 442d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 443d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 444ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (mIsSectionHeaderEnabled) { 445ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee effectiveWidth -= mHeaderWidth + mGapBetweenImageAndText; 446ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 447ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee 448e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mSupportVideoCallIcon) { 449e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn effectiveWidth -= (mVideoCallIconSize + mVideoCallIconMargin); 450e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 451e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 452d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Go over all visible text views and measure actual width of each of them. 453d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Also calculate their heights to get the total height for this entire view. 454d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 45508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (isVisible(mCheckBox)) { 45608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.measure( 45708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 45808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 45908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxWidth = mCheckBox.getMeasuredWidth(); 46008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxHeight = mCheckBox.getMeasuredHeight(); 46108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell effectiveWidth -= mCheckBoxWidth + mGapBetweenImageAndText; 46208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 46308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 464d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mNameTextView)) { 46590fbbae42d4628b18e78434e7de13254099b229ePaul Soulos // Calculate width for name text - this parallels similar measurement in onLayout. 466d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int nameTextWidth = effectiveWidth; 467d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition != PhotoPosition.LEFT) { 468d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng nameTextWidth -= mTextIndent; 469d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 470d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.measure( 471d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(nameTextWidth, MeasureSpec.EXACTLY), 472d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 473d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextViewHeight = mNameTextView.getMeasuredHeight(); 474d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 475d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 476d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPhoneticNameTextView)) { 477d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.measure( 478d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY), 479d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 480d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextViewHeight = mPhoneticNameTextView.getMeasuredHeight(); 481d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 482d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 483d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // If both data (phone number/email address) and label (type like "MOBILE") are quite long, 484d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // we should ellipsize both using appropriate ratio. 485d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int dataWidth; 486d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int labelWidth; 487d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 488d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 489d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int totalWidth = effectiveWidth - mGapBetweenLabelAndData; 490d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = ((totalWidth * mDataViewWidthWeight) 491d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng / (mDataViewWidthWeight + mLabelViewWidthWeight)); 492d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = ((totalWidth * mLabelViewWidthWeight) / 493d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng (mDataViewWidthWeight + mLabelViewWidthWeight)); 494d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 495d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = effectiveWidth; 496d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = 0; 497d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 498d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 499d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = 0; 500d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 501d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = effectiveWidth; 502d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 503d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = 0; 504d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 505d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 506d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 507d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 508d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.measure(MeasureSpec.makeMeasureSpec(dataWidth, MeasureSpec.EXACTLY), 509d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 510d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataViewHeight = mDataView.getMeasuredHeight(); 511d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 512d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 513d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 514e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mLabelView.measure(MeasureSpec.makeMeasureSpec(labelWidth, MeasureSpec.AT_MOST), 515d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 516d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelViewHeight = mLabelView.getMeasuredHeight(); 517d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 518d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight = Math.max(mLabelViewHeight, mDataViewHeight); 519d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 520d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mSnippetView)) { 521d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.measure( 522d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY), 523d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 524d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight = mSnippetView.getMeasuredHeight(); 525d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 526d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 527d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Status view height is the biggest of the text view and the presence icon 528d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPresenceIcon)) { 529d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.measure( 530d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY), 531d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY)); 532d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight(); 533d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 534d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 535e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mSupportVideoCallIcon && isVisible(mVideoCallIcon)) { 536e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.measure( 537e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn MeasureSpec.makeMeasureSpec(mVideoCallIconSize, MeasureSpec.EXACTLY), 538e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn MeasureSpec.makeMeasureSpec(mVideoCallIconSize, MeasureSpec.EXACTLY)); 539e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 540e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 541d19d35ef8347038f5296ed7020cab79396874937Victor Chang if (isVisible(mWorkProfileIcon)) { 542d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.measure( 543d19d35ef8347038f5296ed7020cab79396874937Victor Chang MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 544d19d35ef8347038f5296ed7020cab79396874937Victor Chang MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 545d19d35ef8347038f5296ed7020cab79396874937Victor Chang mNameTextViewHeight = 546d19d35ef8347038f5296ed7020cab79396874937Victor Chang Math.max(mNameTextViewHeight, mWorkProfileIcon.getMeasuredHeight()); 547d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 548d19d35ef8347038f5296ed7020cab79396874937Victor Chang 549d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mStatusView)) { 550d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Presence and status are in a same row, so status will be affected by icon size. 551d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int statusWidth; 552d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPresenceIcon)) { 553d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusWidth = (effectiveWidth - mPresenceIcon.getMeasuredWidth() 554d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng - mPresenceIconMargin); 555d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 556d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusWidth = effectiveWidth; 557d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 558d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.measure(MeasureSpec.makeMeasureSpec(statusWidth, MeasureSpec.EXACTLY), 559d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 560d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = 561d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Math.max(mStatusTextViewHeight, mStatusView.getMeasuredHeight()); 562d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 563d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 564d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Calculate height including padding. 565d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int height = (mNameTextViewHeight + mPhoneticNameTextViewHeight + 566d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight + 567d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight + mStatusTextViewHeight); 568d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 569d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Make sure the height is at least as high as the photo 570d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop()); 571d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 572d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Make sure height is at least the preferred height 573d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng height = Math.max(height, preferredHeight); 574d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 5751f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee // Measure the header if it is visible. 5761f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mHeaderTextView != null && mHeaderTextView.getVisibility() == VISIBLE) { 577d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.measure( 5781f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY), 5796fdf16941587a222f554482fb72531783a924b6eAndrew Lee MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 580d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 581d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 582d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMeasuredDimension(specWidth, height); 583d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 584d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 585d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 586d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 587d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int height = bottom - top; 588d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int width = right - left; 589d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 590d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Determine the vertical bounds by laying out the header first. 591d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int topBound = 0; 592d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int bottomBound = height; 593d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int leftBound = getPaddingLeft(); 594d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int rightBound = width - getPaddingRight(); 595d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 596864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Lee final boolean isLayoutRtl = ViewUtil.isViewLayoutRtl(this); 59709f15e70e86d92ae0f4c15a726b777f170845a3cYorke Lee 5981f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee // Put the section header on the left side of the contact view. 5991f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mIsSectionHeaderEnabled) { 6001f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mHeaderTextView != null) { 6016fdf16941587a222f554482fb72531783a924b6eAndrew Lee int headerHeight = mHeaderTextView.getMeasuredHeight(); 6026fdf16941587a222f554482fb72531783a924b6eAndrew Lee int headerTopBound = (bottomBound + topBound - headerHeight) / 2 + mTextOffsetTop; 6036fdf16941587a222f554482fb72531783a924b6eAndrew Lee 6041f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderTextView.layout( 6051f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee isLayoutRtl ? rightBound - mHeaderWidth : leftBound, 6066fdf16941587a222f554482fb72531783a924b6eAndrew Lee headerTopBound, 6071f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee isLayoutRtl ? rightBound : leftBound + mHeaderWidth, 6086fdf16941587a222f554482fb72531783a924b6eAndrew Lee headerTopBound + headerHeight); 6091f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 6101f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (isLayoutRtl) { 6111f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee rightBound -= mHeaderWidth; 6121f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } else { 6131f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee leftBound += mHeaderWidth; 6141f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 615d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 616d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 617f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mBoundsWithoutHeader.set(left + leftBound, topBound, left + rightBound, bottomBound); 618f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mLeftOffset = left + leftBound; 619f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mRightOffset = left + rightBound; 620ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (mIsSectionHeaderEnabled) { 621ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (isLayoutRtl) { 622ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee rightBound -= mGapBetweenImageAndText; 623ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } else { 624ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee leftBound += mGapBetweenImageAndText; 625ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 626ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 627d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 628d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported && isActivated()) { 629d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setBounds(mBoundsWithoutHeader); 630d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 631d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 63208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (isVisible(mCheckBox)) { 63308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell final int photoTop = topBound + (bottomBound - topBound - mCheckBoxHeight) / 2; 63408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mPhotoPosition == PhotoPosition.LEFT) { 63508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.layout(rightBound - mCheckBoxWidth, 63608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop, 63708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound, 63808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop + mCheckBoxHeight); 63908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } else { 64008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.layout(leftBound, 64108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop, 64208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell leftBound + mCheckBoxWidth, 64308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop + mCheckBoxHeight); 64408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 64508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 64608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 647d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final View photoView = mQuickContact != null ? mQuickContact : mPhotoView; 648d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition == PhotoPosition.LEFT) { 649d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Photo is the left most view. All the other Views should on the right of the photo. 650d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (photoView != null) { 651d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Center the photo vertically 652d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2; 653d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoView.layout( 654d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound, 655d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop, 656d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound + mPhotoViewWidth, 657d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop + mPhotoViewHeight); 658d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mPhotoViewWidth + mGapBetweenImageAndText; 659d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else if (mKeepHorizontalPaddingForPhotoView) { 660d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Draw nothing but keep the padding. 661d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mPhotoViewWidth + mGapBetweenImageAndText; 662d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 663d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 664d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Photo is the right most view. Right bound should be adjusted that way. 665d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (photoView != null) { 666d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Center the photo vertically 667d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2; 668d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoView.layout( 669d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound - mPhotoViewWidth, 670d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop, 671d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 672d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop + mPhotoViewHeight); 673d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText); 6749f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } else if (mKeepHorizontalPaddingForPhotoView) { 6759f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio // Draw nothing but keep the padding. 6769f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText); 677d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 678d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 679d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Add indent between left-most padding and texts. 680d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mTextIndent; 681d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 682d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 683e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mSupportVideoCallIcon) { 684e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn // Place the video call button at the end of the list (e.g. take into account RTL mode). 685e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (isVisible(mVideoCallIcon)) { 686e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn // Center the video icon vertically 687e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn final int videoIconTop = topBound + 688e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn (bottomBound - topBound - mVideoCallIconSize) / 2; 689e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 690e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (!isLayoutRtl) { 691e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn // When photo is on left, video icon is placed on the right edge. 692e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.layout(rightBound - mVideoCallIconSize, 693e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn videoIconTop, 694e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound, 695e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn videoIconTop + mVideoCallIconSize); 696e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } else { 697e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn // When photo is on right, video icon is placed on the left edge. 698e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mVideoCallIcon.layout(leftBound, 699e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn videoIconTop, 700e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn leftBound + mVideoCallIconSize, 701e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn videoIconTop + mVideoCallIconSize); 702e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 703e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 704e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 705e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (mPhotoPosition == PhotoPosition.LEFT) { 706e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound -= (mVideoCallIconSize + mVideoCallIconMargin); 707e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } else { 708e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn leftBound += mVideoCallIconSize + mVideoCallIconMargin; 709e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 710e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 711e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 712e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 7137961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee // Center text vertically, then apply the top offset. 714d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int totalTextHeight = mNameTextViewHeight + mPhoneticNameTextViewHeight + 715d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight; 7167961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee int textTopBound = (bottomBound + topBound - totalTextHeight) / 2 + mTextOffsetTop; 717d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 718d19d35ef8347038f5296ed7020cab79396874937Victor Chang // Work Profile icon align top 719d19d35ef8347038f5296ed7020cab79396874937Victor Chang int workProfileIconWidth = 0; 720d19d35ef8347038f5296ed7020cab79396874937Victor Chang if (isVisible(mWorkProfileIcon)) { 721d19d35ef8347038f5296ed7020cab79396874937Victor Chang workProfileIconWidth = mWorkProfileIcon.getMeasuredWidth(); 722d19d35ef8347038f5296ed7020cab79396874937Victor Chang final int distanceFromEnd = mCheckBoxWidth > 0 723d19d35ef8347038f5296ed7020cab79396874937Victor Chang ? mCheckBoxWidth + mGapBetweenImageAndText : 0; 724d19d35ef8347038f5296ed7020cab79396874937Victor Chang if (mPhotoPosition == PhotoPosition.LEFT) { 725d19d35ef8347038f5296ed7020cab79396874937Victor Chang // When photo is on left, label is placed on the right edge of the list item. 726d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.layout(rightBound - workProfileIconWidth - distanceFromEnd, 727d19d35ef8347038f5296ed7020cab79396874937Victor Chang textTopBound, 728d19d35ef8347038f5296ed7020cab79396874937Victor Chang rightBound - distanceFromEnd, 729d19d35ef8347038f5296ed7020cab79396874937Victor Chang textTopBound + mNameTextViewHeight); 730d19d35ef8347038f5296ed7020cab79396874937Victor Chang } else { 731d19d35ef8347038f5296ed7020cab79396874937Victor Chang // When photo is on right, label is placed on the left of data view. 732d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.layout(leftBound + distanceFromEnd, 733d19d35ef8347038f5296ed7020cab79396874937Victor Chang textTopBound, 734d19d35ef8347038f5296ed7020cab79396874937Victor Chang leftBound + workProfileIconWidth + distanceFromEnd, 735d19d35ef8347038f5296ed7020cab79396874937Victor Chang textTopBound + mNameTextViewHeight); 736d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 737d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 738d19d35ef8347038f5296ed7020cab79396874937Victor Chang 739d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Layout all text view and presence icon 740d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Put name TextView first 741d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mNameTextView)) { 742d19d35ef8347038f5296ed7020cab79396874937Victor Chang final int distanceFromEnd = workProfileIconWidth 743d19d35ef8347038f5296ed7020cab79396874937Victor Chang + (mCheckBoxWidth > 0 ? mCheckBoxWidth + mGapBetweenImageAndText : 0); 74408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mPhotoPosition == PhotoPosition.LEFT) { 74508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mNameTextView.layout(leftBound, 74608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound, 74708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound - distanceFromEnd, 74808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound + mNameTextViewHeight); 74908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } else { 75008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mNameTextView.layout(leftBound + distanceFromEnd, 75108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound, 75208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound, 75308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound + mNameTextViewHeight); 75408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 755d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 756d19d35ef8347038f5296ed7020cab79396874937Victor Chang 757d19d35ef8347038f5296ed7020cab79396874937Victor Chang if (isVisible(mNameTextView) || isVisible(mWorkProfileIcon)) { 758d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mNameTextViewHeight; 759d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 760d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 761d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Presence and status 7629f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isLayoutRtl) { 7639f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int statusRightBound = rightBound; 7649f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mPresenceIcon)) { 7659f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int iconWidth = mPresenceIcon.getMeasuredWidth(); 7669f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPresenceIcon.layout( 7679f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound - iconWidth, 7689f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 7699f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound, 7709f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 7719f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusRightBound -= (iconWidth + mPresenceIconMargin); 7729f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 773d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 7749f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mStatusView)) { 7759f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.layout(leftBound, 7769f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 7779f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusRightBound, 7789f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 7799f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 7809f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } else { 7819f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int statusLeftBound = leftBound; 7829f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mPresenceIcon)) { 7839f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int iconWidth = mPresenceIcon.getMeasuredWidth(); 7849f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPresenceIcon.layout( 7859f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio leftBound, 7869f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 7879f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio leftBound + iconWidth, 7889f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 7899f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusLeftBound += (iconWidth + mPresenceIconMargin); 7909f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 7919f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 7929f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mStatusView)) { 7939f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.layout(statusLeftBound, 7949f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 7959f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound, 7969f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 7979f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 798d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 799d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 800d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mStatusView) || isVisible(mPresenceIcon)) { 801d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mStatusTextViewHeight; 802d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 803d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 804d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Rest of text views 805d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int dataLeftBound = leftBound; 806d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPhoneticNameTextView)) { 807d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.layout(leftBound, 808d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound, 809d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 810d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mPhoneticNameTextViewHeight); 811d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mPhoneticNameTextViewHeight; 812d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 813d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 814d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Label and Data align bottom. 815d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 816e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (!isLayoutRtl) { 817e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mLabelView.layout(dataLeftBound, 818d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight, 819d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 820d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight); 821e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn dataLeftBound += mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData; 822d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 823d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataLeftBound = leftBound + mLabelView.getMeasuredWidth(); 824e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mLabelView.layout(rightBound - mLabelView.getMeasuredWidth(), 825d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight, 826e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound, 827d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight); 828e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound -= (mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData); 829d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 830d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 831d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 832d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 833e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn if (!isLayoutRtl) { 834e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mDataView.layout(dataLeftBound, 835e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight, 836e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound, 837e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn textTopBound + mLabelAndDataViewMaxHeight); 838e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } else { 839e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mDataView.layout(rightBound - mDataView.getMeasuredWidth(), 840e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight, 841e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn rightBound, 842e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn textTopBound + mLabelAndDataViewMaxHeight); 843e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 844d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 845d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView) || isVisible(mDataView)) { 846d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mLabelAndDataViewMaxHeight; 847d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 848d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 849d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mSnippetView)) { 850d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.layout(leftBound, 851d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound, 852d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 853d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mSnippetTextViewHeight); 854d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 855d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 856d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 857d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 858d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void adjustListItemSelectionBounds(Rect bounds) { 859fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee if (mAdjustSelectionBoundsEnabled) { 860fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.top += mBoundsWithoutHeader.top; 861fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.bottom = bounds.top + mBoundsWithoutHeader.height(); 862fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.left = mBoundsWithoutHeader.left; 863fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.right = mBoundsWithoutHeader.right; 864fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 865d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 866d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 867d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected boolean isVisible(View view) { 868d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return view != null && view.getVisibility() == View.VISIBLE; 869d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 870d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 871d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 872d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Extracts width and height from the style 873d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 874d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void ensurePhotoViewSize() { 875d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mPhotoViewWidthAndHeightAreReady) { 876d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize(); 877d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mQuickContactEnabled && mPhotoView == null) { 878d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mKeepHorizontalPaddingForPhotoView) { 879d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidth = 0; 880d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 881d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mKeepVerticalPaddingForPhotoView) { 882d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewHeight = 0; 883d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 884d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 885d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 886d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = true; 887d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 888d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 889d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 890d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected int getDefaultPhotoViewSize() { 891d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDefaultPhotoViewSize; 892d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 893d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 894d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 895d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Gets a LayoutParam that corresponds to the default photo size. 896d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 897d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @return A new LayoutParam. 898d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 899d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private LayoutParams getDefaultPhotoLayoutParams() { 900d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng LayoutParams params = generateDefaultLayoutParams(); 901d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng params.width = getDefaultPhotoViewSize(); 902d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng params.height = params.width; 903d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return params; 904d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 905d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 906d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 907d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void drawableStateChanged() { 908d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.drawableStateChanged(); 909d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported) { 910d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setState(getDrawableState()); 911d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 912d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 913d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 914d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 915d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected boolean verifyDrawable(Drawable who) { 916d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return who == mActivatedBackgroundDrawable || super.verifyDrawable(who); 917d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 918d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 919d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 920d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void jumpDrawablesToCurrentState() { 921d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.jumpDrawablesToCurrentState(); 922d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported) { 923d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.jumpToCurrentState(); 924d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 925d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 926d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 927d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 928d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void dispatchDraw(Canvas canvas) { 929d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported && isActivated()) { 930d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.draw(canvas); 931d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 932d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 933d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.dispatchDraw(canvas); 934d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 935d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 936d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 937d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets section header or makes it invisible if the title is null. 938d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 939d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSectionHeader(String title) { 940d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!TextUtils.isEmpty(title)) { 941d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mHeaderTextView == null) { 942e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mHeaderTextView = new TextView(getContext()); 943e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mHeaderTextView.setTextAppearance(getContext(), R.style.SectionHeaderStyle); 9446fdf16941587a222f554482fb72531783a924b6eAndrew Lee mHeaderTextView.setGravity( 9456fdf16941587a222f554482fb72531783a924b6eAndrew Lee ViewUtil.isViewLayoutRtl(this) ? Gravity.RIGHT : Gravity.LEFT); 946d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mHeaderTextView); 947d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 948d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mHeaderTextView, title); 949d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.setVisibility(View.VISIBLE); 950d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.setAllCaps(true); 9511f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } else if (mHeaderTextView != null) { 9521f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderTextView.setVisibility(View.GONE); 953d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 954d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 955d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 9561f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee public void setIsSectionHeaderEnabled(boolean isSectionHeaderEnabled) { 9571f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mIsSectionHeaderEnabled = isSectionHeaderEnabled; 9581f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 9591f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee 960d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 961d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the quick contact badge, creating it if necessary. 962d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 963d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public QuickContactBadge getQuickContact() { 964d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mQuickContactEnabled) { 965d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng throw new IllegalStateException("QuickContact is disabled for this view"); 966d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 967d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mQuickContact == null) { 968e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact = new QuickContactBadge(getContext()); 969e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 970e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang mQuickContact.setOverlay(null); 971e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 972d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams()); 973d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView != null) { 974e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact.setContentDescription(getContext().getString( 975d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng R.string.description_quick_contact_for, mNameTextView.getText())); 976d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 977d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 978d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mQuickContact); 979d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 980d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 981d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mQuickContact; 982d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 983d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 984d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 985d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the photo view, creating it if necessary. 986d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 987d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ImageView getPhotoView() { 988d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoView == null) { 989e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhotoView = new ImageView(getContext()); 990d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams()); 991d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Quick contact style used above will set a background - remove it 992d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView.setBackground(null); 993d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPhotoView); 994d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 995d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 996d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhotoView; 997d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 998d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 999d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1000d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Removes the photo view. 1001d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1002d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void removePhotoView() { 1003d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removePhotoView(false, true); 1004d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1005d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1006d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1007d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Removes the photo view. 1008d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 1009d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param keepHorizontalPadding True means data on the right side will have 1010d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * padding on left, pretending there is still a photo view. 1011d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param keepVerticalPadding True means the View will have some height 1012d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * enough for accommodating a photo view. 1013d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1014d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void removePhotoView(boolean keepHorizontalPadding, boolean keepVerticalPadding) { 1015d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 1016d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mKeepHorizontalPaddingForPhotoView = keepHorizontalPadding; 1017d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mKeepVerticalPaddingForPhotoView = keepVerticalPadding; 1018d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoView != null) { 1019d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mPhotoView); 1020d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView = null; 1021d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1022d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mQuickContact != null) { 1023d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mQuickContact); 1024d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContact = null; 1025d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1026d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1027d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1028d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1029d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets a word prefix that will be highlighted if encountered in fields like 1030a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * name and search snippet. This will disable the mask highlighting for names. 1031d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * <p> 1032d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * NOTE: must be all upper-case 1033d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1034bd80fd64b9ff94c9ffbdb843beb4b363bb209463Chiao Cheng public void setHighlightedPrefix(String upperCasePrefix) { 1035d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHighlightedPrefix = upperCasePrefix; 1036a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1037a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1038a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 1039f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Clears previously set highlight sequences for the view. 1040a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 1041f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void clearHighlightSequences() { 1042f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence.clear(); 1043f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence.clear(); 1044a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mHighlightedPrefix = null; 1045a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1046a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1047a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 1048f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Adds a highlight sequence to the name highlighter. 1049f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param start The start position of the highlight sequence. 1050f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param end The end position of the highlight sequence. 1051f99a990be713ed35afe64ba8133c5428816390c6Christine Chen */ 1052f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void addNameHighlightSequence(int start, int end) { 1053f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence.add(new HighlightSequence(start, end)); 1054f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 1055f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 1056f99a990be713ed35afe64ba8133c5428816390c6Christine Chen /** 1057f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Adds a highlight sequence to the number highlighter. 1058f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param start The start position of the highlight sequence. 1059f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param end The end position of the highlight sequence. 1060a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 1061f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void addNumberHighlightSequence(int start, int end) { 1062f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence.add(new HighlightSequence(start, end)); 1063d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1064d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1065d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1066d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the contact name, creating it if necessary. 1067d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1068d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getNameTextView() { 1069d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView == null) { 1070e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mNameTextView = new TextView(getContext()); 1071d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setSingleLine(true); 1072d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setEllipsize(getTextEllipsis()); 1073f88b7b9d1a07414053a4a90d13d453a02bd58ac7Nancy Chen mNameTextView.setTextColor(mNameTextViewTextColor); 10743bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati mNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 10753bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati mNameTextViewTextSize); 1076d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Manually call setActivated() since this view may be added after the first 1077d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // setActivated() call toward this whole item view. 1078d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setActivated(isActivated()); 1079d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setGravity(Gravity.CENTER_VERTICAL); 10809f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 10819f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mNameTextView.setId(R.id.cliv_name_textview); 1082e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 1083e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang mNameTextView.setElegantTextHeight(false); 1084e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 1085d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mNameTextView); 1086d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1087d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mNameTextView; 1088d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1089d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1090d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1091d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the phonetic name. 1092d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1093d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPhoneticName(char[] text, int size) { 1094d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (text == null || size == 0) { 1095d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView != null) { 1096d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setVisibility(View.GONE); 1097d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1098d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1099d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getPhoneticNameTextView(); 1100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mPhoneticNameTextView, text, size); 1101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setVisibility(VISIBLE); 1102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1105d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1106d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the phonetic name, creating it if necessary. 1107d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1108d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getPhoneticNameTextView() { 1109d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView == null) { 1110e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhoneticNameTextView = new TextView(getContext()); 1111d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setSingleLine(true); 1112d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setEllipsize(getTextEllipsis()); 1113e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhoneticNameTextView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 11146f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mPhoneticNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1115d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setTypeface(mPhoneticNameTextView.getTypeface(), Typeface.BOLD); 1116d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setActivated(isActivated()); 11179f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPhoneticNameTextView.setId(R.id.cliv_phoneticname_textview); 1118d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPhoneticNameTextView); 1119d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1120d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhoneticNameTextView; 1121d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1122d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1123d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1124d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the data label. 1125d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1126d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setLabel(CharSequence text) { 1127d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 1128d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mLabelView != null) { 1129d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setVisibility(View.GONE); 1130d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1131d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1132d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getLabelView(); 1133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mLabelView, text); 1134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setVisibility(VISIBLE); 1135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1136d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1137d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1138d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1139d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the data label, creating it if necessary. 1140d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1141d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getLabelView() { 1142d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mLabelView == null) { 1143e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mLabelView = new TextView(getContext()); 1144e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mLabelView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, 1145e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn LayoutParams.WRAP_CONTENT)); 1146e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 1147d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setSingleLine(true); 1148d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setEllipsize(getTextEllipsis()); 114990a368279bb3e94291e12fc0c7dc8676f194c33dYorke Lee mLabelView.setTextAppearance(getContext(), R.style.TextAppearanceSmall); 1150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition == PhotoPosition.LEFT) { 1151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setAllCaps(true); 1152d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setTypeface(mLabelView.getTypeface(), Typeface.BOLD); 1154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setActivated(isActivated()); 11569f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mLabelView.setId(R.id.cliv_label_textview); 1157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mLabelView); 1158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mLabelView; 1160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the data element. 1164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1165a81953a2b1818066ef5e44817f374ac288bab343Christine Chen public void setData(char[] text, int size) { 1166d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (text == null || size == 0) { 1167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mDataView != null) { 1168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setVisibility(View.GONE); 1169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1170d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getDataView(); 1172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mDataView, text, size); 1173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setVisibility(VISIBLE); 1174a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1175a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1176a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1177a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 1178a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Sets phone number for a list item. This takes care of number highlighting if the highlight 1179a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * mask exists. 1180a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 118162dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee public void setPhoneNumber(String text, String countryIso) { 1182a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (text == null) { 1183a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (mDataView != null) { 1184a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setVisibility(View.GONE); 11859f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1186a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } else { 1187a81953a2b1818066ef5e44817f374ac288bab343Christine Chen getDataView(); 118862dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee 1189eabf27292960173c0600e022c64919453741c93fYorke Lee // TODO: Format number using PhoneNumberUtils.formatNumber before assigning it to 1190eabf27292960173c0600e022c64919453741c93fYorke Lee // mDataView. Make sure that determination of the highlight sequences are done only 1191eabf27292960173c0600e022c64919453741c93fYorke Lee // after number formatting. 119262dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee 1193a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Sets phone number texts for display after highlighting it, if applicable. 119462dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee // CharSequence textToSet = text; 1195f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final SpannableString textToSet = new SpannableString(text); 1196f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 1197f99a990be713ed35afe64ba8133c5428816390c6Christine Chen if (mNumberHighlightSequence.size() != 0) { 1198f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final HighlightSequence highlightSequence = mNumberHighlightSequence.get(0); 1199f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.applyMaskingHighlight(textToSet, highlightSequence.start, 1200f99a990be713ed35afe64ba8133c5428816390c6Christine Chen highlightSequence.end); 1201a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1202f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 1203a81953a2b1818066ef5e44817f374ac288bab343Christine Chen setMarqueeText(mDataView, textToSet); 1204a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setVisibility(VISIBLE); 1205a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1206a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // We have a phone number as "mDataView" so make it always LTR and VIEW_START 1207a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setTextDirection(View.TEXT_DIRECTION_LTR); 1208a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1212d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void setMarqueeText(TextView textView, char[] text, int size) { 1213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (getTextEllipsis() == TruncateAt.MARQUEE) { 1214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(textView, new String(text, 0, size)); 1215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(text, 0, size); 1217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void setMarqueeText(TextView textView, CharSequence text) { 1221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (getTextEllipsis() == TruncateAt.MARQUEE) { 1222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // To show MARQUEE correctly (with END effect during non-active state), we need 1223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // to build Spanned with MARQUEE in addition to TextView's ellipsize setting. 1224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final SpannableString spannable = new SpannableString(text); 1225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng spannable.setSpan(TruncateAt.MARQUEE, 0, spannable.length(), 1226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 1227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(spannable); 1228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1229d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(text); 1230d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1232d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 12344ad6cc6d88af85a069a948a27b344465619b5ad8Wenyi Wang * Returns the {@link CheckBox} view, creating it if necessary. 123508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell */ 12364ad6cc6d88af85a069a948a27b344465619b5ad8Wenyi Wang public CheckBox getCheckBox() { 123708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mCheckBox == null) { 12384ad6cc6d88af85a069a948a27b344465619b5ad8Wenyi Wang mCheckBox = new CheckBox(getContext()); 123908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell // Make non-focusable, so the rest of the ContactListItemView can be clicked. 124008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.setFocusable(false); 124108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell addView(mCheckBox); 124208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 124308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell return mCheckBox; 124408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 124508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 124608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell /** 1247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the data text, creating it if necessary. 1248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getDataView() { 1250d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mDataView == null) { 1251e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mDataView = new TextView(getContext()); 1252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setSingleLine(true); 1253d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setEllipsize(getTextEllipsis()); 125490a368279bb3e94291e12fc0c7dc8676f194c33dYorke Lee mDataView.setTextAppearance(getContext(), R.style.TextAppearanceSmall); 12556f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setActivated(isActivated()); 12579f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mDataView.setId(R.id.cliv_data_view); 1258e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 1259e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang mDataView.setElegantTextHeight(false); 1260e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 1261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mDataView); 1262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1263d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDataView; 1264d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1265d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1266d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1267d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the search snippet. 1268d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSnippet(String text) { 1270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 1271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mSnippetView != null) { 1272d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setVisibility(View.GONE); 1273d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1274d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1275f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.setPrefixText(getSnippetView(), text, mHighlightedPrefix); 1276d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setVisibility(VISIBLE); 1277d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang if (ContactDisplayUtils.isPossiblePhoneNumber(text)) { 1278d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang // Give the text-to-speech engine a hint that it's a phone number 12793abf10065b24373b3d6e46ed3c7f34af2b4639fbWenyi Wang mSnippetView.setContentDescription( 12803abf10065b24373b3d6e46ed3c7f34af2b4639fbWenyi Wang PhoneNumberUtilsCompat.createTtsSpannable(text)); 1281d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } else { 1282d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang mSnippetView.setContentDescription(null); 1283d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } 1284d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1285d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1286d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1287d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1288d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the search snippet, creating it if necessary. 1289d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1290d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getSnippetView() { 1291d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mSnippetView == null) { 1292e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mSnippetView = new TextView(getContext()); 1293d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setSingleLine(true); 1294d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setEllipsize(getTextEllipsis()); 1295e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mSnippetView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 12966f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mSnippetView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1297d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setActivated(isActivated()); 1298d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mSnippetView); 1299d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1300d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mSnippetView; 1301d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1302d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1303d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1304d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the status, creating it if necessary. 1305d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1306d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getStatusView() { 1307d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mStatusView == null) { 1308e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mStatusView = new TextView(getContext()); 1309d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setSingleLine(true); 1310d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setEllipsize(getTextEllipsis()); 1311e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mStatusView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 1312d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setTextColor(mSecondaryTextColor); 1313d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setActivated(isActivated()); 13149f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1315d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mStatusView); 1316d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1317d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mStatusView; 1318d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1319d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1320d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1321d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the status. 1322d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1323d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setStatus(CharSequence text) { 1324d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 1325d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mStatusView != null) { 1326d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setVisibility(View.GONE); 1327d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1328d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1329d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getStatusView(); 1330d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mStatusView, text); 1331d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setVisibility(VISIBLE); 1332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1333d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1334d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1335d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates the presence icon view. 1337d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1338d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPresence(Drawable icon) { 1339d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (icon != null) { 1340d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPresenceIcon == null) { 1341e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPresenceIcon = new ImageView(getContext()); 1342d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPresenceIcon); 1343d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setImageDrawable(icon); 1345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setScaleType(ScaleType.CENTER); 1346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setVisibility(View.VISIBLE); 1347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPresenceIcon != null) { 1349d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setVisibility(View.GONE); 1350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1353d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1354d19d35ef8347038f5296ed7020cab79396874937Victor Chang /** 1355d19d35ef8347038f5296ed7020cab79396874937Victor Chang * Set to display work profile icon or not 1356d19d35ef8347038f5296ed7020cab79396874937Victor Chang * 1357d19d35ef8347038f5296ed7020cab79396874937Victor Chang * @param enabled set to display work profile icon or not 1358d19d35ef8347038f5296ed7020cab79396874937Victor Chang */ 1359d19d35ef8347038f5296ed7020cab79396874937Victor Chang public void setWorkProfileIconEnabled(boolean enabled) { 1360d19d35ef8347038f5296ed7020cab79396874937Victor Chang if (mWorkProfileIcon != null) { 1361d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.setVisibility(enabled ? View.VISIBLE : View.GONE); 1362d19d35ef8347038f5296ed7020cab79396874937Victor Chang } else if (enabled) { 1363d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon = new ImageView(getContext()); 1364d19d35ef8347038f5296ed7020cab79396874937Victor Chang addView(mWorkProfileIcon); 1365d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.setImageResource(R.drawable.ic_work_profile); 1366d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.setScaleType(ScaleType.CENTER_INSIDE); 1367d19d35ef8347038f5296ed7020cab79396874937Victor Chang mWorkProfileIcon.setVisibility(View.VISIBLE); 1368d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 1369d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 1370d19d35ef8347038f5296ed7020cab79396874937Victor Chang 1371d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TruncateAt getTextEllipsis() { 1372d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return TruncateAt.MARQUEE; 1373d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1374d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1375d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showDisplayName(Cursor cursor, int nameColumnIndex, int displayOrder) { 1376d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng CharSequence name = cursor.getString(nameColumnIndex); 137727330d80bb6575df2964112d34143125c8af9b78Yorke Lee setDisplayName(name); 137827330d80bb6575df2964112d34143125c8af9b78Yorke Lee 137927330d80bb6575df2964112d34143125c8af9b78Yorke Lee // Since the quick contact content description is derived from the display name and there is 138027330d80bb6575df2964112d34143125c8af9b78Yorke Lee // no guarantee that when the quick contact is initialized the display name is already set, 138127330d80bb6575df2964112d34143125c8af9b78Yorke Lee // do it here too. 138227330d80bb6575df2964112d34143125c8af9b78Yorke Lee if (mQuickContact != null) { 1383e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact.setContentDescription(getContext().getString( 138427330d80bb6575df2964112d34143125c8af9b78Yorke Lee R.string.description_quick_contact_for, mNameTextView.getText())); 138527330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 138627330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 138727330d80bb6575df2964112d34143125c8af9b78Yorke Lee 138827330d80bb6575df2964112d34143125c8af9b78Yorke Lee public void setDisplayName(CharSequence name, boolean highlight) { 138927330d80bb6575df2964112d34143125c8af9b78Yorke Lee if (!TextUtils.isEmpty(name) && highlight) { 139027330d80bb6575df2964112d34143125c8af9b78Yorke Lee clearHighlightSequences(); 139127330d80bb6575df2964112d34143125c8af9b78Yorke Lee addNameHighlightSequence(0, name.length()); 139227330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 139327330d80bb6575df2964112d34143125c8af9b78Yorke Lee setDisplayName(name); 139427330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 139527330d80bb6575df2964112d34143125c8af9b78Yorke Lee 139627330d80bb6575df2964112d34143125c8af9b78Yorke Lee public void setDisplayName(CharSequence name) { 1397d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!TextUtils.isEmpty(name)) { 1398a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Chooses the available highlighting method for highlighting. 1399a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (mHighlightedPrefix != null) { 1400a81953a2b1818066ef5e44817f374ac288bab343Christine Chen name = mTextHighlighter.applyPrefixHighlight(name, mHighlightedPrefix); 1401f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } else if (mNameHighlightSequence.size() != 0) { 1402f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final SpannableString spannableName = new SpannableString(name); 1403f99a990be713ed35afe64ba8133c5428816390c6Christine Chen for (HighlightSequence highlightSequence : mNameHighlightSequence) { 1404f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.applyMaskingHighlight(spannableName, highlightSequence.start, 1405f99a990be713ed35afe64ba8133c5428816390c6Christine Chen highlightSequence.end); 1406f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 1407f99a990be713ed35afe64ba8133c5428816390c6Christine Chen name = spannableName; 1408a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1409d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1410d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng name = mUnknownNameText; 1411d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1412d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(getNameTextView(), name); 1413d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang 1414d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang if (ContactDisplayUtils.isPossiblePhoneNumber(name)) { 1415d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang // Give the text-to-speech engine a hint that it's a phone number 14167b03f132552cbee9b5df1958621bcf808217c2c6Tingting Wang mNameTextView.setTextDirection(View.TEXT_DIRECTION_LTR); 1417d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang mNameTextView.setContentDescription( 14183abf10065b24373b3d6e46ed3c7f34af2b4639fbWenyi Wang PhoneNumberUtilsCompat.createTtsSpannable(name.toString())); 1419d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } else { 142082f67c1535b00320bdcc7df603c0f259df7b83a4Qi Wang // Remove span tags of highlighting for talkback to avoid reading highlighting and rest 142182f67c1535b00320bdcc7df603c0f259df7b83a4Qi Wang // of the name into two separate parts. 142282f67c1535b00320bdcc7df603c0f259df7b83a4Qi Wang mNameTextView.setContentDescription(name.toString()); 1423d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } 1424d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1425d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 142608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell public void hideCheckBox() { 142708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mCheckBox != null) { 142808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell removeView(mCheckBox); 142908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox = null; 143008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 143108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 143208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 1433d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void hideDisplayName() { 1434d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView != null) { 1435d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mNameTextView); 1436d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView = null; 1437d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1438d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1439d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1440d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showPhoneticName(Cursor cursor, int phoneticNameColumnIndex) { 1441d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.copyStringToBuffer(phoneticNameColumnIndex, mPhoneticNameBuffer); 1442d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int phoneticNameSize = mPhoneticNameBuffer.sizeCopied; 1443d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (phoneticNameSize != 0) { 1444d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPhoneticName(mPhoneticNameBuffer.data, phoneticNameSize); 1445d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1446d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPhoneticName(null, 0); 1447d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1448d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1449d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1450d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void hidePhoneticName() { 1451d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView != null) { 1452d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mPhoneticNameTextView); 1453d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView = null; 1454d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1455d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1456d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1457d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1458d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets the proper icon (star or presence or nothing) and/or status message. 1459d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1460d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showPresenceAndStatusMessage(Cursor cursor, int presenceColumnIndex, 1461d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int contactStatusColumnIndex) { 1462d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Drawable icon = null; 1463d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int presence = 0; 1464d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!cursor.isNull(presenceColumnIndex)) { 1465d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng presence = cursor.getInt(presenceColumnIndex); 1466d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng icon = ContactPresenceIconUtil.getPresenceIcon(getContext(), presence); 1467d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1468d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPresence(icon); 1469d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1470d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String statusMessage = null; 1471d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (contactStatusColumnIndex != 0 && !cursor.isNull(contactStatusColumnIndex)) { 1472d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusMessage = cursor.getString(contactStatusColumnIndex); 1473d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1474d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // If there is no status message from the contact, but there was a presence value, then use 1475d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // the default status message string 1476d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (statusMessage == null && presence != 0) { 1477d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusMessage = ContactStatusUtil.getStatusString(getContext(), presence); 1478d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1479d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setStatus(statusMessage); 1480d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1481d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1482d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1483938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang * Shows search snippet for email and phone number matches. 1484938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang */ 1485938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang public void showSnippet(Cursor cursor, String query, int snippetColumn) { 1486938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // TODO: this does not properly handle phone numbers with control characters 1487938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // For example if the phone number is 444-5555, the search query 4445 will match the 1488938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // number since we normalize it before querying CP2 but the snippet will fail since 1489938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // the portion to be highlighted is 444-5 not 4445. 1490938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang final String snippet = cursor.getString(snippetColumn); 1491938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang if (snippet == null) { 1492938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang setSnippet(null); 1493938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang return; 1494938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang } 1495938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang final String displayName = cursor.getColumnIndex(Contacts.DISPLAY_NAME) >= 0 1496938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang ? cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)) : null; 1497938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang if (snippet.equals(displayName)) { 1498938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // If the snippet exactly matches the display name (i.e. the phone number or email 1499938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // address is being used as the display name) then no snippet is necessary 1500938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang setSnippet(null); 1501938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang return; 1502938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang } 1503938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang // Show the snippet with the part of the query that matched it 1504938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang setSnippet(updateSnippet(snippet, query, displayName)); 1505938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang } 1506938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang 1507938440c2a5da9ae8b6c88a21210fd0f624ffb3f1Walter Jang /** 1508d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Shows search snippet. 1509d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1510d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showSnippet(Cursor cursor, int summarySnippetColumnIndex) { 151173f41231df9868953047cbbcce529ee5687de7f2Walter Jang if (cursor.getColumnCount() <= summarySnippetColumnIndex 151273f41231df9868953047cbbcce529ee5687de7f2Walter Jang || !SearchSnippets.SNIPPET.equals(cursor.getColumnName(summarySnippetColumnIndex))) { 1513d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setSnippet(null); 1514d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 1515d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1516d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 151705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng String snippet = cursor.getString(summarySnippetColumnIndex); 1518cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1519d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Do client side snippeting if provider didn't do it 152005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final Bundle extras = cursor.getExtras(); 1521d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (extras.getBoolean(ContactsContract.DEFERRED_SNIPPETING)) { 1522d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 152305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final String query = extras.getString(ContactsContract.DEFERRED_SNIPPETING_QUERY); 1524cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1525cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng String displayName = null; 1526cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int displayNameIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); 1527cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (displayNameIndex >= 0) { 1528cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng displayName = cursor.getString(displayNameIndex); 152905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1530cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1531cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng snippet = updateSnippet(snippet, query, displayName); 1532cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 153305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } else { 153405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (snippet != null) { 153505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int from = 0; 153605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int to = snippet.length(); 153705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int start = snippet.indexOf(DefaultContactListAdapter.SNIPPET_START_MATCH); 153805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (start == -1) { 153905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng snippet = null; 154005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } else { 154105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int firstNl = snippet.lastIndexOf('\n', start); 154205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (firstNl != -1) { 154305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng from = firstNl + 1; 154405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 154505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int end = snippet.lastIndexOf(DefaultContactListAdapter.SNIPPET_END_MATCH); 154605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (end != -1) { 154705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int lastNl = snippet.indexOf('\n', end); 154805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (lastNl != -1) { 154905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng to = lastNl; 155005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 155105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1552d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 155305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng StringBuilder sb = new StringBuilder(); 155405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng for (int i = from; i < to; i++) { 155505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng char c = snippet.charAt(i); 155605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (c != DefaultContactListAdapter.SNIPPET_START_MATCH && 155705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng c != DefaultContactListAdapter.SNIPPET_END_MATCH) { 155805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng sb.append(c); 155905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1560d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 156105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng snippet = sb.toString(); 1562d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1563d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1564d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1565cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1566d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setSnippet(snippet); 1567d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1568d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1569cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng /** 1570cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * Used for deferred snippets from the database. The contents come back as large strings which 1571cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * need to be extracted for display. 1572cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * 1573cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param snippet The snippet from the database. 1574cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param query The search query substring. 1575cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param displayName The contact display name. 1576cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @return The proper snippet to display. 1577cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng */ 1578cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng private String updateSnippet(String snippet, String query, String displayName) { 1579cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1580cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (TextUtils.isEmpty(snippet) || TextUtils.isEmpty(query)) { 1581cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1582cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1583cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng query = SearchUtil.cleanStartAndEndOfSearchQuery(query.toLowerCase()); 1584cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1585cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // If the display name already contains the query term, return empty - snippets should 1586cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // not be needed in that case. 1587cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!TextUtils.isEmpty(displayName)) { 1588cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final String lowerDisplayName = displayName.toLowerCase(); 1589cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final List<String> nameTokens = split(lowerDisplayName); 1590cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng for (String nameToken : nameTokens) { 1591cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (nameToken.startsWith(query)) { 1592cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1593cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1594cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1595cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1596cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1597cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // The snippet may contain multiple data lines. 1598cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Show the first line that matches the query. 1599cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final SearchUtil.MatchedLine matched = SearchUtil.findMatchingLine(snippet, query); 1600cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1601cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (matched != null && matched.line != null) { 1602cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Tokenize for long strings since the match may be at the end of it. 1603cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Skip this part for short strings since the whole string will be displayed. 1604cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Most contact strings are short so the snippetize method will be called infrequently. 1605cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final int lengthThreshold = getResources().getInteger( 1606cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng R.integer.snippet_length_before_tokenize); 1607cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (matched.line.length() > lengthThreshold) { 1608cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return snippetize(matched.line, matched.startIndex, lengthThreshold); 1609cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } else { 1610cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return matched.line; 1611cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1612cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1613cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1614cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // No match found. 1615cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1616cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1617cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1618cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng private String snippetize(String line, int matchIndex, int maxLength) { 1619cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Show up to maxLength characters. But we only show full tokens so show the last full token 1620cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // up to maxLength characters. So as many starting tokens as possible before trying ending 1621cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // tokens. 1622cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int remainingLength = maxLength; 1623cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int tempRemainingLength = remainingLength; 1624cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1625cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Start the end token after the matched query. 1626cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int index = matchIndex; 1627cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int endTokenIndex = index; 1628cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1629cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find the match token first. 1630cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index < line.length()) { 1631cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1632cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng endTokenIndex = index; 1633cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng remainingLength = tempRemainingLength; 1634cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng break; 1635cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1636cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1637cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index++; 1638cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1639cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1640cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find as much content before the match. 1641cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index = matchIndex - 1; 1642cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength = remainingLength; 1643cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int startTokenIndex = matchIndex; 1644cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index > -1 && tempRemainingLength > 0) { 1645cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1646cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng startTokenIndex = index; 1647cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng remainingLength = tempRemainingLength; 1648cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1649cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1650cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index--; 1651cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1652cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1653cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index = endTokenIndex; 1654cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength = remainingLength; 1655cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find remaining content at after match. 1656cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index < line.length() && tempRemainingLength > 0) { 1657cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1658cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng endTokenIndex = index; 1659cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1660cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1661cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index++; 1662cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1663cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Append ellipse if there is content before or after. 1664cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final StringBuilder sb = new StringBuilder(); 1665cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (startTokenIndex > 0) { 1666cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append("..."); 1667cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1668cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append(line.substring(startTokenIndex, endTokenIndex)); 1669cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (endTokenIndex < line.length()) { 1670cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append("..."); 1671cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1672cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return sb.toString(); 1673cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1674cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 167505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng private static final Pattern SPLIT_PATTERN = Pattern.compile( 167605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng "([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+"); 167705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 167805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng /** 167905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * Helper method for splitting a string into tokens. The lists passed in are populated with 168005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * the 168105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * tokens and offsets into the content of each token. The tokenization function parses e-mail 168205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * addresses as a single token; otherwise it splits on any non-alphanumeric character. 168305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * 168405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * @param content Content to split. 168505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * @return List of token strings. 168605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng */ 168705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng private static List<String> split(String content) { 168805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final Matcher matcher = SPLIT_PATTERN.matcher(content); 168905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final ArrayList<String> tokens = Lists.newArrayList(); 169005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng while (matcher.find()) { 169105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng tokens.add(matcher.group()); 169205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 169305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng return tokens; 169405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 169505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 1696d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 16977a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner * Shows data element. 1698d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1699d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showData(Cursor cursor, int dataColumnIndex) { 1700d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.copyStringToBuffer(dataColumnIndex, mDataBuffer); 17017a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner setData(mDataBuffer.data, mDataBuffer.sizeCopied); 17027a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 17037a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner 1704d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setActivatedStateSupported(boolean flag) { 1705d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng this.mActivatedStateSupported = flag; 1706d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1707d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1708fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee public void setAdjustSelectionBoundsEnabled(boolean enabled) { 1709fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee mAdjustSelectionBoundsEnabled = enabled; 1710fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 1711fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee 1712d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 1713d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void requestLayout() { 1714d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // We will assume that once measured this will not need to resize 1715d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // itself, so there is no need to pass the layout request to the parent 1716d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // view (ListView). 1717d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng forceLayout(); 1718d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1719d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1720d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPhotoPosition(PhotoPosition photoPosition) { 1721d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoPosition = photoPosition; 1722d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1723d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1724d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public PhotoPosition getPhotoPosition() { 1725d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhotoPosition; 1726d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1727d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1728d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1729e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee * Set drawable resources directly for the drawable resource of the photo view. 173027330d80bb6575df2964112d34143125c8af9b78Yorke Lee * 1731e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee * @param drawableId Id of drawable resource. 173227330d80bb6575df2964112d34143125c8af9b78Yorke Lee */ 1733e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee public void setDrawableResource(int drawableId) { 1734e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee ImageView photo = getPhotoView(); 173527330d80bb6575df2964112d34143125c8af9b78Yorke Lee photo.setScaleType(ImageView.ScaleType.CENTER); 1736e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang final Drawable drawable = ContextCompat.getDrawable(getContext(), drawableId); 1737e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang final int iconColor = 1738e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang ContextCompat.getColor(getContext(), R.color.search_shortcut_icon_color); 1739e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 1740e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang photo.setImageDrawable(drawable); 1741e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang photo.setImageTintList(ColorStateList.valueOf(iconColor)); 1742e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } else { 1743e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang final Drawable drawableWrapper = DrawableCompat.wrap(drawable).mutate(); 1744e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang DrawableCompat.setTint(drawableWrapper, iconColor); 1745e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang photo.setImageDrawable(drawableWrapper); 1746e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 174727330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 174810349f190691f802b8935175dbf38bff74a8a703Yorke Lee 174910349f190691f802b8935175dbf38bff74a8a703Yorke Lee @Override 175010349f190691f802b8935175dbf38bff74a8a703Yorke Lee public boolean onTouchEvent(MotionEvent event) { 175110349f190691f802b8935175dbf38bff74a8a703Yorke Lee final float x = event.getX(); 175210349f190691f802b8935175dbf38bff74a8a703Yorke Lee final float y = event.getY(); 1753538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // If the touch event's coordinates are not within the view's header, then delegate 1754538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // to super.onTouchEvent so that regular view behavior is preserved. Otherwise, consume 1755538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // and ignore the touch event. 1756bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee if (mBoundsWithoutHeader.contains((int) x, (int) y) || !pointIsInView(x, y)) { 175710349f190691f802b8935175dbf38bff74a8a703Yorke Lee return super.onTouchEvent(event); 175810349f190691f802b8935175dbf38bff74a8a703Yorke Lee } else { 175910349f190691f802b8935175dbf38bff74a8a703Yorke Lee return true; 176010349f190691f802b8935175dbf38bff74a8a703Yorke Lee } 176110349f190691f802b8935175dbf38bff74a8a703Yorke Lee } 1762bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee 1763bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee private final boolean pointIsInView(float localX, float localY) { 1764f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati return localX >= mLeftOffset && localX < mRightOffset 17653d7e2893cb55dc0f1bc4f7e731322973ee09bc1fYorke Lee && localY >= 0 && localY < (getBottom() - getTop()); 1766bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee } 1767d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng} 1768