1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.messaging.ui.contact; 17 18 import android.content.Context; 19 import android.database.Cursor; 20 import android.net.Uri; 21 import android.provider.ContactsContract.CommonDataKinds.Phone; 22 import android.util.AttributeSet; 23 import android.view.View; 24 import android.view.View.OnClickListener; 25 import android.widget.ImageView; 26 import android.widget.LinearLayout; 27 import android.widget.TextView; 28 29 import com.android.ex.chips.RecipientEntry; 30 import com.android.messaging.R; 31 import com.android.messaging.datamodel.DataModel; 32 import com.android.messaging.datamodel.data.ContactListItemData; 33 import com.android.messaging.datamodel.data.ParticipantData; 34 import com.android.messaging.ui.ContactIconView; 35 import com.android.messaging.util.Assert; 36 import com.android.messaging.util.AvatarUriUtil; 37 import com.google.common.annotations.VisibleForTesting; 38 39 /** 40 * The view for a single entry in a contact list. 41 */ 42 public class ContactListItemView extends LinearLayout implements OnClickListener { 43 public interface HostInterface { 44 void onContactListItemClicked(ContactListItemData item, ContactListItemView view); 45 boolean isContactSelected(ContactListItemData item); 46 } 47 48 @VisibleForTesting 49 final ContactListItemData mData; 50 private TextView mContactNameTextView; 51 private TextView mContactDetailsTextView; 52 private TextView mContactDetailTypeTextView; 53 private TextView mAlphabetHeaderTextView; 54 private ContactIconView mContactIconView; 55 private ImageView mContactCheckmarkView; 56 private HostInterface mHostInterface; 57 private boolean mShouldShowAlphabetHeader; 58 59 public ContactListItemView(final Context context, final AttributeSet attrs) { 60 super(context, attrs); 61 mData = DataModel.get().createContactListItemData(); 62 } 63 64 @Override 65 protected void onFinishInflate () { 66 mContactNameTextView = (TextView) findViewById(R.id.contact_name); 67 mContactDetailsTextView = (TextView) findViewById(R.id.contact_details); 68 mContactDetailTypeTextView = (TextView) findViewById(R.id.contact_detail_type); 69 mAlphabetHeaderTextView = (TextView) findViewById(R.id.alphabet_header); 70 mContactIconView = (ContactIconView) findViewById(R.id.contact_icon); 71 mContactCheckmarkView = (ImageView) findViewById(R.id.contact_checkmark); 72 } 73 74 /** 75 * Fills in the data associated with this view by binding to a contact cursor provided by 76 * ContactUtil. 77 * @param cursor the contact cursor. 78 * @param hostInterface host interface to this view. 79 * @param shouldShowAlphabetHeader whether an alphabetical header should shown on the side 80 * of this view. If {@code headerLabel} is empty, we will still leave space for it. 81 * @param headerLabel the alphabetical header on the side of this view, if it should be shown. 82 */ 83 public void bind(final Cursor cursor, final HostInterface hostInterface, 84 final boolean shouldShowAlphabetHeader, final String headerLabel) { 85 mData.bind(cursor, headerLabel); 86 mHostInterface = hostInterface; 87 mShouldShowAlphabetHeader = shouldShowAlphabetHeader; 88 setOnClickListener(this); 89 updateViewAppearance(); 90 } 91 92 /** 93 * Binds a RecipientEntry. This is used by the chips text view's dropdown layout. 94 * @param recipientEntry the source RecipientEntry provided by ContactDropdownLayouter, which 95 * was in turn directly from one of the existing chips, or from filtered results 96 * generated by ContactRecipientAdapter. 97 * @param styledName display name where the portion that matches the search text is bold. 98 * @param styledDestination number where the portion that matches the search text is bold. 99 * @param hostInterface host interface to this view. 100 * @param isSingleRecipient whether this item is shown as the only line item in the single 101 * recipient drop down from the chips view. If this is the case, we always show the 102 * contact avatar even if it's not a first-level entry. 103 */ 104 public void bind(final RecipientEntry recipientEntry, final CharSequence styledName, 105 final CharSequence styledDestination, final HostInterface hostInterface, 106 final boolean isSingleRecipient) { 107 mData.bind(recipientEntry, styledName, styledDestination, isSingleRecipient); 108 mHostInterface = hostInterface; 109 mShouldShowAlphabetHeader = false; 110 updateViewAppearance(); 111 } 112 113 private void updateViewAppearance() { 114 mContactNameTextView.setText(mData.getDisplayName()); 115 mContactDetailsTextView.setText(mData.getDestination()); 116 mContactDetailTypeTextView.setText(Phone.getTypeLabel(getResources(), 117 mData.getDestinationType(), mData.getDestinationLabel())); 118 final RecipientEntry recipientEntry = mData.getRecipientEntry(); 119 final String destinationString = String.valueOf(mData.getDestination()); 120 if (mData.getIsSimpleContactItem()) { 121 // This is a special number-with-avatar type of contact (for unknown contact chips 122 // and for direct "send to destination" item). In this case, make sure we only show 123 // the display name (phone number) and the avatar and hide everything else. 124 final Uri avatarUri = AvatarUriUtil.createAvatarUri( 125 ParticipantData.getFromRecipientEntry(recipientEntry)); 126 mContactIconView.setImageResourceUri(avatarUri, mData.getContactId(), 127 mData.getLookupKey(), destinationString); 128 mContactIconView.setVisibility(VISIBLE); 129 mContactCheckmarkView.setVisibility(GONE); 130 mContactDetailTypeTextView.setVisibility(GONE); 131 mContactDetailsTextView.setVisibility(GONE); 132 mContactNameTextView.setVisibility(VISIBLE); 133 } else if (mData.getIsFirstLevel()) { 134 final Uri avatarUri = AvatarUriUtil.createAvatarUri( 135 ParticipantData.getFromRecipientEntry(recipientEntry)); 136 mContactIconView.setImageResourceUri(avatarUri, mData.getContactId(), 137 mData.getLookupKey(), destinationString); 138 mContactIconView.setVisibility(VISIBLE); 139 mContactNameTextView.setVisibility(VISIBLE); 140 final boolean isSelected = mHostInterface.isContactSelected(mData); 141 setSelected(isSelected); 142 mContactCheckmarkView.setVisibility(isSelected ? VISIBLE : GONE); 143 mContactDetailsTextView.setVisibility(VISIBLE); 144 mContactDetailTypeTextView.setVisibility(VISIBLE); 145 } else { 146 mContactIconView.setImageResourceUri(null); 147 mContactIconView.setVisibility(INVISIBLE); 148 mContactNameTextView.setVisibility(GONE); 149 final boolean isSelected = mHostInterface.isContactSelected(mData); 150 setSelected(isSelected); 151 mContactCheckmarkView.setVisibility(isSelected ? VISIBLE : GONE); 152 mContactDetailsTextView.setVisibility(VISIBLE); 153 mContactDetailTypeTextView.setVisibility(VISIBLE); 154 } 155 156 if (mShouldShowAlphabetHeader) { 157 mAlphabetHeaderTextView.setVisibility(VISIBLE); 158 mAlphabetHeaderTextView.setText(mData.getAlphabetHeader()); 159 } else { 160 mAlphabetHeaderTextView.setVisibility(GONE); 161 } 162 } 163 164 /** 165 * {@inheritDoc} from OnClickListener 166 */ 167 @Override 168 public void onClick(final View v) { 169 Assert.isTrue(v == this); 170 Assert.isTrue(mHostInterface != null); 171 mHostInterface.onContactListItemClicked(mData, this); 172 } 173 174 public void setImageClickHandlerDisabled(final boolean isHandlerDisabled) { 175 mContactIconView.setImageClickHandlerDisabled(isHandlerDisabled); 176 } 177 } 178