1/* 2 * Copyright (C) 2011 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 */ 16package com.android.contacts.common.list; 17 18import android.content.Context; 19import android.graphics.Rect; 20import android.net.Uri; 21import android.util.AttributeSet; 22import android.view.View; 23import android.widget.FrameLayout; 24import android.widget.ImageView; 25import android.widget.TextView; 26import com.android.contacts.common.ContactPhotoManager; 27import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; 28import com.android.contacts.common.MoreContactUtils; 29import com.android.contacts.common.R; 30import com.android.dialer.callintent.CallInitiationType; 31import com.android.dialer.callintent.CallSpecificAppData; 32import com.android.dialer.common.LogUtil; 33 34/** A ContactTile displays a contact's picture and name */ 35public abstract class ContactTileView extends FrameLayout { 36 37 private static final String TAG = ContactTileView.class.getSimpleName(); 38 protected Listener mListener; 39 private Uri mLookupUri; 40 private ImageView mPhoto; 41 private TextView mName; 42 private ContactPhotoManager mPhotoManager = null; 43 44 public ContactTileView(Context context, AttributeSet attrs) { 45 super(context, attrs); 46 } 47 48 @Override 49 protected void onFinishInflate() { 50 super.onFinishInflate(); 51 mName = (TextView) findViewById(R.id.contact_tile_name); 52 mPhoto = (ImageView) findViewById(R.id.contact_tile_image); 53 54 OnClickListener listener = createClickListener(); 55 setOnClickListener(listener); 56 } 57 58 protected OnClickListener createClickListener() { 59 return new OnClickListener() { 60 @Override 61 public void onClick(View v) { 62 if (mListener == null) { 63 return; 64 } 65 CallSpecificAppData callSpecificAppData = 66 CallSpecificAppData.newBuilder() 67 .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL) 68 .build(); 69 mListener.onContactSelected( 70 getLookupUri(), 71 MoreContactUtils.getTargetRectFromView(ContactTileView.this), 72 callSpecificAppData); 73 } 74 }; 75 } 76 77 public void setPhotoManager(ContactPhotoManager photoManager) { 78 mPhotoManager = photoManager; 79 } 80 81 /** 82 * Populates the data members to be displayed from the fields in {@link 83 * com.android.contacts.common.list.ContactEntry} 84 */ 85 public void loadFromContact(ContactEntry entry) { 86 87 if (entry != null) { 88 mName.setText(getNameForView(entry)); 89 mLookupUri = entry.lookupUri; 90 91 setVisibility(View.VISIBLE); 92 93 if (mPhotoManager != null) { 94 DefaultImageRequest request = getDefaultImageRequest(entry.namePrimary, entry.lookupKey); 95 configureViewForImage(entry.photoUri == null); 96 if (mPhoto != null) { 97 mPhotoManager.loadPhoto( 98 mPhoto, 99 entry.photoUri, 100 getApproximateImageSize(), 101 isDarkTheme(), 102 isContactPhotoCircular(), 103 request); 104 105 106 } 107 } else { 108 LogUtil.w(TAG, "contactPhotoManager not set"); 109 } 110 } else { 111 setVisibility(View.INVISIBLE); 112 } 113 } 114 115 public void setListener(Listener listener) { 116 mListener = listener; 117 } 118 119 public Uri getLookupUri() { 120 return mLookupUri; 121 } 122 123 /** 124 * Returns the string that should actually be displayed as the contact's name. Subclasses can 125 * override this to return formatted versions of the name - i.e. first name only. 126 */ 127 protected String getNameForView(ContactEntry contactEntry) { 128 return contactEntry.namePrimary; 129 } 130 131 /** 132 * Implemented by subclasses to estimate the size of the picture. This can return -1 if only a 133 * thumbnail is shown anyway 134 */ 135 protected abstract int getApproximateImageSize(); 136 137 protected abstract boolean isDarkTheme(); 138 139 /** 140 * Implemented by subclasses to reconfigure the view's layout and subviews, based on whether or 141 * not the contact has a user-defined photo. 142 * 143 * @param isDefaultImage True if the contact does not have a user-defined contact photo (which 144 * means a default contact image will be applied by the {@link ContactPhotoManager} 145 */ 146 protected void configureViewForImage(boolean isDefaultImage) { 147 // No-op by default. 148 } 149 150 /** 151 * Implemented by subclasses to allow them to return a {@link DefaultImageRequest} with the 152 * various image parameters defined to match their own layouts. 153 * 154 * @param displayName The display name of the contact 155 * @param lookupKey The lookup key of the contact 156 * @return A {@link DefaultImageRequest} object with each field configured by the subclass as 157 * desired, or {@code null}. 158 */ 159 protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) { 160 return new DefaultImageRequest(displayName, lookupKey, isContactPhotoCircular()); 161 } 162 163 /** 164 * Whether contact photo should be displayed as a circular image. Implemented by subclasses so 165 * they can change which drawables to fetch. 166 */ 167 protected boolean isContactPhotoCircular() { 168 return true; 169 } 170 171 public interface Listener { 172 173 /** Notification that the contact was selected; no specific action is dictated. */ 174 void onContactSelected( 175 Uri contactLookupUri, Rect viewRect, CallSpecificAppData callSpecificAppData); 176 177 /** Notification that the specified number is to be called. */ 178 void onCallNumberDirectly(String phoneNumber, CallSpecificAppData callSpecificAppData); 179 } 180} 181