1 /* 2 * Copyright (C) 2017 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 17 package com.android.car.dialer; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.graphics.BitmapFactory; 23 import android.net.Uri; 24 import android.support.annotation.Nullable; 25 import android.support.v7.widget.RecyclerView; 26 import android.view.View; 27 import android.widget.ImageView; 28 import android.widget.TextView; 29 30 import com.android.car.apps.common.CircleBitmapDrawable; 31 import com.android.car.apps.common.LetterTileDrawable; 32 33 import java.io.FileNotFoundException; 34 import java.io.InputStream; 35 36 /** 37 * A {@link android.support.v7.widget.RecyclerView.ViewHolder} that will parse relevant 38 * views out of a {@code contact_result} layout. 39 */ 40 public class ContactResultViewHolder extends RecyclerView.ViewHolder { 41 private final Context mContext; 42 private final View mContactCard; 43 private final TextView mContactName; 44 private final ImageView mContactPicture; 45 ContactResultViewHolder(View view)46 public ContactResultViewHolder(View view) { 47 super(view); 48 mContext = view.getContext(); 49 mContactCard = view.findViewById(R.id.contact_result_card); 50 mContactName = view.findViewById(R.id.contact_name); 51 mContactPicture = view.findViewById(R.id.contact_picture); 52 } 53 54 /** 55 * Populates the view that is represented by this ViewHolder with the information in the 56 * provided {@link ContactDetails}. 57 */ bind(ContactDetails details, int itemCount)58 public void bind(ContactDetails details, int itemCount) { 59 updateBackground(itemCount); 60 61 mContactCard.setOnClickListener(v -> { 62 Intent intent = new Intent(); 63 intent.setAction(TelecomIntents.ACTION_SHOW_CONTACT_DETAILS); 64 intent.putExtra(TelecomIntents.CONTACT_LOOKUP_URI_EXTRA, details.lookupUri.toString()); 65 mContext.startActivity(intent); 66 }); 67 68 mContactName.setText(details.displayName); 69 70 if (details.photoUri == null) { 71 setLetterDrawableForContact(details); 72 return; 73 } 74 75 Bitmap bitmap = getContactBitmapFromUri(mContext, details.photoUri); 76 if (bitmap == null) { 77 setLetterDrawableForContact(details); 78 } else { 79 mContactPicture.setScaleType(ImageView.ScaleType.CENTER_CROP); 80 mContactPicture.setImageDrawable( 81 new CircleBitmapDrawable(mContext.getResources(), bitmap)); 82 } 83 } 84 85 /** 86 * Sets the contact picture to be a rounded, colored circle that has the first letter of the 87 * contact's name in it. 88 */ setLetterDrawableForContact(ContactDetails details)89 private void setLetterDrawableForContact(ContactDetails details) { 90 mContactPicture.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 91 LetterTileDrawable letterTileDrawable = new LetterTileDrawable(mContext.getResources()); 92 letterTileDrawable.setContactDetails(details.displayName, details.displayName); 93 letterTileDrawable.setIsCircular(true); 94 mContactPicture.setImageDrawable(letterTileDrawable); 95 } 96 97 /** 98 * Sets the appropriate background on the card containing the preset information. The cards 99 * need to have rounded corners depending on its position in the list and the number of items 100 * in the list. 101 */ updateBackground(int itemCount)102 private void updateBackground(int itemCount) { 103 int position = getAdapterPosition(); 104 105 // Correctly set the background for each card. Only the top and last card should 106 // have rounded corners. 107 if (itemCount == 1) { 108 // One card - all corners are rounded 109 mContactCard.setBackgroundResource( 110 R.drawable.car_card_rounded_top_bottom_background); 111 } else if (position == 0) { 112 // First card gets rounded top 113 mContactCard.setBackgroundResource(R.drawable.car_card_rounded_top_background); 114 } else if (position == itemCount - 1) { 115 // Last one has a rounded bottom 116 mContactCard.setBackgroundResource(R.drawable.car_card_rounded_bottom_background); 117 } else { 118 // Middle has no rounded corners 119 mContactCard.setBackgroundResource(R.color.car_card); 120 } 121 } 122 123 /** 124 * Retrieves the picture that is specified by the given {@link Uri}. 125 */ 126 @Nullable getContactBitmapFromUri(Context context, Uri uri)127 private static Bitmap getContactBitmapFromUri(Context context, Uri uri) { 128 try { 129 InputStream input = context.getContentResolver().openInputStream(uri); 130 return input == null ? null : BitmapFactory.decodeStream(input); 131 } catch (FileNotFoundException e) { 132 return null; 133 } 134 } 135 136 /** 137 * A struct that holds the details for a contact row. 138 */ 139 public static class ContactDetails { 140 public final String displayName; 141 public final Uri photoUri; 142 public final Uri lookupUri; 143 ContactDetails(String displayName, String photoUri, Uri lookupUri)144 public ContactDetails(String displayName, String photoUri, Uri lookupUri) { 145 this.displayName = displayName; 146 this.photoUri = photoUri == null ? null : Uri.parse(photoUri); 147 this.lookupUri = lookupUri; 148 } 149 } 150 } 151