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.graphics.drawable.StateListDrawable; 20 import android.net.Uri; 21 import android.support.v4.text.BidiFormatter; 22 import android.support.v4.text.TextDirectionHeuristicsCompat; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.ImageView; 27 28 import com.android.ex.chips.DropdownChipLayouter; 29 import com.android.ex.chips.RecipientEntry; 30 import com.android.messaging.R; 31 import com.android.messaging.datamodel.data.ContactListItemData; 32 import com.android.messaging.datamodel.data.ParticipantData; 33 import com.android.messaging.ui.ContactIconView; 34 import com.android.messaging.util.Assert; 35 import com.android.messaging.util.AvatarUriUtil; 36 import com.android.messaging.util.ContactRecipientEntryUtils; 37 import com.android.messaging.util.ContactUtil; 38 39 /** 40 * An implementation for {@link DropdownChipLayouter}. Layouts the dropdown 41 * list in the ContactRecipientAutoCompleteView in Material style. 42 */ 43 public class ContactDropdownLayouter extends DropdownChipLayouter { 44 private final ContactListItemView.HostInterface mClivHostInterface; 45 46 public ContactDropdownLayouter(final LayoutInflater inflater, final Context context, 47 final ContactListItemView.HostInterface clivHostInterface) { 48 super(inflater, context); 49 mClivHostInterface = new ContactListItemView.HostInterface() { 50 51 @Override 52 public void onContactListItemClicked(final ContactListItemData item, 53 final ContactListItemView view) { 54 // The chips UI will handle auto-complete item click events, so No-op here. 55 } 56 57 @Override 58 public boolean isContactSelected(final ContactListItemData item) { 59 // In chips drop down we don't show any selected checkmark per design. 60 return false; 61 } 62 }; 63 } 64 65 /** 66 * Bind a drop down view to a RecipientEntry. We'd like regular dropdown items (BASE_RECIPIENT) 67 * to behave the same as regular ContactListItemViews, while using the chips library's 68 * item styling for alternates dropdown items (happens when you click on a chip). 69 */ 70 @Override 71 public View bindView(final View convertView, final ViewGroup parent, final RecipientEntry entry, 72 final int position, AdapterType type, final String substring, 73 final StateListDrawable deleteDrawable) { 74 if (type != AdapterType.BASE_RECIPIENT) { 75 if (type == AdapterType.SINGLE_RECIPIENT) { 76 // Treat single recipients the same way as alternates. The base implementation of 77 // single recipients would try to simplify the destination by tokenizing. We'd 78 // like to always show the full destination address per design request. 79 type = AdapterType.RECIPIENT_ALTERNATES; 80 } 81 return super.bindView(convertView, parent, entry, position, type, substring, 82 deleteDrawable); 83 } 84 85 // Default to show all the information 86 // RTL : To format contact name and detail if they happen to be phone numbers. 87 final BidiFormatter bidiFormatter = BidiFormatter.getInstance(); 88 final String displayName = bidiFormatter.unicodeWrap( 89 ContactRecipientEntryUtils.getDisplayNameForContactList(entry), 90 TextDirectionHeuristicsCompat.LTR); 91 final String destination = bidiFormatter.unicodeWrap( 92 ContactRecipientEntryUtils.formatDestination(entry), 93 TextDirectionHeuristicsCompat.LTR); 94 final View itemView = reuseOrInflateView(convertView, parent, type); 95 96 // Bold the string that is matched. 97 final CharSequence[] styledResults = 98 getStyledResults(substring, displayName, destination); 99 100 Assert.isTrue(itemView instanceof ContactListItemView); 101 final ContactListItemView contactListItemView = (ContactListItemView) itemView; 102 contactListItemView.setImageClickHandlerDisabled(true); 103 boolean isWorkContact = ContactUtil.isEnterpriseContactId(entry.getContactId()); 104 contactListItemView.bind(entry, styledResults[0], styledResults[1], 105 mClivHostInterface, (type == AdapterType.SINGLE_RECIPIENT), isWorkContact); 106 return itemView; 107 } 108 109 @Override 110 protected void bindIconToView(boolean showImage, RecipientEntry entry, ImageView view, 111 AdapterType type) { 112 if (showImage && view instanceof ContactIconView) { 113 final ContactIconView contactView = (ContactIconView) view; 114 // These show contact cards by default, but that isn't what we want here 115 contactView.setImageClickHandlerDisabled(true); 116 final Uri avatarUri = AvatarUriUtil.createAvatarUri( 117 ParticipantData.getFromRecipientEntry(entry)); 118 contactView.setImageResourceUri(avatarUri); 119 } else { 120 super.bindIconToView(showImage, entry, view, type); 121 } 122 } 123 124 @Override 125 protected int getItemLayoutResId(AdapterType type) { 126 switch (type) { 127 case BASE_RECIPIENT: 128 return R.layout.contact_list_item_view; 129 case RECIPIENT_ALTERNATES: 130 return R.layout.chips_alternates_dropdown_item; 131 default: 132 return R.layout.chips_alternates_dropdown_item; 133 } 134 } 135 136 @Override 137 protected int getAlternateItemLayoutResId(AdapterType type) { 138 return getItemLayoutResId(type); 139 } 140 } 141