ContactListItemView.java revision 3181b8ffaa6af370268acee97903e98a6b94138f
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; 323181b8ffaa6af370268acee97903e98a6b94138fWenyi Wangimport android.support.v4.content.ContextCompat; 33941090ea5f2cd169038bd9f6c2811d6bc12db6a5Brian Attwellimport android.telephony.PhoneNumberUtils; 34d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.Spannable; 35d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.SpannableString; 36d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils; 37d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils.TruncateAt; 38d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.util.AttributeSet; 393bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapatiimport android.util.TypedValue; 40d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.Gravity; 4110349f190691f802b8935175dbf38bff74a8a703Yorke Leeimport android.view.MotionEvent; 42d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.View; 43d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.ViewGroup; 44d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.AbsListView.SelectionBoundsAdjuster; 4508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwellimport android.widget.CheckBox; 46d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ImageView; 47d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ImageView.ScaleType; 48d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.QuickContactBadge; 49d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.TextView; 50d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 51d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.ContactPresenceIconUtil; 52d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.ContactStatusUtil; 53d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.R; 54a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport com.android.contacts.common.format.TextHighlighter; 55d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jangimport com.android.contacts.common.util.ContactDisplayUtils; 56cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Chengimport com.android.contacts.common.util.SearchUtil; 57864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Leeimport com.android.contacts.common.util.ViewUtil; 58864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Lee 5905897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport com.google.common.collect.Lists; 6005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 6105897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.ArrayList; 6205897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.List; 639f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglioimport java.util.Locale; 6405897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.regex.Matcher; 6505897c8e016942e10f0ef6f0da02d339480d4748Chiao Chengimport java.util.regex.Pattern; 66d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 67d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/** 68d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * A custom view for an item in the contact list. 69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The view contains the contact's photo, a set of text views (for name, status, etc...) and 70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * icons for presence and call. 71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The view uses no XML file for layout and all the measurements and layouts are done 72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * in the onMeasure and onLayout methods. 73d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 74d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The layout puts the contact's photo on the right side of the view, the call icon (if present) 75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * to the left of the photo, the text lines are aligned to the left and the presence icon (if 76d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * present) is set to the left of the status line. 77d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 78d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * The layout also supports a header (used as a header of a group of contacts) that is above the 79d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * contact's data and a divider between contact view. 80d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 81d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 82d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic class ContactListItemView extends ViewGroup 83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng implements SelectionBoundsAdjuster { 84d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 85d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Style values for layout and appearance 86d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // The initialized values are defaults if none is provided through xml. 87d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPreferredHeight = 0; 88d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mGapBetweenImageAndText = 0; 89d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mGapBetweenLabelAndData = 0; 90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPresenceIconMargin = 4; 91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPresenceIconSize = 16; 92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mTextIndent = 0; 937961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee private int mTextOffsetTop; 943bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati private int mNameTextViewTextSize; 951f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee private int mHeaderWidth; 96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private Drawable mActivatedBackgroundDrawable; 97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 98f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati // Set in onLayout. Represent left and right position of the View on the screen. 99f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati private int mLeftOffset; 100f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati private int mRightOffset; 101f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati 102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Used with {@link #mLabelView}, specifying the width ratio between label and data. 104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 105d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelViewWidthWeight = 3; 106d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 107d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Used with {@link #mDataView}, specifying the width ratio between label and data. 108d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 109d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDataViewWidthWeight = 5; 110d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 111f99a990be713ed35afe64ba8133c5428816390c6Christine Chen protected static class HighlightSequence { 112f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private final int start; 113f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private final int end; 114f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 115f99a990be713ed35afe64ba8133c5428816390c6Christine Chen HighlightSequence(int start, int end) { 116f99a990be713ed35afe64ba8133c5428816390c6Christine Chen this.start = start; 117f99a990be713ed35afe64ba8133c5428816390c6Christine Chen this.end = end; 118f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 119f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 120f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 121f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private ArrayList<HighlightSequence> mNameHighlightSequence; 122f99a990be713ed35afe64ba8133c5428816390c6Christine Chen private ArrayList<HighlightSequence> mNumberHighlightSequence; 123a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 124a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Highlighting prefix for names. 125a81953a2b1818066ef5e44817f374ac288bab343Christine Chen private String mHighlightedPrefix; 126a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 127d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 128d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Where to put contact photo. This affects the other Views' layout or look-and-feel. 1299f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio * 1309f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio * TODO: replace enum with int constants 131d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 132d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public enum PhotoPosition { 133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng LEFT, 134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng RIGHT 135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1369f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 1379f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio static public final PhotoPosition getDefaultPhotoPosition(boolean opposite) { 1389f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio final Locale locale = Locale.getDefault(); 1399f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale); 1409f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio switch (layoutDirection) { 1419f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio case View.LAYOUT_DIRECTION_RTL: 142a9950433dc469d24b314204075a6250d2410e01bAndrew Lee return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT); 1439f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio case View.LAYOUT_DIRECTION_LTR: 1449f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio default: 145a9950433dc469d24b314204075a6250d2410e01bAndrew Lee return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT); 1469f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1479f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1489f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 1499f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio private PhotoPosition mPhotoPosition = getDefaultPhotoPosition(false /* normal/non opposite */); 150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Header layout data 152d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mHeaderTextView; 1531f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee private boolean mIsSectionHeaderEnabled; 154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // The views inside the contact view 156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mQuickContactEnabled = true; 157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private QuickContactBadge mQuickContact; 158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ImageView mPhotoView; 159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mNameTextView; 160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mPhoneticNameTextView; 161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mLabelView; 162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mDataView; 163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mSnippetView; 164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TextView mStatusView; 165d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ImageView mPresenceIcon; 16608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell private CheckBox mCheckBox; 167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ColorStateList mSecondaryTextColor; 169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 170a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDefaultPhotoViewSize = 0; 173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Can be effective even when {@link #mPhotoView} is null, as we want to have horizontal padding 175d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * to align other data in this View. 176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhotoViewWidth; 178d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Can be effective even when {@link #mPhotoView} is null, as we want to have vertical padding. 180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhotoViewHeight; 182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Only effective when {@link #mPhotoView} is null. 185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * When true all the Views on the right side of the photo should have horizontal padding on 186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * those left assuming there is a photo. 187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 188d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mKeepHorizontalPaddingForPhotoView; 189d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 190d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Only effective when {@link #mPhotoView} is null. 191d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 192d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mKeepVerticalPaddingForPhotoView; 193d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 194d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 195d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * True when {@link #mPhotoViewWidth} and {@link #mPhotoViewHeight} are ready for being used. 196d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * False indicates those values should be updated before being used in position calculation. 197d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 198d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mPhotoViewWidthAndHeightAreReady = false; 199d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 200d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mNameTextViewHeight; 20158a793ee1253f8f46dd7f754a51f61a6bbcdce60Andrew Lee private int mNameTextViewTextColor = Color.BLACK; 202d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mPhoneticNameTextViewHeight; 203d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelViewHeight; 204d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDataViewHeight; 205d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mSnippetTextViewHeight; 206d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mStatusTextViewHeight; 20708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell private int mCheckBoxHeight; 20808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell private int mCheckBoxWidth; 209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Holds Math.max(mLabelTextViewHeight, mDataViewHeight), assuming Label and Data share the 211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // same row. 212d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mLabelAndDataViewMaxHeight; 213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO: some TextView fields are using CharArrayBuffer while some are not. Determine which is 215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // more efficient for each case or in general, and simplify the whole implementation. 216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Note: if we're sure MARQUEE will be used every time, there's no reason to use 217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // CharArrayBuffer, since MARQUEE requires Span and thus we need to copy characters inside the 218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // buffer to Spannable once, while CharArrayBuffer is for directly applying char array to 219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TextView without any modification. 220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private final CharArrayBuffer mDataBuffer = new CharArrayBuffer(128); 221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private final CharArrayBuffer mPhoneticNameBuffer = new CharArrayBuffer(128); 222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mActivatedStateSupported; 224fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee private boolean mAdjustSelectionBoundsEnabled = true; 225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private Rect mBoundsWithoutHeader = new Rect(); 227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** A helper used to highlight a prefix in a text field. */ 229a81953a2b1818066ef5e44817f374ac288bab343Christine Chen private final TextHighlighter mTextHighlighter; 230d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private CharSequence mUnknownNameText; 231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 232d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactListItemView(Context context) { 233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super(context); 234d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 23542210256d3d584783ac2fb2742088ce57d9da766Yorke Lee mTextHighlighter = new TextHighlighter(Typeface.BOLD); 236bb67024ef64a7853f5ec320652d80f0cdf7b660fYorke Lee mNameHighlightSequence = new ArrayList<HighlightSequence>(); 237bb67024ef64a7853f5ec320652d80f0cdf7b660fYorke Lee mNumberHighlightSequence = new ArrayList<HighlightSequence>(); 238d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 239d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 240d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactListItemView(Context context, AttributeSet attrs) { 241d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super(context, attrs); 242d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 24325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee TypedArray a; 24425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 24525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee if (R.styleable.ContactListItemView != null) { 24625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee // Read all style values 24725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView); 24825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPreferredHeight = a.getDimensionPixelSize( 24925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_height, mPreferredHeight); 25025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mActivatedBackgroundDrawable = a.getDrawable( 25125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_activated_background); 25225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 25325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenImageAndText = a.getDimensionPixelOffset( 25425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_gap_between_image_and_text, 25525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenImageAndText); 25625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenLabelAndData = a.getDimensionPixelOffset( 25725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_gap_between_label_and_data, 25825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mGapBetweenLabelAndData); 25925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconMargin = a.getDimensionPixelOffset( 26025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_presence_icon_margin, 26125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconMargin); 26225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconSize = a.getDimensionPixelOffset( 26325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_presence_icon_size, 26425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mPresenceIconSize); 26525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDefaultPhotoViewSize = a.getDimensionPixelOffset( 26625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize); 26725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mTextIndent = a.getDimensionPixelOffset( 26825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_text_indent, mTextIndent); 26925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mTextOffsetTop = a.getDimensionPixelOffset( 27025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_text_offset_top, mTextOffsetTop); 27125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDataViewWidthWeight = a.getInteger( 27225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_data_width_weight, 27325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mDataViewWidthWeight); 27425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mLabelViewWidthWeight = a.getInteger( 27525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_label_width_weight, 27625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mLabelViewWidthWeight); 27725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextColor = a.getColor( 27825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_name_text_color, 27925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextColor); 28025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mNameTextViewTextSize = (int) a.getDimension( 28125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_name_text_size, 28225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee (int) getResources().getDimension(R.dimen.contact_browser_list_item_text_size)); 28325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 28425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee setPaddingRelative( 28525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 28625527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_left, 0), 28725527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 28825527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_top, 0), 28925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 29025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_right, 0), 29125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.getDimensionPixelOffset( 29225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee R.styleable.ContactListItemView_list_item_padding_bottom, 0)); 29325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee 29425527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.recycle(); 29525527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee } 296d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 29742210256d3d584783ac2fb2742088ce57d9da766Yorke Lee mTextHighlighter = new TextHighlighter(Typeface.BOLD); 29842210256d3d584783ac2fb2742088ce57d9da766Yorke Lee 29925527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee if (R.styleable.Theme != null) { 30025527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a = getContext().obtainStyledAttributes(R.styleable.Theme); 30125527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee mSecondaryTextColor = a.getColorStateList(R.styleable.Theme_android_textColorSecondary); 30225527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee a.recycle(); 30325527b9fe191063927e211bcf86d5cd26ab6b67aYorke Lee } 304d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 3051f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderWidth = 3061f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width); 3071f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee 308d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedBackgroundDrawable != null) { 309d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setCallback(this); 310d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 311f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 312f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence = new ArrayList<HighlightSequence>(); 313f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence = new ArrayList<HighlightSequence>(); 31453c7dc1e9691b5b427395642a4274d37a1a15bb4Yorke Lee 31553c7dc1e9691b5b427395642a4274d37a1a15bb4Yorke Lee setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE); 316d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 317d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 318d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setUnknownNameText(CharSequence unknownNameText) { 319d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mUnknownNameText = unknownNameText; 320d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 321d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 322d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setQuickContactEnabled(boolean flag) { 323d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContactEnabled = flag; 324d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 325d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 326d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 327d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 328d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // We will match parent's width and wrap content vertically, but make sure 329d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // height is no less than listPreferredItemHeight. 330d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int specWidth = resolveSize(0, widthMeasureSpec); 331f4fcd3def28e5b1168f5160e476c05ad69339adcAndrew Lee final int preferredHeight = mPreferredHeight; 332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 333d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextViewHeight = 0; 334d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextViewHeight = 0; 335d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelViewHeight = 0; 336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataViewHeight = 0; 337d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight = 0; 338d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight = 0; 339d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = 0; 34008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxWidth = 0; 34108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxHeight = 0; 342d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 343d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ensurePhotoViewSize(); 344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Width each TextView is able to use. 346ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee int effectiveWidth; 347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // All the other Views will honor the photo, so available width for them may be shrunk. 348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) { 349d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight() 350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng - (mPhotoViewWidth + mGapBetweenImageAndText); 351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight(); 353d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 354d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 355ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (mIsSectionHeaderEnabled) { 356ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee effectiveWidth -= mHeaderWidth + mGapBetweenImageAndText; 357ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 358ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee 359d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Go over all visible text views and measure actual width of each of them. 360d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Also calculate their heights to get the total height for this entire view. 361d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 36208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (isVisible(mCheckBox)) { 36308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.measure( 36408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 36508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 36608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxWidth = mCheckBox.getMeasuredWidth(); 36708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBoxHeight = mCheckBox.getMeasuredHeight(); 36808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell effectiveWidth -= mCheckBoxWidth + mGapBetweenImageAndText; 36908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 37008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 371d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mNameTextView)) { 37290fbbae42d4628b18e78434e7de13254099b229ePaul Soulos // Calculate width for name text - this parallels similar measurement in onLayout. 373d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int nameTextWidth = effectiveWidth; 374d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition != PhotoPosition.LEFT) { 375d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng nameTextWidth -= mTextIndent; 376d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 377d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.measure( 378d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(nameTextWidth, MeasureSpec.EXACTLY), 379d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 380d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextViewHeight = mNameTextView.getMeasuredHeight(); 381d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 382d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 383d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPhoneticNameTextView)) { 384d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.measure( 385d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY), 386d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 387d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextViewHeight = mPhoneticNameTextView.getMeasuredHeight(); 388d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 389d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 390d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // If both data (phone number/email address) and label (type like "MOBILE") are quite long, 391d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // we should ellipsize both using appropriate ratio. 392d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int dataWidth; 393d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int labelWidth; 394d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 395d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 396d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int totalWidth = effectiveWidth - mGapBetweenLabelAndData; 397d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = ((totalWidth * mDataViewWidthWeight) 398d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng / (mDataViewWidthWeight + mLabelViewWidthWeight)); 399d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = ((totalWidth * mLabelViewWidthWeight) / 400d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng (mDataViewWidthWeight + mLabelViewWidthWeight)); 401d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 402d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = effectiveWidth; 403d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = 0; 404d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 405d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 406d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataWidth = 0; 407d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 408d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = effectiveWidth; 409d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 410d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng labelWidth = 0; 411d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 412d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 413d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 414d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 415d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.measure(MeasureSpec.makeMeasureSpec(dataWidth, MeasureSpec.EXACTLY), 416d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 417d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataViewHeight = mDataView.getMeasuredHeight(); 418d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 419d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 420d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 421d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // For performance reason we don't want AT_MOST usually, but when the picture is 422d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // on right, we need to use it anyway because mDataView is next to mLabelView. 423d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int mode = (mPhotoPosition == PhotoPosition.LEFT 424d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ? MeasureSpec.EXACTLY : MeasureSpec.AT_MOST); 425d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.measure(MeasureSpec.makeMeasureSpec(labelWidth, mode), 426d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 427d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelViewHeight = mLabelView.getMeasuredHeight(); 428d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 429d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight = Math.max(mLabelViewHeight, mDataViewHeight); 430d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 431d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mSnippetView)) { 432d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.measure( 433d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY), 434d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 435d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight = mSnippetView.getMeasuredHeight(); 436d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 437d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 438d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Status view height is the biggest of the text view and the presence icon 439d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPresenceIcon)) { 440d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.measure( 441d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY), 442d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY)); 443d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight(); 444d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 445d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 446d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mStatusView)) { 447d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Presence and status are in a same row, so status will be affected by icon size. 448d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int statusWidth; 449d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPresenceIcon)) { 450d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusWidth = (effectiveWidth - mPresenceIcon.getMeasuredWidth() 451d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng - mPresenceIconMargin); 452d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 453d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusWidth = effectiveWidth; 454d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 455d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.measure(MeasureSpec.makeMeasureSpec(statusWidth, MeasureSpec.EXACTLY), 456d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 457d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusTextViewHeight = 458d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Math.max(mStatusTextViewHeight, mStatusView.getMeasuredHeight()); 459d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 460d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 461d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Calculate height including padding. 462d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int height = (mNameTextViewHeight + mPhoneticNameTextViewHeight + 463d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight + 464d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetTextViewHeight + mStatusTextViewHeight); 465d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 466d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Make sure the height is at least as high as the photo 467d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop()); 468d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 469d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Make sure height is at least the preferred height 470d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng height = Math.max(height, preferredHeight); 471d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 4721f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee // Measure the header if it is visible. 4731f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mHeaderTextView != null && mHeaderTextView.getVisibility() == VISIBLE) { 474d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.measure( 4751f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY), 4766fdf16941587a222f554482fb72531783a924b6eAndrew Lee MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 477d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 478d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 479d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMeasuredDimension(specWidth, height); 480d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 481d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 482d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 483d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 484d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int height = bottom - top; 485d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int width = right - left; 486d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 487d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Determine the vertical bounds by laying out the header first. 488d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int topBound = 0; 489d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int bottomBound = height; 490d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int leftBound = getPaddingLeft(); 491d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int rightBound = width - getPaddingRight(); 492d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 493864c67691b5a0169b5cbb91469d67d93e24ad9ebYorke Lee final boolean isLayoutRtl = ViewUtil.isViewLayoutRtl(this); 49409f15e70e86d92ae0f4c15a726b777f170845a3cYorke Lee 4951f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee // Put the section header on the left side of the contact view. 4961f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mIsSectionHeaderEnabled) { 4971f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (mHeaderTextView != null) { 4986fdf16941587a222f554482fb72531783a924b6eAndrew Lee int headerHeight = mHeaderTextView.getMeasuredHeight(); 4996fdf16941587a222f554482fb72531783a924b6eAndrew Lee int headerTopBound = (bottomBound + topBound - headerHeight) / 2 + mTextOffsetTop; 5006fdf16941587a222f554482fb72531783a924b6eAndrew Lee 5011f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderTextView.layout( 5021f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee isLayoutRtl ? rightBound - mHeaderWidth : leftBound, 5036fdf16941587a222f554482fb72531783a924b6eAndrew Lee headerTopBound, 5041f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee isLayoutRtl ? rightBound : leftBound + mHeaderWidth, 5056fdf16941587a222f554482fb72531783a924b6eAndrew Lee headerTopBound + headerHeight); 5061f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 5071f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee if (isLayoutRtl) { 5081f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee rightBound -= mHeaderWidth; 5091f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } else { 5101f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee leftBound += mHeaderWidth; 5111f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 512d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 513d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 514f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mBoundsWithoutHeader.set(left + leftBound, topBound, left + rightBound, bottomBound); 515f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mLeftOffset = left + leftBound; 516f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati mRightOffset = left + rightBound; 517ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (mIsSectionHeaderEnabled) { 518ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee if (isLayoutRtl) { 519ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee rightBound -= mGapBetweenImageAndText; 520ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } else { 521ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee leftBound += mGapBetweenImageAndText; 522ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 523ceb851d9c2d5c73bdd9c60ca47be0902516636aaAndrew Lee } 524d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 525d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported && isActivated()) { 526d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setBounds(mBoundsWithoutHeader); 527d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 528d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 52908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (isVisible(mCheckBox)) { 53008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell final int photoTop = topBound + (bottomBound - topBound - mCheckBoxHeight) / 2; 53108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mPhotoPosition == PhotoPosition.LEFT) { 53208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.layout(rightBound - mCheckBoxWidth, 53308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop, 53408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound, 53508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop + mCheckBoxHeight); 53608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } else { 53708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.layout(leftBound, 53808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop, 53908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell leftBound + mCheckBoxWidth, 54008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell photoTop + mCheckBoxHeight); 54108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 54208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 54308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 544d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final View photoView = mQuickContact != null ? mQuickContact : mPhotoView; 545d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition == PhotoPosition.LEFT) { 546d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Photo is the left most view. All the other Views should on the right of the photo. 547d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (photoView != null) { 548d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Center the photo vertically 549d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2; 550d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoView.layout( 551d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound, 552d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop, 553d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound + mPhotoViewWidth, 554d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop + mPhotoViewHeight); 555d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mPhotoViewWidth + mGapBetweenImageAndText; 556d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else if (mKeepHorizontalPaddingForPhotoView) { 557d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Draw nothing but keep the padding. 558d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mPhotoViewWidth + mGapBetweenImageAndText; 559d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 560d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 561d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Photo is the right most view. Right bound should be adjusted that way. 562d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (photoView != null) { 563d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Center the photo vertically 564d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2; 565d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoView.layout( 566d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound - mPhotoViewWidth, 567d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop, 568d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 569d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoTop + mPhotoViewHeight); 570d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText); 5719f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } else if (mKeepHorizontalPaddingForPhotoView) { 5729f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio // Draw nothing but keep the padding. 5739f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText); 574d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 575d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 576d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Add indent between left-most padding and texts. 577d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng leftBound += mTextIndent; 578d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 579d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 5807961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee // Center text vertically, then apply the top offset. 581d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int totalTextHeight = mNameTextViewHeight + mPhoneticNameTextViewHeight + 582d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight; 5837961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee int textTopBound = (bottomBound + topBound - totalTextHeight) / 2 + mTextOffsetTop; 584d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 585d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Layout all text view and presence icon 586d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Put name TextView first 587d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mNameTextView)) { 58808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell final int distanceFromEnd = mCheckBoxWidth > 0 58908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell ? mCheckBoxWidth + mGapBetweenImageAndText : 0; 59008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mPhotoPosition == PhotoPosition.LEFT) { 59108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mNameTextView.layout(leftBound, 59208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound, 59308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound - distanceFromEnd, 59408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound + mNameTextViewHeight); 59508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } else { 59608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mNameTextView.layout(leftBound + distanceFromEnd, 59708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound, 59808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell rightBound, 59908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell textTopBound + mNameTextViewHeight); 60008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 601d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mNameTextViewHeight; 602d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 603d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 604d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Presence and status 6059f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isLayoutRtl) { 6069f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int statusRightBound = rightBound; 6079f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mPresenceIcon)) { 6089f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int iconWidth = mPresenceIcon.getMeasuredWidth(); 6099f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPresenceIcon.layout( 6109f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound - iconWidth, 6119f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 6129f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound, 6139f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 6149f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusRightBound -= (iconWidth + mPresenceIconMargin); 6159f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 616d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 6179f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mStatusView)) { 6189f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.layout(leftBound, 6199f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 6209f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusRightBound, 6219f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 6229f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 6239f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } else { 6249f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int statusLeftBound = leftBound; 6259f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mPresenceIcon)) { 6269f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio int iconWidth = mPresenceIcon.getMeasuredWidth(); 6279f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPresenceIcon.layout( 6289f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio leftBound, 6299f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 6309f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio leftBound + iconWidth, 6319f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 6329f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio statusLeftBound += (iconWidth + mPresenceIconMargin); 6339f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 6349f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio 6359f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio if (isVisible(mStatusView)) { 6369f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.layout(statusLeftBound, 6379f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound, 6389f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio rightBound, 6399f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio textTopBound + mStatusTextViewHeight); 6409f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 641d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 642d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 643d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mStatusView) || isVisible(mPresenceIcon)) { 644d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mStatusTextViewHeight; 645d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 646d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 647d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Rest of text views 648d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int dataLeftBound = leftBound; 649d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mPhoneticNameTextView)) { 650d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.layout(leftBound, 651d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound, 652d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 653d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mPhoneticNameTextViewHeight); 654d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mPhoneticNameTextViewHeight; 655d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 656d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 657d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Label and Data align bottom. 658d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView)) { 659d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition == PhotoPosition.LEFT) { 660d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // When photo is on left, label is placed on the right edge of the list item. 661d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.layout(rightBound - mLabelView.getMeasuredWidth(), 662d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight, 663d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 664d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight); 665d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound -= mLabelView.getMeasuredWidth(); 666d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 667d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // When photo is on right, label is placed on the left of data view. 668d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataLeftBound = leftBound + mLabelView.getMeasuredWidth(); 669d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.layout(leftBound, 670d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight, 671d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataLeftBound, 672d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight); 673d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng dataLeftBound += mGapBetweenLabelAndData; 674d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 675d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 676d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 677d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mDataView)) { 678d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.layout(dataLeftBound, 679d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight, 680d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 681d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mLabelAndDataViewMaxHeight); 682d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 683d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mLabelView) || isVisible(mDataView)) { 684d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound += mLabelAndDataViewMaxHeight; 685d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 686d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 687d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isVisible(mSnippetView)) { 688d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.layout(leftBound, 689d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound, 690d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng rightBound, 691d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textTopBound + mSnippetTextViewHeight); 692d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 693d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 694d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 695d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 696d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void adjustListItemSelectionBounds(Rect bounds) { 697fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee if (mAdjustSelectionBoundsEnabled) { 698fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.top += mBoundsWithoutHeader.top; 699fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.bottom = bounds.top + mBoundsWithoutHeader.height(); 700fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.left = mBoundsWithoutHeader.left; 701fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee bounds.right = mBoundsWithoutHeader.right; 702fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 703d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 704d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 705d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected boolean isVisible(View view) { 706d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return view != null && view.getVisibility() == View.VISIBLE; 707d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 708d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 709d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 710d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Extracts width and height from the style 711d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 712d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void ensurePhotoViewSize() { 713d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mPhotoViewWidthAndHeightAreReady) { 714d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize(); 715d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mQuickContactEnabled && mPhotoView == null) { 716d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mKeepHorizontalPaddingForPhotoView) { 717d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidth = 0; 718d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 719d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mKeepVerticalPaddingForPhotoView) { 720d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewHeight = 0; 721d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 722d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 723d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 724d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = true; 725d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 726d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 727d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 728d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected int getDefaultPhotoViewSize() { 729d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDefaultPhotoViewSize; 730d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 731d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 732d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 733d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Gets a LayoutParam that corresponds to the default photo size. 734d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 735d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @return A new LayoutParam. 736d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 737d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private LayoutParams getDefaultPhotoLayoutParams() { 738d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng LayoutParams params = generateDefaultLayoutParams(); 739d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng params.width = getDefaultPhotoViewSize(); 740d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng params.height = params.width; 741d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return params; 742d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 743d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 744d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 745d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void drawableStateChanged() { 746d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.drawableStateChanged(); 747d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported) { 748d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.setState(getDrawableState()); 749d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 750d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 751d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 752d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 753d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected boolean verifyDrawable(Drawable who) { 754d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return who == mActivatedBackgroundDrawable || super.verifyDrawable(who); 755d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 756d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 757d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 758d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void jumpDrawablesToCurrentState() { 759d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.jumpDrawablesToCurrentState(); 760d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported) { 761d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.jumpToCurrentState(); 762d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 763d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 764d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 765d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 766d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void dispatchDraw(Canvas canvas) { 767d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mActivatedStateSupported && isActivated()) { 768d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mActivatedBackgroundDrawable.draw(canvas); 769d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 770d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 771d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.dispatchDraw(canvas); 772d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 773d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 774d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 775d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets section header or makes it invisible if the title is null. 776d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 777d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSectionHeader(String title) { 778d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!TextUtils.isEmpty(title)) { 779d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mHeaderTextView == null) { 780e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mHeaderTextView = new TextView(getContext()); 781e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mHeaderTextView.setTextAppearance(getContext(), R.style.SectionHeaderStyle); 7826fdf16941587a222f554482fb72531783a924b6eAndrew Lee mHeaderTextView.setGravity( 7836fdf16941587a222f554482fb72531783a924b6eAndrew Lee ViewUtil.isViewLayoutRtl(this) ? Gravity.RIGHT : Gravity.LEFT); 784d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mHeaderTextView); 785d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 786d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mHeaderTextView, title); 787d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.setVisibility(View.VISIBLE); 788d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHeaderTextView.setAllCaps(true); 7891f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } else if (mHeaderTextView != null) { 7901f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mHeaderTextView.setVisibility(View.GONE); 791d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 792d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 793d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 7941f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee public void setIsSectionHeaderEnabled(boolean isSectionHeaderEnabled) { 7951f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee mIsSectionHeaderEnabled = isSectionHeaderEnabled; 7961f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 7971f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee 798d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 799d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the quick contact badge, creating it if necessary. 800d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 801d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public QuickContactBadge getQuickContact() { 802d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mQuickContactEnabled) { 803d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng throw new IllegalStateException("QuickContact is disabled for this view"); 804d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 805d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mQuickContact == null) { 806e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact = new QuickContactBadge(getContext()); 8073f9c2f426058413055fa54c08c69ad9461717658Yorke Lee mQuickContact.setOverlay(null); 808d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams()); 809d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView != null) { 810e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact.setContentDescription(getContext().getString( 811d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng R.string.description_quick_contact_for, mNameTextView.getText())); 812d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 813d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 814d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mQuickContact); 815d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 816d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 817d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mQuickContact; 818d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 819d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 820d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 821d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the photo view, creating it if necessary. 822d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 823d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ImageView getPhotoView() { 824d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoView == null) { 825e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhotoView = new ImageView(getContext()); 826d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams()); 827d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Quick contact style used above will set a background - remove it 828d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView.setBackground(null); 829d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPhotoView); 830d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 831d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 832d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhotoView; 833d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 834d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 835d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 836d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Removes the photo view. 837d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 838d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void removePhotoView() { 839d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removePhotoView(false, true); 840d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 841d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 842d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 843d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Removes the photo view. 844d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 845d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param keepHorizontalPadding True means data on the right side will have 846d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * padding on left, pretending there is still a photo view. 847d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param keepVerticalPadding True means the View will have some height 848d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * enough for accommodating a photo view. 849d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 850d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void removePhotoView(boolean keepHorizontalPadding, boolean keepVerticalPadding) { 851d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoViewWidthAndHeightAreReady = false; 852d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mKeepHorizontalPaddingForPhotoView = keepHorizontalPadding; 853d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mKeepVerticalPaddingForPhotoView = keepVerticalPadding; 854d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoView != null) { 855d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mPhotoView); 856d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoView = null; 857d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 858d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mQuickContact != null) { 859d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mQuickContact); 860d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContact = null; 861d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 862d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 863d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 864d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 865d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets a word prefix that will be highlighted if encountered in fields like 866a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * name and search snippet. This will disable the mask highlighting for names. 867d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * <p> 868d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * NOTE: must be all upper-case 869d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 870bd80fd64b9ff94c9ffbdb843beb4b363bb209463Chiao Cheng public void setHighlightedPrefix(String upperCasePrefix) { 871d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mHighlightedPrefix = upperCasePrefix; 872a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 873a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 874a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 875f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Clears previously set highlight sequences for the view. 876a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 877f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void clearHighlightSequences() { 878f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence.clear(); 879f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence.clear(); 880a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mHighlightedPrefix = null; 881a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 882a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 883a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 884f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Adds a highlight sequence to the name highlighter. 885f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param start The start position of the highlight sequence. 886f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param end The end position of the highlight sequence. 887f99a990be713ed35afe64ba8133c5428816390c6Christine Chen */ 888f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void addNameHighlightSequence(int start, int end) { 889f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNameHighlightSequence.add(new HighlightSequence(start, end)); 890f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 891f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 892f99a990be713ed35afe64ba8133c5428816390c6Christine Chen /** 893f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * Adds a highlight sequence to the number highlighter. 894f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param start The start position of the highlight sequence. 895f99a990be713ed35afe64ba8133c5428816390c6Christine Chen * @param end The end position of the highlight sequence. 896a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 897f99a990be713ed35afe64ba8133c5428816390c6Christine Chen public void addNumberHighlightSequence(int start, int end) { 898f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mNumberHighlightSequence.add(new HighlightSequence(start, end)); 899d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 900d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 901d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 902d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the contact name, creating it if necessary. 903d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 904d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getNameTextView() { 905d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView == null) { 906e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mNameTextView = new TextView(getContext()); 907d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setSingleLine(true); 908d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setEllipsize(getTextEllipsis()); 909f88b7b9d1a07414053a4a90d13d453a02bd58ac7Nancy Chen mNameTextView.setTextColor(mNameTextViewTextColor); 9103bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati mNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 9113bc19a3bb1ed23b03352fff6de69a89e763a315eSai Cheemalapati mNameTextViewTextSize); 912d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Manually call setActivated() since this view may be added after the first 913d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // setActivated() call toward this whole item view. 914d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setActivated(isActivated()); 915d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView.setGravity(Gravity.CENTER_VERTICAL); 9169f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 9179f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mNameTextView.setId(R.id.cliv_name_textview); 9187961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee mNameTextView.setElegantTextHeight(false); 919d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mNameTextView); 920d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 921d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mNameTextView; 922d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 923d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 924d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 925d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the phonetic name. 926d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 927d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPhoneticName(char[] text, int size) { 928d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (text == null || size == 0) { 929d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView != null) { 930d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setVisibility(View.GONE); 931d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 932d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 933d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getPhoneticNameTextView(); 934d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mPhoneticNameTextView, text, size); 935d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setVisibility(VISIBLE); 936d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 937d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 938d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 939d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 940d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the phonetic name, creating it if necessary. 941d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 942d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getPhoneticNameTextView() { 943d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView == null) { 944e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhoneticNameTextView = new TextView(getContext()); 945d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setSingleLine(true); 946d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setEllipsize(getTextEllipsis()); 947e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPhoneticNameTextView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 9486f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mPhoneticNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 949d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setTypeface(mPhoneticNameTextView.getTypeface(), Typeface.BOLD); 950d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView.setActivated(isActivated()); 9519f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mPhoneticNameTextView.setId(R.id.cliv_phoneticname_textview); 952d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPhoneticNameTextView); 953d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 954d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhoneticNameTextView; 955d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 956d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 957d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 958d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the data label. 959d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 960d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setLabel(CharSequence text) { 961d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 962d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mLabelView != null) { 963d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setVisibility(View.GONE); 964d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 965d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 966d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getLabelView(); 967d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mLabelView, text); 968d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setVisibility(VISIBLE); 969d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 970d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 971d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 972d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 973d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the data label, creating it if necessary. 974d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 975d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getLabelView() { 976d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mLabelView == null) { 977e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mLabelView = new TextView(getContext()); 978d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setSingleLine(true); 979d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setEllipsize(getTextEllipsis()); 98090a368279bb3e94291e12fc0c7dc8676f194c33dYorke Lee mLabelView.setTextAppearance(getContext(), R.style.TextAppearanceSmall); 981d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhotoPosition == PhotoPosition.LEFT) { 982d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setAllCaps(true); 9839f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mLabelView.setGravity(Gravity.END); 984d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 985d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setTypeface(mLabelView.getTypeface(), Typeface.BOLD); 986d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 987d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mLabelView.setActivated(isActivated()); 9889f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mLabelView.setId(R.id.cliv_label_textview); 989d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mLabelView); 990d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 991d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mLabelView; 992d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 993d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 994d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 995d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the data element. 996d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 997a81953a2b1818066ef5e44817f374ac288bab343Christine Chen public void setData(char[] text, int size) { 998d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (text == null || size == 0) { 999d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mDataView != null) { 1000d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setVisibility(View.GONE); 1001d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1002d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1003d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getDataView(); 1004d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mDataView, text, size); 1005d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setVisibility(VISIBLE); 1006a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1007a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1008a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1009a81953a2b1818066ef5e44817f374ac288bab343Christine Chen /** 1010a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Sets phone number for a list item. This takes care of number highlighting if the highlight 1011a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * mask exists. 1012a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */ 101362dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee public void setPhoneNumber(String text, String countryIso) { 1014a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (text == null) { 1015a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (mDataView != null) { 1016a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setVisibility(View.GONE); 10179f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio } 1018a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } else { 1019a81953a2b1818066ef5e44817f374ac288bab343Christine Chen getDataView(); 102062dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee 1021eabf27292960173c0600e022c64919453741c93fYorke Lee // TODO: Format number using PhoneNumberUtils.formatNumber before assigning it to 1022eabf27292960173c0600e022c64919453741c93fYorke Lee // mDataView. Make sure that determination of the highlight sequences are done only 1023eabf27292960173c0600e022c64919453741c93fYorke Lee // after number formatting. 102462dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee 1025a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Sets phone number texts for display after highlighting it, if applicable. 102662dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee // CharSequence textToSet = text; 1027f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final SpannableString textToSet = new SpannableString(text); 1028f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 1029f99a990be713ed35afe64ba8133c5428816390c6Christine Chen if (mNumberHighlightSequence.size() != 0) { 1030f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final HighlightSequence highlightSequence = mNumberHighlightSequence.get(0); 1031f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.applyMaskingHighlight(textToSet, highlightSequence.start, 1032f99a990be713ed35afe64ba8133c5428816390c6Christine Chen highlightSequence.end); 1033a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1034f99a990be713ed35afe64ba8133c5428816390c6Christine Chen 1035a81953a2b1818066ef5e44817f374ac288bab343Christine Chen setMarqueeText(mDataView, textToSet); 1036a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setVisibility(VISIBLE); 1037a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 1038a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // We have a phone number as "mDataView" so make it always LTR and VIEW_START 1039a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setTextDirection(View.TEXT_DIRECTION_LTR); 1040a81953a2b1818066ef5e44817f374ac288bab343Christine Chen mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1041d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1042d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1043d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1044d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void setMarqueeText(TextView textView, char[] text, int size) { 1045d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (getTextEllipsis() == TruncateAt.MARQUEE) { 1046d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(textView, new String(text, 0, size)); 1047d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1048d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(text, 0, size); 1049d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1050d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1051d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1052d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void setMarqueeText(TextView textView, CharSequence text) { 1053d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (getTextEllipsis() == TruncateAt.MARQUEE) { 1054d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // To show MARQUEE correctly (with END effect during non-active state), we need 1055d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // to build Spanned with MARQUEE in addition to TextView's ellipsize setting. 1056d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final SpannableString spannable = new SpannableString(text); 1057d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng spannable.setSpan(TruncateAt.MARQUEE, 0, spannable.length(), 1058d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 1059d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(spannable); 1060d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1061d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng textView.setText(text); 1062d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1063d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1064d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1065d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 106608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell * Returns the {@link CheckBox} view, creating it if necessary. 106708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell */ 106808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell public CheckBox getCheckBox() { 106908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mCheckBox == null) { 107008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox = new CheckBox(getContext()); 107108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell // Make non-focusable, so the rest of the ContactListItemView can be clicked. 107208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox.setFocusable(false); 107308901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell addView(mCheckBox); 107408901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 107508901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell return mCheckBox; 107608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 107708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 107808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell /** 1079d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the data text, creating it if necessary. 1080d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1081d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getDataView() { 1082d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mDataView == null) { 1083e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mDataView = new TextView(getContext()); 1084d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setSingleLine(true); 1085d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setEllipsize(getTextEllipsis()); 108690a368279bb3e94291e12fc0c7dc8676f194c33dYorke Lee mDataView.setTextAppearance(getContext(), R.style.TextAppearanceSmall); 10876f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1088d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDataView.setActivated(isActivated()); 10899f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mDataView.setId(R.id.cliv_data_view); 10907961175eb7b8b8d6f990bd8e510f59fe48c5ef4bAndrew Lee mDataView.setElegantTextHeight(false); 1091d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mDataView); 1092d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1093d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDataView; 1094d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1095d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1096d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1097d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the search snippet. 1098d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1099d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSnippet(String text) { 1100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 1101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mSnippetView != null) { 1102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setVisibility(View.GONE); 1103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1105f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.setPrefixText(getSnippetView(), text, mHighlightedPrefix); 1106d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setVisibility(VISIBLE); 1107d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang if (ContactDisplayUtils.isPossiblePhoneNumber(text)) { 1108d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang // Give the text-to-speech engine a hint that it's a phone number 1109c30de25fea532591e85c33966e04aa1443710eabBrian Attwell mSnippetView.setContentDescription(PhoneNumberUtils.createTtsSpannable(text)); 1110d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } else { 1111d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang mSnippetView.setContentDescription(null); 1112d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } 1113d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1114d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1115d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1116d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1117d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the search snippet, creating it if necessary. 1118d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1119d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getSnippetView() { 1120d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mSnippetView == null) { 1121e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mSnippetView = new TextView(getContext()); 1122d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setSingleLine(true); 1123d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setEllipsize(getTextEllipsis()); 1124e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mSnippetView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 11256f2673a25ecc59426c2faa2cfec5780e59ac5e5eWalter Jang mSnippetView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1126d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSnippetView.setActivated(isActivated()); 1127d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mSnippetView); 1128d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1129d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mSnippetView; 1130d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1131d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1132d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the text view for the status, creating it if necessary. 1134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public TextView getStatusView() { 1136d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mStatusView == null) { 1137e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mStatusView = new TextView(getContext()); 1138d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setSingleLine(true); 1139d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setEllipsize(getTextEllipsis()); 1140e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mStatusView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small); 1141d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setTextColor(mSecondaryTextColor); 1142d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setActivated(isActivated()); 11439f0c1621718b382531cbebfe38907e6d3db6ceaeFabrice Di Meglio mStatusView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 1144d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mStatusView); 1145d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1146d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mStatusView; 1147d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1148d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1149d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates a text view for the status. 1151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1152d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setStatus(CharSequence text) { 1153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(text)) { 1154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mStatusView != null) { 1155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setVisibility(View.GONE); 1156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getStatusView(); 1159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(mStatusView, text); 1160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mStatusView.setVisibility(VISIBLE); 1161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1165d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Adds or updates the presence icon view. 1166d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPresence(Drawable icon) { 1168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (icon != null) { 1169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPresenceIcon == null) { 1170e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mPresenceIcon = new ImageView(getContext()); 1171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addView(mPresenceIcon); 1172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setImageDrawable(icon); 1174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setScaleType(ScaleType.CENTER); 1175d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setVisibility(View.VISIBLE); 1176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPresenceIcon != null) { 1178d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPresenceIcon.setVisibility(View.GONE); 1179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private TruncateAt getTextEllipsis() { 1184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return TruncateAt.MARQUEE; 1185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showDisplayName(Cursor cursor, int nameColumnIndex, int displayOrder) { 1188d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng CharSequence name = cursor.getString(nameColumnIndex); 118927330d80bb6575df2964112d34143125c8af9b78Yorke Lee setDisplayName(name); 119027330d80bb6575df2964112d34143125c8af9b78Yorke Lee 119127330d80bb6575df2964112d34143125c8af9b78Yorke Lee // Since the quick contact content description is derived from the display name and there is 119227330d80bb6575df2964112d34143125c8af9b78Yorke Lee // no guarantee that when the quick contact is initialized the display name is already set, 119327330d80bb6575df2964112d34143125c8af9b78Yorke Lee // do it here too. 119427330d80bb6575df2964112d34143125c8af9b78Yorke Lee if (mQuickContact != null) { 1195e9736747aa45ed6091a5479b38e3311823675853Yorke Lee mQuickContact.setContentDescription(getContext().getString( 119627330d80bb6575df2964112d34143125c8af9b78Yorke Lee R.string.description_quick_contact_for, mNameTextView.getText())); 119727330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 119827330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 119927330d80bb6575df2964112d34143125c8af9b78Yorke Lee 120027330d80bb6575df2964112d34143125c8af9b78Yorke Lee public void setDisplayName(CharSequence name, boolean highlight) { 120127330d80bb6575df2964112d34143125c8af9b78Yorke Lee if (!TextUtils.isEmpty(name) && highlight) { 120227330d80bb6575df2964112d34143125c8af9b78Yorke Lee clearHighlightSequences(); 120327330d80bb6575df2964112d34143125c8af9b78Yorke Lee addNameHighlightSequence(0, name.length()); 120427330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 120527330d80bb6575df2964112d34143125c8af9b78Yorke Lee setDisplayName(name); 120627330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 120727330d80bb6575df2964112d34143125c8af9b78Yorke Lee 120827330d80bb6575df2964112d34143125c8af9b78Yorke Lee public void setDisplayName(CharSequence name) { 1209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!TextUtils.isEmpty(name)) { 1210a81953a2b1818066ef5e44817f374ac288bab343Christine Chen // Chooses the available highlighting method for highlighting. 1211a81953a2b1818066ef5e44817f374ac288bab343Christine Chen if (mHighlightedPrefix != null) { 1212a81953a2b1818066ef5e44817f374ac288bab343Christine Chen name = mTextHighlighter.applyPrefixHighlight(name, mHighlightedPrefix); 1213f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } else if (mNameHighlightSequence.size() != 0) { 1214f99a990be713ed35afe64ba8133c5428816390c6Christine Chen final SpannableString spannableName = new SpannableString(name); 1215f99a990be713ed35afe64ba8133c5428816390c6Christine Chen for (HighlightSequence highlightSequence : mNameHighlightSequence) { 1216f99a990be713ed35afe64ba8133c5428816390c6Christine Chen mTextHighlighter.applyMaskingHighlight(spannableName, highlightSequence.start, 1217f99a990be713ed35afe64ba8133c5428816390c6Christine Chen highlightSequence.end); 1218f99a990be713ed35afe64ba8133c5428816390c6Christine Chen } 1219f99a990be713ed35afe64ba8133c5428816390c6Christine Chen name = spannableName; 1220a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 1221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng name = mUnknownNameText; 1223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setMarqueeText(getNameTextView(), name); 1225d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang 1226d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang if (ContactDisplayUtils.isPossiblePhoneNumber(name)) { 1227d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang // Give the text-to-speech engine a hint that it's a phone number 12287b03f132552cbee9b5df1958621bcf808217c2c6Tingting Wang mNameTextView.setTextDirection(View.TEXT_DIRECTION_LTR); 1229d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang mNameTextView.setContentDescription( 1230c30de25fea532591e85c33966e04aa1443710eabBrian Attwell PhoneNumberUtils.createTtsSpannable(name.toString())); 1231d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } else { 1232d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang mNameTextView.setContentDescription(null); 1233d4c540b696b2575f32b3bb9f7f34248ea18c37b4Walter Jang } 1234d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1235d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 123608901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell public void hideCheckBox() { 123708901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell if (mCheckBox != null) { 123808901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell removeView(mCheckBox); 123908901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell mCheckBox = null; 124008901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 124108901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell } 124208901312c70a244e5785668cdbe1a009ed9b67a8Brian Attwell 1243d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void hideDisplayName() { 1244d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mNameTextView != null) { 1245d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mNameTextView); 1246d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mNameTextView = null; 1247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1250d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showPhoneticName(Cursor cursor, int phoneticNameColumnIndex) { 1251d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.copyStringToBuffer(phoneticNameColumnIndex, mPhoneticNameBuffer); 1252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int phoneticNameSize = mPhoneticNameBuffer.sizeCopied; 1253d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (phoneticNameSize != 0) { 1254d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPhoneticName(mPhoneticNameBuffer.data, phoneticNameSize); 1255d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 1256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPhoneticName(null, 0); 1257d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1258d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1259d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1260d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void hidePhoneticName() { 1261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mPhoneticNameTextView != null) { 1262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removeView(mPhoneticNameTextView); 1263d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhoneticNameTextView = null; 1264d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1265d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1266d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1267d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1268d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Sets the proper icon (star or presence or nothing) and/or status message. 1269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showPresenceAndStatusMessage(Cursor cursor, int presenceColumnIndex, 1271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int contactStatusColumnIndex) { 1272d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Drawable icon = null; 1273d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int presence = 0; 1274d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!cursor.isNull(presenceColumnIndex)) { 1275d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng presence = cursor.getInt(presenceColumnIndex); 1276d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng icon = ContactPresenceIconUtil.getPresenceIcon(getContext(), presence); 1277d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1278d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setPresence(icon); 1279d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1280d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String statusMessage = null; 1281d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (contactStatusColumnIndex != 0 && !cursor.isNull(contactStatusColumnIndex)) { 1282d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusMessage = cursor.getString(contactStatusColumnIndex); 1283d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1284d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // If there is no status message from the contact, but there was a presence value, then use 1285d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // the default status message string 1286d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (statusMessage == null && presence != 0) { 1287d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng statusMessage = ContactStatusUtil.getStatusString(getContext(), presence); 1288d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1289d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setStatus(statusMessage); 1290d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1291d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1292d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1293d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Shows search snippet. 1294d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1295d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showSnippet(Cursor cursor, int summarySnippetColumnIndex) { 1296d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (cursor.getColumnCount() <= summarySnippetColumnIndex) { 1297d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setSnippet(null); 1298d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 1299d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1300d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 130105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng String snippet = cursor.getString(summarySnippetColumnIndex); 1302cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1303d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Do client side snippeting if provider didn't do it 130405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final Bundle extras = cursor.getExtras(); 1305d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (extras.getBoolean(ContactsContract.DEFERRED_SNIPPETING)) { 1306d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 130705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final String query = extras.getString(ContactsContract.DEFERRED_SNIPPETING_QUERY); 1308cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1309cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng String displayName = null; 1310cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int displayNameIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); 1311cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (displayNameIndex >= 0) { 1312cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng displayName = cursor.getString(displayNameIndex); 131305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1314cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1315cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng snippet = updateSnippet(snippet, query, displayName); 1316cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 131705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } else { 131805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (snippet != null) { 131905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int from = 0; 132005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int to = snippet.length(); 132105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int start = snippet.indexOf(DefaultContactListAdapter.SNIPPET_START_MATCH); 132205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (start == -1) { 132305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng snippet = null; 132405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } else { 132505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int firstNl = snippet.lastIndexOf('\n', start); 132605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (firstNl != -1) { 132705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng from = firstNl + 1; 132805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 132905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int end = snippet.lastIndexOf(DefaultContactListAdapter.SNIPPET_END_MATCH); 133005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (end != -1) { 133105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng int lastNl = snippet.indexOf('\n', end); 133205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (lastNl != -1) { 133305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng to = lastNl; 133405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 133505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 133705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng StringBuilder sb = new StringBuilder(); 133805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng for (int i = from; i < to; i++) { 133905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng char c = snippet.charAt(i); 134005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng if (c != DefaultContactListAdapter.SNIPPET_START_MATCH && 134105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng c != DefaultContactListAdapter.SNIPPET_END_MATCH) { 134205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng sb.append(c); 134305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 1344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 134505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng snippet = sb.toString(); 1346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1349cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setSnippet(snippet); 1351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1353cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng /** 1354cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * Used for deferred snippets from the database. The contents come back as large strings which 1355cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * need to be extracted for display. 1356cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * 1357cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param snippet The snippet from the database. 1358cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param query The search query substring. 1359cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @param displayName The contact display name. 1360cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng * @return The proper snippet to display. 1361cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng */ 1362cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng private String updateSnippet(String snippet, String query, String displayName) { 1363cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1364cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (TextUtils.isEmpty(snippet) || TextUtils.isEmpty(query)) { 1365cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1366cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1367cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng query = SearchUtil.cleanStartAndEndOfSearchQuery(query.toLowerCase()); 1368cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1369cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // If the display name already contains the query term, return empty - snippets should 1370cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // not be needed in that case. 1371cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!TextUtils.isEmpty(displayName)) { 1372cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final String lowerDisplayName = displayName.toLowerCase(); 1373cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final List<String> nameTokens = split(lowerDisplayName); 1374cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng for (String nameToken : nameTokens) { 1375cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (nameToken.startsWith(query)) { 1376cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1377cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1378cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1379cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1380cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1381cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // The snippet may contain multiple data lines. 1382cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Show the first line that matches the query. 1383cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final SearchUtil.MatchedLine matched = SearchUtil.findMatchingLine(snippet, query); 1384cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1385cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (matched != null && matched.line != null) { 1386cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Tokenize for long strings since the match may be at the end of it. 1387cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Skip this part for short strings since the whole string will be displayed. 1388cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Most contact strings are short so the snippetize method will be called infrequently. 1389cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final int lengthThreshold = getResources().getInteger( 1390cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng R.integer.snippet_length_before_tokenize); 1391cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (matched.line.length() > lengthThreshold) { 1392cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return snippetize(matched.line, matched.startIndex, lengthThreshold); 1393cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } else { 1394cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return matched.line; 1395cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1396cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1397cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1398cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // No match found. 1399cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return null; 1400cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1401cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1402cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng private String snippetize(String line, int matchIndex, int maxLength) { 1403cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Show up to maxLength characters. But we only show full tokens so show the last full token 1404cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // up to maxLength characters. So as many starting tokens as possible before trying ending 1405cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // tokens. 1406cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int remainingLength = maxLength; 1407cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int tempRemainingLength = remainingLength; 1408cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1409cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Start the end token after the matched query. 1410cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int index = matchIndex; 1411cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int endTokenIndex = index; 1412cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1413cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find the match token first. 1414cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index < line.length()) { 1415cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1416cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng endTokenIndex = index; 1417cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng remainingLength = tempRemainingLength; 1418cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng break; 1419cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1420cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1421cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index++; 1422cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1423cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1424cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find as much content before the match. 1425cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index = matchIndex - 1; 1426cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength = remainingLength; 1427cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng int startTokenIndex = matchIndex; 1428cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index > -1 && tempRemainingLength > 0) { 1429cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1430cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng startTokenIndex = index; 1431cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng remainingLength = tempRemainingLength; 1432cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1433cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1434cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index--; 1435cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1436cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 1437cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index = endTokenIndex; 1438cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength = remainingLength; 1439cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Find remaining content at after match. 1440cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng while (index < line.length() && tempRemainingLength > 0) { 1441cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (!Character.isLetterOrDigit(line.charAt(index))) { 1442cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng endTokenIndex = index; 1443cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1444cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng tempRemainingLength--; 1445cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng index++; 1446cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1447cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng // Append ellipse if there is content before or after. 1448cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng final StringBuilder sb = new StringBuilder(); 1449cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (startTokenIndex > 0) { 1450cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append("..."); 1451cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1452cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append(line.substring(startTokenIndex, endTokenIndex)); 1453cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng if (endTokenIndex < line.length()) { 1454cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng sb.append("..."); 1455cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1456cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng return sb.toString(); 1457cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng } 1458cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng 145905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng private static final Pattern SPLIT_PATTERN = Pattern.compile( 146005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng "([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+"); 146105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 146205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng /** 146305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * Helper method for splitting a string into tokens. The lists passed in are populated with 146405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * the 146505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * tokens and offsets into the content of each token. The tokenization function parses e-mail 146605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * addresses as a single token; otherwise it splits on any non-alphanumeric character. 146705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * 146805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * @param content Content to split. 146905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng * @return List of token strings. 147005897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng */ 147105897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng private static List<String> split(String content) { 147205897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final Matcher matcher = SPLIT_PATTERN.matcher(content); 147305897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng final ArrayList<String> tokens = Lists.newArrayList(); 147405897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng while (matcher.find()) { 147505897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng tokens.add(matcher.group()); 147605897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 147705897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng return tokens; 147805897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng } 147905897c8e016942e10f0ef6f0da02d339480d4748Chiao Cheng 1480d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 14817a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner * Shows data element. 1482d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 1483d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void showData(Cursor cursor, int dataColumnIndex) { 1484d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.copyStringToBuffer(dataColumnIndex, mDataBuffer); 14857a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner setData(mDataBuffer.data, mDataBuffer.sizeCopied); 14867a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 14877a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner 1488d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setActivatedStateSupported(boolean flag) { 1489d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng this.mActivatedStateSupported = flag; 1490d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1491d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1492fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee public void setAdjustSelectionBoundsEnabled(boolean enabled) { 1493fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee mAdjustSelectionBoundsEnabled = enabled; 1494fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 1495fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee 1496d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 1497d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void requestLayout() { 1498d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // We will assume that once measured this will not need to resize 1499d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // itself, so there is no need to pass the layout request to the parent 1500d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // view (ListView). 1501d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng forceLayout(); 1502d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1503d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1504d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPhotoPosition(PhotoPosition photoPosition) { 1505d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoPosition = photoPosition; 1506d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1507d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1508d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public PhotoPosition getPhotoPosition() { 1509d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhotoPosition; 1510d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 1511d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 1512d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 1513e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee * Set drawable resources directly for the drawable resource of the photo view. 151427330d80bb6575df2964112d34143125c8af9b78Yorke Lee * 1515e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee * @param drawableId Id of drawable resource. 151627330d80bb6575df2964112d34143125c8af9b78Yorke Lee */ 1517e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee public void setDrawableResource(int drawableId) { 1518e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee ImageView photo = getPhotoView(); 151927330d80bb6575df2964112d34143125c8af9b78Yorke Lee photo.setScaleType(ImageView.ScaleType.CENTER); 1520e05a0f5d375168585594fccf68a3ec60a88d4430Andrew Lee photo.setImageDrawable(getContext().getDrawable(drawableId)); 15213181b8ffaa6af370268acee97903e98a6b94138fWenyi Wang photo.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor( 15223181b8ffaa6af370268acee97903e98a6b94138fWenyi Wang getContext(), R.color.search_shortcut_icon_color))); 152327330d80bb6575df2964112d34143125c8af9b78Yorke Lee } 152410349f190691f802b8935175dbf38bff74a8a703Yorke Lee 152510349f190691f802b8935175dbf38bff74a8a703Yorke Lee @Override 152610349f190691f802b8935175dbf38bff74a8a703Yorke Lee public boolean onTouchEvent(MotionEvent event) { 152710349f190691f802b8935175dbf38bff74a8a703Yorke Lee final float x = event.getX(); 152810349f190691f802b8935175dbf38bff74a8a703Yorke Lee final float y = event.getY(); 1529538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // If the touch event's coordinates are not within the view's header, then delegate 1530538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // to super.onTouchEvent so that regular view behavior is preserved. Otherwise, consume 1531538e05b3bbde399f25ccf1aad251fca6d7f4d6b3Yorke Lee // and ignore the touch event. 1532bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee if (mBoundsWithoutHeader.contains((int) x, (int) y) || !pointIsInView(x, y)) { 153310349f190691f802b8935175dbf38bff74a8a703Yorke Lee return super.onTouchEvent(event); 153410349f190691f802b8935175dbf38bff74a8a703Yorke Lee } else { 153510349f190691f802b8935175dbf38bff74a8a703Yorke Lee return true; 153610349f190691f802b8935175dbf38bff74a8a703Yorke Lee } 153710349f190691f802b8935175dbf38bff74a8a703Yorke Lee } 1538bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee 1539bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee private final boolean pointIsInView(float localX, float localY) { 1540f7a205fdcb17161c454bee673cc2fce5b23d0760Sai Cheemalapati return localX >= mLeftOffset && localX < mRightOffset 15413d7e2893cb55dc0f1bc4f7e731322973ee09bc1fYorke Lee && localY >= 0 && localY < (getBottom() - getTop()); 1542bded9d078784569efef4aec2d636ce3f733601d7Yorke Lee } 1543d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng} 1544