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.list; 17 18import android.content.Context; 19import android.graphics.Rect; 20import android.net.Uri; 21import android.util.AttributeSet; 22import android.util.Log; 23import android.view.View; 24import android.widget.FrameLayout; 25import android.widget.ImageView; 26import android.widget.QuickContactBadge; 27import android.widget.TextView; 28 29import com.android.contacts.ContactPhotoManager; 30import com.android.contacts.ContactsUtils; 31import com.android.contacts.R; 32import com.android.contacts.list.ContactTileAdapter.ContactEntry; 33 34/** 35 * A ContactTile displays a contact's picture and name 36 */ 37public abstract class ContactTileView extends FrameLayout { 38 private final static String TAG = ContactTileView.class.getSimpleName(); 39 40 private Uri mLookupUri; 41 private ImageView mPhoto; 42 private QuickContactBadge mQuickContact; 43 private TextView mName; 44 private TextView mStatus; 45 private TextView mPhoneLabel; 46 private TextView mPhoneNumber; 47 private ContactPhotoManager mPhotoManager = null; 48 private View mPushState; 49 private View mHorizontalDivider; 50 protected Listener mListener; 51 52 public ContactTileView(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 } 55 56 @Override 57 protected void onFinishInflate() { 58 super.onFinishInflate(); 59 mName = (TextView) findViewById(R.id.contact_tile_name); 60 61 mQuickContact = (QuickContactBadge) findViewById(R.id.contact_tile_quick); 62 mPhoto = (ImageView) findViewById(R.id.contact_tile_image); 63 mStatus = (TextView) findViewById(R.id.contact_tile_status); 64 mPhoneLabel = (TextView) findViewById(R.id.contact_tile_phone_type); 65 mPhoneNumber = (TextView) findViewById(R.id.contact_tile_phone_number); 66 mPushState = findViewById(R.id.contact_tile_push_state); 67 mHorizontalDivider = findViewById(R.id.contact_tile_horizontal_divider); 68 69 OnClickListener listener = createClickListener(); 70 71 if(mPushState != null) { 72 mPushState.setOnClickListener(listener); 73 } else { 74 setOnClickListener(listener); 75 } 76 } 77 78 protected OnClickListener createClickListener() { 79 return new OnClickListener() { 80 @Override 81 public void onClick(View v) { 82 if (mListener == null) return; 83 mListener.onContactSelected( 84 getLookupUri(), 85 ContactsUtils.getTargetRectFromView(mContext, ContactTileView.this)); 86 } 87 }; 88 } 89 90 public void setPhotoManager(ContactPhotoManager photoManager) { 91 mPhotoManager = photoManager; 92 } 93 94 /** 95 * Populates the data members to be displayed from the 96 * fields in {@link ContactEntry} 97 */ 98 public void loadFromContact(ContactEntry entry) { 99 100 if (entry != null) { 101 mName.setText(entry.name); 102 mLookupUri = entry.lookupKey; 103 104 if (mStatus != null) { 105 if (entry.status == null) { 106 mStatus.setVisibility(View.GONE); 107 } else { 108 mStatus.setText(entry.status); 109 mStatus.setCompoundDrawablesWithIntrinsicBounds(entry.presenceIcon, 110 null, null, null); 111 mStatus.setVisibility(View.VISIBLE); 112 } 113 } 114 115 if (mPhoneLabel != null) { 116 mPhoneLabel.setText(entry.phoneLabel); 117 } 118 119 if (mPhoneNumber != null) { 120 // TODO: Format number correctly 121 mPhoneNumber.setText(entry.phoneNumber); 122 } 123 124 setVisibility(View.VISIBLE); 125 126 if (mPhotoManager != null) { 127 if (mPhoto != null) { 128 mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(), 129 isDarkTheme()); 130 131 if (mQuickContact != null) { 132 mQuickContact.assignContactUri(mLookupUri); 133 } 134 } else if (mQuickContact != null) { 135 mQuickContact.assignContactUri(mLookupUri); 136 mPhotoManager.loadPhoto(mQuickContact, entry.photoUri, 137 getApproximateImageSize(), isDarkTheme()); 138 } 139 } else { 140 Log.w(TAG, "contactPhotoManager not set"); 141 } 142 143 if (mPushState != null) { 144 mPushState.setContentDescription(entry.name); 145 } else if (mQuickContact != null) { 146 mQuickContact.setContentDescription(entry.name); 147 } 148 } else { 149 setVisibility(View.INVISIBLE); 150 } 151 } 152 153 public void setListener(Listener listener) { 154 mListener = listener; 155 } 156 157 public void setHorizontalDividerVisibility(int visibility) { 158 if (mHorizontalDivider != null) mHorizontalDivider.setVisibility(visibility); 159 } 160 161 public Uri getLookupUri() { 162 return mLookupUri; 163 } 164 165 protected QuickContactBadge getQuickContact() { 166 return mQuickContact; 167 } 168 169 /** 170 * Implemented by subclasses to estimate the size of the picture. This can return -1 if only 171 * a thumbnail is shown anyway 172 */ 173 protected abstract int getApproximateImageSize(); 174 175 protected abstract boolean isDarkTheme(); 176 177 public interface Listener { 178 /** 179 * Notification that the contact was selected; no specific action is dictated. 180 */ 181 void onContactSelected(Uri contactLookupUri, Rect viewRect); 182 /** 183 * Notification that the specified number is to be called. 184 */ 185 void onCallNumberDirectly(String phoneNumber); 186 /** 187 * @return The width of each tile. This doesn't have to be a precise number (e.g. paddings 188 * can be ignored), but is used to load the correct picture size from the database 189 */ 190 int getApproximateTileWidth(); 191 } 192} 193