1b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linpackage com.android.ex.chips; 2b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 3b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.content.Context; 46c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Caoimport android.content.res.Resources; 5b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.graphics.Bitmap; 6b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.graphics.BitmapFactory; 784f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walkerimport android.graphics.Color; 884f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walkerimport android.graphics.PorterDuff; 984f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walkerimport android.graphics.drawable.Drawable; 104db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Caoimport android.graphics.drawable.StateListDrawable; 11b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.net.Uri; 124db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Caoimport android.support.annotation.DrawableRes; 134db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Caoimport android.support.annotation.IdRes; 144ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Caoimport android.support.annotation.LayoutRes; 15e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedyimport android.support.annotation.Nullable; 166f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedyimport android.support.v4.view.MarginLayoutParamsCompat; 17e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedyimport android.text.SpannableStringBuilder; 18e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedyimport android.text.Spanned; 19b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.text.TextUtils; 20e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedyimport android.text.style.ForegroundColorSpan; 21b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.text.util.Rfc822Tokenizer; 22b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.view.LayoutInflater; 23b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.view.View; 24f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovicimport android.view.View.OnClickListener; 25b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.view.ViewGroup; 266f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedyimport android.view.ViewGroup.MarginLayoutParams; 27b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.widget.ImageView; 28b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport android.widget.TextView; 29b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 30b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linimport com.android.ex.chips.Queries.Query; 31b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 32b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin/** 33b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * A class that inflates and binds the views in the dropdown list from 34b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * RecipientEditTextView. 35b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 36b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Linpublic class DropdownChipLayouter { 37b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 38b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * The type of adapter that is requesting a chip layout. 39b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 40b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public enum AdapterType { 41b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin BASE_RECIPIENT, 42b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin RECIPIENT_ALTERNATES, 43b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin SINGLE_RECIPIENT 44b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 45b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 464db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao public interface ChipDeleteListener { 474db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao void onChipDelete(); 484db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 494db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao 50f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic /** 51f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * Listener that handles the dismisses of the entries of the 52f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * {@link RecipientEntry#ENTRY_TYPE_PERMISSION_REQUEST} type. 53f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic */ 54f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic public interface PermissionRequestDismissedListener { 55f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 56f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic /** 57f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * Callback that occurs when user dismisses the item that asks user to grant permissions to 58f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * the app. 59f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic */ 60f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic void onPermissionRequestDismissed(); 61f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 62f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 63b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin private final LayoutInflater mInflater; 64b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin private final Context mContext; 654db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao private ChipDeleteListener mDeleteListener; 66f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic private PermissionRequestDismissedListener mPermissionRequestDismissedListener; 67b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin private Query mQuery; 686f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy private int mAutocompleteDividerMarginStart; 69b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 70b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public DropdownChipLayouter(LayoutInflater inflater, Context context) { 71b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin mInflater = inflater; 72b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin mContext = context; 736f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy mAutocompleteDividerMarginStart = 746f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy context.getResources().getDimensionPixelOffset(R.dimen.chip_wrapper_start_padding); 75b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 76b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 77b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public void setQuery(Query query) { 78b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin mQuery = query; 79b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 80b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 814db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao public void setDeleteListener(ChipDeleteListener listener) { 824db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao mDeleteListener = listener; 834db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 844db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao 85f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic public void setPermissionRequestDismissedListener(PermissionRequestDismissedListener listener) { 86f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic mPermissionRequestDismissedListener = listener; 87f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 88f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 896f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy public void setAutocompleteDividerMarginStart(int autocompleteDividerMarginStart) { 906f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy mAutocompleteDividerMarginStart = autocompleteDividerMarginStart; 916f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy } 92b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 93b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 94b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Layouts and binds recipient information to the view. If convertView is null, inflates a new 95b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * view with getItemLaytout(). 96b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * 97b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param convertView The view to bind information to. 98b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param parent The parent to bind the view to if we inflate a new view. 99b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param entry The recipient entry to get information from. 100b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param position The position in the list. 101b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param type The adapter type that is requesting the bind. 102b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @param constraint The constraint typed in the auto complete view. 103b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * 104b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * @return A view ready to be shown in the drop down list. 105b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 106b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public View bindView(View convertView, ViewGroup parent, RecipientEntry entry, int position, 107b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin AdapterType type, String constraint) { 1084db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao return bindView(convertView, parent, entry, position, type, constraint, null); 1094db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 1104db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao 1114db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao /** 1124db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao * See {@link #bindView(View, ViewGroup, RecipientEntry, int, AdapterType, String)} 1136c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao * @param deleteDrawable a {@link android.graphics.drawable.StateListDrawable} representing 1146c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao * the delete icon. android.R.attr.state_activated should map to the delete icon, and the 1156c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao * default state can map to a drawable of your choice (or null for no drawable). 1164db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao */ 1174db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao public View bindView(View convertView, ViewGroup parent, RecipientEntry entry, int position, 1180d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock AdapterType type, String constraint, StateListDrawable deleteDrawable) { 119b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // Default to show all the information 120d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe CharSequence[] styledResults = getStyledResults(constraint, entry); 121e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy CharSequence displayName = styledResults[0]; 122e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy CharSequence destination = styledResults[1]; 123b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin boolean showImage = true; 124b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin CharSequence destinationType = getDestinationType(entry); 125b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 1260d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock final View itemView = reuseOrInflateView(convertView, parent, type); 127b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 128b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin final ViewHolder viewHolder = new ViewHolder(itemView); 129b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 130f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic // Hide some information depending on the adapter type. 1310d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock switch (type) { 132b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case BASE_RECIPIENT: 133b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (TextUtils.isEmpty(displayName) || TextUtils.equals(displayName, destination)) { 134b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin displayName = destination; 135b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 136b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // We only show the destination for secondary entries, so clear it only for the 137b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // first level. 138b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (entry.isFirstLevel()) { 139b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin destination = null; 140b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 141b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 142b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 143b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (!entry.isFirstLevel()) { 144b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin displayName = null; 145b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin showImage = false; 146b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 147b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao 148b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao // For BASE_RECIPIENT set all top dividers except for the first one to be GONE. 149b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao if (viewHolder.topDivider != null) { 150b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao viewHolder.topDivider.setVisibility(position == 0 ? View.VISIBLE : View.GONE); 1516f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy MarginLayoutParamsCompat.setMarginStart( 1526f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy (MarginLayoutParams) viewHolder.topDivider.getLayoutParams(), 1536f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy mAutocompleteDividerMarginStart); 1546f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy } 1550d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock if (viewHolder.bottomDivider != null) { 1566f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy MarginLayoutParamsCompat.setMarginStart( 1576f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy (MarginLayoutParams) viewHolder.bottomDivider.getLayoutParams(), 1586f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy mAutocompleteDividerMarginStart); 159b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao } 160b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 161b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case RECIPIENT_ALTERNATES: 162b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (position != 0) { 163b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin displayName = null; 164b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin showImage = false; 165b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 166b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 167b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case SINGLE_RECIPIENT: 16823f4fd2e3581f29e164d4b62a9095ab1e492c009Michael Berberet if (!PhoneUtil.isPhoneNumber(entry.getDestination())) { 16923f4fd2e3581f29e164d4b62a9095ab1e492c009Michael Berberet destination = Rfc822Tokenizer.tokenize(entry.getDestination())[0].getAddress(); 17023f4fd2e3581f29e164d4b62a9095ab1e492c009Michael Berberet } 171b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin destinationType = null; 172b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 173b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 174b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // Bind the information to the view 175b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin bindTextToView(displayName, viewHolder.displayNameView); 176b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin bindTextToView(destination, viewHolder.destinationView); 177b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin bindTextToView(destinationType, viewHolder.destinationTypeView); 1780d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock bindIconToView(showImage, entry, viewHolder.imageView, type); 1796c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao bindDrawableToDeleteView(deleteDrawable, entry.getDisplayName(), viewHolder.deleteView); 18084f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker bindIndicatorToView( 18184f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker entry.getIndicatorIconId(), entry.getIndicatorText(), viewHolder.indicatorView); 182f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic bindPermissionRequestDismissView(viewHolder.permissionRequestDismissView); 183f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 1840d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock // Hide some view groups depending on the entry type 1850d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock final int entryType = entry.getEntryType(); 1860d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock if (entryType == RecipientEntry.ENTRY_TYPE_PERSON) { 1870d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock setViewVisibility(viewHolder.personViewGroup, View.VISIBLE); 1880d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock setViewVisibility(viewHolder.permissionViewGroup, View.GONE); 189e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock setViewVisibility(viewHolder.permissionBottomDivider, View.GONE); 1900d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock } else if (entryType == RecipientEntry.ENTRY_TYPE_PERMISSION_REQUEST) { 1910d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock setViewVisibility(viewHolder.personViewGroup, View.GONE); 1920d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock setViewVisibility(viewHolder.permissionViewGroup, View.VISIBLE); 193e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock setViewVisibility(viewHolder.permissionBottomDivider, View.VISIBLE); 1940d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock } 1950d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock 196b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return itemView; 197b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 198b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 199b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 2004ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao * Returns a new view with {@link #getItemLayoutResId(AdapterType)}. 201b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 2024ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao public View newView(AdapterType type) { 2034ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return mInflater.inflate(getItemLayoutResId(type), null); 204b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 205b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 206b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 207b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns the same view, or inflates a new one if the given view was null. 208b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 2090d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock protected View reuseOrInflateView(View convertView, ViewGroup parent, AdapterType type) { 2100d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock int itemLayout = getItemLayoutResId(type); 2110d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock switch (type) { 212b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case BASE_RECIPIENT: 213b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case RECIPIENT_ALTERNATES: 214b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 215b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case SINGLE_RECIPIENT: 2160d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock itemLayout = getAlternateItemLayoutResId(type); 217b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 218b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 219b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return convertView != null ? convertView : mInflater.inflate(itemLayout, parent, false); 220b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 221b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 222b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 223b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Binds the text to the given text view. If the text was null, hides the text view. 224b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 225b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin protected void bindTextToView(CharSequence text, TextView view) { 226b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (view == null) { 227b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return; 228b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 229b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 230b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (text != null) { 231b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setText(text); 232b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setVisibility(View.VISIBLE); 233b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } else { 234b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setVisibility(View.GONE); 235b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 236b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 237b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 238b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 239b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Binds the avatar icon to the image view. If we don't want to show the image, hides the 240b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * image view. 241b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 242b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin protected void bindIconToView(boolean showImage, RecipientEntry entry, ImageView view, 243b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin AdapterType type) { 244b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (view == null) { 245b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return; 246b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 247b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 248b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (showImage) { 249b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin switch (type) { 250b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case BASE_RECIPIENT: 251b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin byte[] photoBytes = entry.getPhotoBytes(); 252b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (photoBytes != null && photoBytes.length > 0) { 253b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin final Bitmap photo = BitmapFactory.decodeByteArray(photoBytes, 0, 254b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin photoBytes.length); 255b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setImageBitmap(photo); 256b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } else { 257b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setImageResource(getDefaultPhotoResId()); 258b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 259b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 260b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case RECIPIENT_ALTERNATES: 261b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin Uri thumbnailUri = entry.getPhotoThumbnailUri(); 262b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin if (thumbnailUri != null) { 263b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // TODO: see if this needs to be done outside the main thread 264b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin // as it may be too slow to get immediately. 2657a4e67708498ec46c2e9b3bad69d3807d88c064eScott Kennedy view.setImageURI(thumbnailUri); 266b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } else { 267b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setImageResource(getDefaultPhotoResId()); 268b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 269b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 270b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin case SINGLE_RECIPIENT: 271b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin default: 272b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin break; 273b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 274b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setVisibility(View.VISIBLE); 275b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } else { 276b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin view.setVisibility(View.GONE); 277b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 278b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 279b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 2806c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao protected void bindDrawableToDeleteView(final StateListDrawable drawable, String recipient, 2816c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao ImageView view) { 2824db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao if (view == null) { 2834db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao return; 2844db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 2854db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao if (drawable == null) { 2864db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao view.setVisibility(View.GONE); 287ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao } else { 2886c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao final Resources res = mContext.getResources(); 289ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao view.setImageDrawable(drawable); 2906c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao view.setContentDescription( 2916c3f99e2e9f0f1ada622c7ab25876b69fa82b146Jin Cao res.getString(R.string.dropdown_delete_button_desc, recipient)); 292ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao if (mDeleteListener != null) { 293ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao view.setOnClickListener(new View.OnClickListener() { 294ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao @Override 295ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao public void onClick(View view) { 296ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao if (drawable.getCurrent() != null) { 297ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao mDeleteListener.onChipDelete(); 298ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao } 2994db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 300ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao }); 301ffc0111fa742c72f2457cecc1116e4ea3c6c8c6eJin Cao } 3024db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 3034db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao } 3044db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao 305f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected void bindIndicatorToView( 306f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic @DrawableRes int indicatorIconId, String indicatorText, TextView view) { 30784f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker if (view != null) { 308f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic if (indicatorText != null || indicatorIconId != 0) { 30984f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker view.setText(indicatorText); 310f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic view.setVisibility(View.VISIBLE); 311f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic final Drawable indicatorIcon; 312f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic if (indicatorIconId != 0) { 313f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic indicatorIcon = mContext.getDrawable(indicatorIconId).mutate(); 31484f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker indicatorIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN); 31584f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } else { 316f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic indicatorIcon = null; 31784f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } 318f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic view.setCompoundDrawablesRelativeWithIntrinsicBounds( 319f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic indicatorIcon, null, null, null); 32084f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } else { 32184f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker view.setVisibility(View.GONE); 32284f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } 32384f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } 32484f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker } 32584f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker 326f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected void bindPermissionRequestDismissView(ImageView view) { 327f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic if (view == null) { 328f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic return; 329f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 330f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic view.setOnClickListener(new OnClickListener() { 331f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic @Override 332f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic public void onClick(View v) { 333f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic if (mPermissionRequestDismissedListener != null) { 334f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic mPermissionRequestDismissedListener.onPermissionRequestDismissed(); 335f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 336f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 337f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic }); 338f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 339f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 340f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected void setViewVisibility(View view, int visibility) { 341f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic if (view != null) { 342f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic view.setVisibility(visibility); 343f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 344f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 345f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 346b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin protected CharSequence getDestinationType(RecipientEntry entry) { 347b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return mQuery.getTypeLabel(mContext.getResources(), entry.getDestinationType(), 348b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin entry.getDestinationLabel()).toString().toUpperCase(); 349b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 350b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 351b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 352b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns a layout id for each item inside auto-complete list. 353b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * 354b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Each View must contain two TextViews (for display name and destination) and one ImageView 355b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * (for photo). Ids for those should be available via {@link #getDisplayNameResId()}, 356b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * {@link #getDestinationResId()}, and {@link #getPhotoResId()}. 357b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 3580d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock protected @LayoutRes int getItemLayoutResId(AdapterType type) { 3590d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock switch (type) { 3604ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao case BASE_RECIPIENT: 3614ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_autocomplete_recipient_dropdown_item; 3624ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao case RECIPIENT_ALTERNATES: 3634ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_recipient_dropdown_item; 3644ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao default: 3654ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_recipient_dropdown_item; 3664ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao } 367b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 368b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 369b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 370b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns a layout id for each item inside alternate auto-complete list. 371b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * 372b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Each View must contain two TextViews (for display name and destination) and one ImageView 373b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * (for photo). Ids for those should be available via {@link #getDisplayNameResId()}, 374b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * {@link #getDestinationResId()}, and {@link #getPhotoResId()}. 375b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 3764ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao protected @LayoutRes int getAlternateItemLayoutResId(AdapterType type) { 3774ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao switch (type) { 3784ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao case BASE_RECIPIENT: 3794ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_autocomplete_recipient_dropdown_item; 3804ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao case RECIPIENT_ALTERNATES: 3814ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_recipient_dropdown_item; 3824ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao default: 3834ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao return R.layout.chips_recipient_dropdown_item; 3844ddcdaed9ef5ea83910a0513e87538130270e2e4Jin Cao } 385b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 386b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 387b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 388b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns a resource ID representing an image which should be shown when ther's no relevant 389b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * photo is available. 390b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 3914db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @DrawableRes int getDefaultPhotoResId() { 392b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return R.drawable.ic_contact_picture; 393b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 394b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 395b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 396f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * Returns an id for the ViewGroup in an item View that contains the person ui elements. 397f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic */ 398f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected @IdRes int getPersonGroupResId() { 399f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic return R.id.chip_person_wrapper; 400f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 401f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 402f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic /** 403b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns an id for TextView in an item View for showing a display name. By default 404b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * {@link android.R.id#title} is returned. 405b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 4064db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @IdRes int getDisplayNameResId() { 407b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return android.R.id.title; 408b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 409b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 410b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 411b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns an id for TextView in an item View for showing a destination 412b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * (an email address or a phone number). 413b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * By default {@link android.R.id#text1} is returned. 414b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 4154db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @IdRes int getDestinationResId() { 416b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return android.R.id.text1; 417b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 418b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 419b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 420b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns an id for TextView in an item View for showing the type of the destination. 421b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * By default {@link android.R.id#text2} is returned. 422b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 4234db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @IdRes int getDestinationTypeResId() { 424b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return android.R.id.text2; 425b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 426b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 427b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 428b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * Returns an id for ImageView in an item View for showing photo image for a person. In default 429b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * {@link android.R.id#icon} is returned. 430b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 4314db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @IdRes int getPhotoResId() { 432b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin return android.R.id.icon; 433b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 434b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 435b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin /** 4364db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao * Returns an id for ImageView in an item View for showing the delete button. In default 4374db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao * {@link android.R.id#icon1} is returned. 4384db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao */ 4394db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao protected @IdRes int getDeleteResId() { return android.R.id.icon1; } 4404db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao 4414db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao /** 442f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * Returns an id for the ViewGroup in an item View that contains the request permission ui 443f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * elements. 444f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic */ 445f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected @IdRes int getPermissionGroupResId() { 446f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic return R.id.chip_permission_wrapper; 447f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 448f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 449f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic /** 450f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * Returns an id for ImageView in an item View for dismissing the permission request. In default 451f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic * {@link android.R.id#icon2} is returned. 452f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic */ 453f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic protected @IdRes int getPermissionRequestDismissResId() { 454f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic return android.R.id.icon2; 455f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic } 456f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 457f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic /** 458d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * Given a constraint and a recipient entry, tries to find the constraint in the name and 459d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * destination in the recipient entry. A foreground font color style will be applied to the 460d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * section that matches the constraint. As soon as a match has been found, no further matches 461d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * are attempted. 462d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * 463d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * @param constraint A string that we will attempt to find within the results. 464d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * @param entry The recipient entry to style results for. 465d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * 466d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * @return An array of CharSequences, the length determined by the length of results. Each 467d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe * CharSequence will either be a styled SpannableString or just the input String. 468d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe */ 469d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe protected CharSequence[] getStyledResults(@Nullable String constraint, RecipientEntry entry) { 470d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe return getStyledResults(constraint, entry.getDisplayName(), entry.getDestination()); 471d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe } 472d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe 473d829c9383940496eedd0ab6027efad36a0ec235cBen Brosbe /** 474e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * Given a constraint and results, tries to find the constraint in those results, one at a time. 475e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * A foreground font color style will be applied to the section that matches the constraint. As 476e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * soon as a match has been found, no further matches are attempted. 477e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * 478e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * @param constraint A string that we will attempt to find within the results. 479e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * @param results Strings that may contain the constraint. The order given is the order used to 480e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * search for the constraint. 481e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * 482e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * @return An array of CharSequences, the length determined by the length of results. Each 483e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy * CharSequence will either be a styled SpannableString or just the input String. 484e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy */ 485e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy protected CharSequence[] getStyledResults(@Nullable String constraint, String... results) { 486e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (isAllWhitespace(constraint)) { 487e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy return results; 488e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 489e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 490e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy CharSequence[] styledResults = new CharSequence[results.length]; 491e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy boolean foundMatch = false; 492e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy for (int i = 0; i < results.length; i++) { 493e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy String result = results[i]; 494e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (result == null) { 495e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy continue; 496e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 497e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 498e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (!foundMatch) { 499e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy int index = result.toLowerCase().indexOf(constraint.toLowerCase()); 500e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (index != -1) { 501e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy SpannableStringBuilder styled = SpannableStringBuilder.valueOf(result); 502e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy ForegroundColorSpan highlightSpan = 503e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy new ForegroundColorSpan(mContext.getResources().getColor( 504e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy R.color.chips_dropdown_text_highlighted)); 505e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy styled.setSpan(highlightSpan, 506e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy index, index + constraint.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 507e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy styledResults[i] = styled; 508e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy foundMatch = true; 509e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy continue; 510e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 511e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 512e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy styledResults[i] = result; 513e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 514e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy return styledResults; 515e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 516e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 517e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy private static boolean isAllWhitespace(@Nullable String string) { 518e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (TextUtils.isEmpty(string)) { 519e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy return true; 520e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 521e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 522e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy for (int i = 0; i < string.length(); ++i) { 523e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy if (!Character.isWhitespace(string.charAt(i))) { 524e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy return false; 525e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 526e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 527e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 528e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy return true; 529e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy } 530e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy 531e5d17d57be3b89a6adb7d429a4cb3cb1fbb422ffScott Kennedy /** 532b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * A holder class the view. Uses the getters in DropdownChipLayouter to find the id of the 533b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin * corresponding views. 534b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin */ 535b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin protected class ViewHolder { 5360d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock public final ViewGroup personViewGroup; 537b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public final TextView displayNameView; 538b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public final TextView destinationView; 539b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public final TextView destinationTypeView; 54084f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker public final TextView indicatorView; 541b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public final ImageView imageView; 5424db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao public final ImageView deleteView; 543b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao public final View topDivider; 5446f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy public final View bottomDivider; 545e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock public final View permissionBottomDivider; 546b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin 5470d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock public final ViewGroup permissionViewGroup; 548f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic public final ImageView permissionRequestDismissView; 549f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 550b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin public ViewHolder(View view) { 5510d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock personViewGroup = (ViewGroup) view.findViewById(getPersonGroupResId()); 552b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin displayNameView = (TextView) view.findViewById(getDisplayNameResId()); 553b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin destinationView = (TextView) view.findViewById(getDestinationResId()); 554b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin destinationTypeView = (TextView) view.findViewById(getDestinationTypeResId()); 555b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin imageView = (ImageView) view.findViewById(getPhotoResId()); 5564db8cccf3332ad7c6fb1915f9f0f169953c3953aJin Cao deleteView = (ImageView) view.findViewById(getDeleteResId()); 557b58c9a621a250c6119be2d5a77164b940a8559b0Jin Cao topDivider = view.findViewById(R.id.chip_autocomplete_top_divider); 558e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock 5596f86e3b4ab4137d43769d78abd9a45ed84e6e50dScott Kennedy bottomDivider = view.findViewById(R.id.chip_autocomplete_bottom_divider); 560e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock permissionBottomDivider = view.findViewById(R.id.chip_permission_bottom_divider); 561e78ad406f0b2ee0d031b71b33e6094a6961f7c79Greg Bullock 56284f848c6601f1759689c5318e8d01924ce2f0b2bBraden Walker indicatorView = (TextView) view.findViewById(R.id.chip_indicator_text); 563f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic 5640d4d806606fa8210ad09430fab3a230a1c4e3681Greg Bullock permissionViewGroup = (ViewGroup) view.findViewById(getPermissionGroupResId()); 565f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic permissionRequestDismissView = 566f1ad4f6dba7c6ea28f529736b8662faa6fb498f8Milos Stankovic (ImageView) view.findViewById(getPermissionRequestDismissResId()); 567b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 568b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin } 569b10d1c652d0416c284d9792fc9a0a92b3acd51caKevin Lin} 570