blob: 172d720626e120e1d6823cdce452ca2946df1ba6 [file] [log] [blame]
Chiao Cheng87a36dc2012-11-07 18:20:17 -08001/*
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;
Yorke Lee54722682013-09-24 15:57:02 -070021import android.text.TextUtils;
Chiao Cheng87a36dc2012-11-07 18:20:17 -080022import android.util.AttributeSet;
23import android.util.Log;
24import android.view.View;
25import android.widget.FrameLayout;
26import android.widget.ImageView;
27import android.widget.QuickContactBadge;
28import android.widget.TextView;
29
30import com.android.contacts.common.ContactPhotoManager;
Yorke Lee9df5e192014-02-12 14:58:25 -080031import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
Chiao Cheng87a36dc2012-11-07 18:20:17 -080032import com.android.contacts.common.MoreContactUtils;
33import com.android.contacts.common.R;
34
35/**
36 * A ContactTile displays a contact's picture and name
37 */
38public abstract class ContactTileView extends FrameLayout {
39 private final static String TAG = ContactTileView.class.getSimpleName();
40
41 private Uri mLookupUri;
42 private ImageView mPhoto;
43 private QuickContactBadge mQuickContact;
44 private TextView mName;
45 private TextView mStatus;
46 private TextView mPhoneLabel;
47 private TextView mPhoneNumber;
48 private ContactPhotoManager mPhotoManager = null;
49 private View mPushState;
50 private View mHorizontalDivider;
51 protected Listener mListener;
52
53 public ContactTileView(Context context, AttributeSet attrs) {
54 super(context, attrs);
55 }
56
57 @Override
58 protected void onFinishInflate() {
59 super.onFinishInflate();
60 mName = (TextView) findViewById(R.id.contact_tile_name);
61
62 mQuickContact = (QuickContactBadge) findViewById(R.id.contact_tile_quick);
63 mPhoto = (ImageView) findViewById(R.id.contact_tile_image);
64 mStatus = (TextView) findViewById(R.id.contact_tile_status);
65 mPhoneLabel = (TextView) findViewById(R.id.contact_tile_phone_type);
66 mPhoneNumber = (TextView) findViewById(R.id.contact_tile_phone_number);
67 mPushState = findViewById(R.id.contact_tile_push_state);
68 mHorizontalDivider = findViewById(R.id.contact_tile_horizontal_divider);
69
70 OnClickListener listener = createClickListener();
Christine Chen152ad492013-07-17 13:57:14 -070071 setOnClickListener(listener);
Chiao Cheng87a36dc2012-11-07 18:20:17 -080072 }
73
74 protected OnClickListener createClickListener() {
75 return new OnClickListener() {
76 @Override
77 public void onClick(View v) {
78 if (mListener == null) return;
79 mListener.onContactSelected(
80 getLookupUri(),
Yorke Lee22426f92013-10-24 13:53:24 -070081 MoreContactUtils.getTargetRectFromView(ContactTileView.this));
Chiao Cheng87a36dc2012-11-07 18:20:17 -080082 }
83 };
84 }
85
86 public void setPhotoManager(ContactPhotoManager photoManager) {
87 mPhotoManager = photoManager;
88 }
89
90 /**
91 * Populates the data members to be displayed from the
Yorke Leef08f2d42013-07-12 16:11:56 -070092 * fields in {@link com.android.contacts.common.list.ContactEntry}
Chiao Cheng87a36dc2012-11-07 18:20:17 -080093 */
Yorke Leef08f2d42013-07-12 16:11:56 -070094 public void loadFromContact(ContactEntry entry) {
Chiao Cheng87a36dc2012-11-07 18:20:17 -080095
96 if (entry != null) {
Brandon Maxwellff1be302015-10-28 15:33:43 -070097 mName.setText(getNameForView(entry));
Yorke Lee9df5e192014-02-12 14:58:25 -080098 mLookupUri = entry.lookupUri;
Chiao Cheng87a36dc2012-11-07 18:20:17 -080099
100 if (mStatus != null) {
101 if (entry.status == null) {
102 mStatus.setVisibility(View.GONE);
103 } else {
104 mStatus.setText(entry.status);
105 mStatus.setCompoundDrawablesWithIntrinsicBounds(entry.presenceIcon,
106 null, null, null);
107 mStatus.setVisibility(View.VISIBLE);
108 }
109 }
110
111 if (mPhoneLabel != null) {
Yorke Lee54722682013-09-24 15:57:02 -0700112 if (TextUtils.isEmpty(entry.phoneLabel)) {
113 mPhoneLabel.setVisibility(View.GONE);
114 } else {
115 mPhoneLabel.setVisibility(View.VISIBLE);
116 mPhoneLabel.setText(entry.phoneLabel);
117 }
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800118 }
119
120 if (mPhoneNumber != null) {
121 // TODO: Format number correctly
122 mPhoneNumber.setText(entry.phoneNumber);
123 }
124
125 setVisibility(View.VISIBLE);
126
127 if (mPhotoManager != null) {
Brandon Maxwellff1be302015-10-28 15:33:43 -0700128 DefaultImageRequest request = getDefaultImageRequest(entry.namePrimary,
129 entry.lookupKey);
Yorke Lee7052b7a2014-02-28 17:21:48 -0800130 configureViewForImage(entry.photoUri == null);
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800131 if (mPhoto != null) {
132 mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(),
Brian Attwell2a865f92014-06-11 18:36:07 -0700133 isDarkTheme(), isContactPhotoCircular(), request);
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800134
135 if (mQuickContact != null) {
136 mQuickContact.assignContactUri(mLookupUri);
137 }
138 } else if (mQuickContact != null) {
139 mQuickContact.assignContactUri(mLookupUri);
140 mPhotoManager.loadPhoto(mQuickContact, entry.photoUri,
Brian Attwell2a865f92014-06-11 18:36:07 -0700141 getApproximateImageSize(), isDarkTheme(), isContactPhotoCircular(),
Yorke Leec4a2a232014-04-28 17:53:42 -0700142 request);
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800143 }
144 } else {
145 Log.w(TAG, "contactPhotoManager not set");
146 }
147
148 if (mPushState != null) {
Brandon Maxwellff1be302015-10-28 15:33:43 -0700149 mPushState.setContentDescription(entry.namePrimary);
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800150 } else if (mQuickContact != null) {
Brandon Maxwellff1be302015-10-28 15:33:43 -0700151 mQuickContact.setContentDescription(entry.namePrimary);
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800152 }
153 } else {
154 setVisibility(View.INVISIBLE);
155 }
156 }
157
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800158 public void setListener(Listener listener) {
159 mListener = listener;
160 }
161
162 public void setHorizontalDividerVisibility(int visibility) {
163 if (mHorizontalDivider != null) mHorizontalDivider.setVisibility(visibility);
164 }
165
166 public Uri getLookupUri() {
167 return mLookupUri;
168 }
169
170 protected QuickContactBadge getQuickContact() {
171 return mQuickContact;
172 }
173
Brian Attwellefd210a2014-05-29 13:45:56 -0700174 protected View getPhotoView() {
175 return mPhoto;
176 }
177
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800178 /**
Yorke Leeb36c11f2013-08-30 11:00:14 -0700179 * Returns the string that should actually be displayed as the contact's name. Subclasses
180 * can override this to return formatted versions of the name - i.e. first name only.
181 */
Brandon Maxwellff1be302015-10-28 15:33:43 -0700182 protected String getNameForView(ContactEntry contactEntry) {
183 return contactEntry.namePrimary;
Yorke Leeb36c11f2013-08-30 11:00:14 -0700184 }
185
186 /**
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800187 * Implemented by subclasses to estimate the size of the picture. This can return -1 if only
188 * a thumbnail is shown anyway
189 */
190 protected abstract int getApproximateImageSize();
191
192 protected abstract boolean isDarkTheme();
193
Yorke Lee9df5e192014-02-12 14:58:25 -0800194 /**
Yorke Lee7052b7a2014-02-28 17:21:48 -0800195 * Implemented by subclasses to reconfigure the view's layout and subviews, based on whether
196 * or not the contact has a user-defined photo.
197 *
198 * @param isDefaultImage True if the contact does not have a user-defined contact photo
199 * (which means a default contact image will be applied by the {@link ContactPhotoManager}
200 */
201 protected void configureViewForImage(boolean isDefaultImage) {
202 // No-op by default.
203 }
204
205 /**
Yorke Lee9df5e192014-02-12 14:58:25 -0800206 * Implemented by subclasses to allow them to return a {@link DefaultImageRequest} with the
207 * various image parameters defined to match their own layouts.
208 *
209 * @param displayName The display name of the contact
210 * @param lookupKey The lookup key of the contact
211 * @return A {@link DefaultImageRequest} object with each field configured by the subclass
212 * as desired, or {@code null}.
213 */
214 protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
Brian Attwell2a865f92014-06-11 18:36:07 -0700215 return new DefaultImageRequest(displayName, lookupKey, isContactPhotoCircular());
216 }
217
218 /**
219 * Whether contact photo should be displayed as a circular image. Implemented by subclasses
220 * so they can change which drawables to fetch.
221 */
222 protected boolean isContactPhotoCircular() {
223 return true;
Yorke Lee9df5e192014-02-12 14:58:25 -0800224 }
225
Chiao Cheng87a36dc2012-11-07 18:20:17 -0800226 public interface Listener {
227 /**
228 * Notification that the contact was selected; no specific action is dictated.
229 */
230 void onContactSelected(Uri contactLookupUri, Rect viewRect);
231 /**
232 * Notification that the specified number is to be called.
233 */
234 void onCallNumberDirectly(String phoneNumber);
235 /**
236 * @return The width of each tile. This doesn't have to be a precise number (e.g. paddings
237 * can be ignored), but is used to load the correct picture size from the database
238 */
239 int getApproximateTileWidth();
240 }
241}