Home | History | Annotate | Download | only in list
      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  */
     16 package com.android.contacts.common.list;
     17 
     18 import android.content.Context;
     19 import android.graphics.Rect;
     20 import android.net.Uri;
     21 import android.text.TextUtils;
     22 import android.util.AttributeSet;
     23 import android.util.Log;
     24 import android.view.View;
     25 import android.widget.FrameLayout;
     26 import android.widget.ImageView;
     27 import android.widget.QuickContactBadge;
     28 import android.widget.TextView;
     29 
     30 import com.android.contacts.common.ContactPhotoManager;
     31 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
     32 import com.android.contacts.common.MoreContactUtils;
     33 import com.android.contacts.common.R;
     34 
     35 /**
     36  * A ContactTile displays a contact's picture and name
     37  */
     38 public 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();
     71         setOnClickListener(listener);
     72     }
     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(),
     81                         MoreContactUtils.getTargetRectFromView(ContactTileView.this));
     82             }
     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
     92      * fields in {@link com.android.contacts.common.list.ContactEntry}
     93      */
     94     public void loadFromContact(ContactEntry entry) {
     95 
     96         if (entry != null) {
     97             mName.setText(getNameForView(entry));
     98             mLookupUri = entry.lookupUri;
     99 
    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) {
    112                 if (TextUtils.isEmpty(entry.phoneLabel)) {
    113                     mPhoneLabel.setVisibility(View.GONE);
    114                 } else {
    115                     mPhoneLabel.setVisibility(View.VISIBLE);
    116                     mPhoneLabel.setText(entry.phoneLabel);
    117                 }
    118             }
    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) {
    128                 DefaultImageRequest request = getDefaultImageRequest(entry.namePrimary,
    129                         entry.lookupKey);
    130                 configureViewForImage(entry.photoUri == null);
    131                 if (mPhoto != null) {
    132                     mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(),
    133                             isDarkTheme(), isContactPhotoCircular(), request);
    134 
    135                     if (mQuickContact != null) {
    136                         mQuickContact.assignContactUri(mLookupUri);
    137                     }
    138                 } else if (mQuickContact != null) {
    139                     mQuickContact.assignContactUri(mLookupUri);
    140                     mPhotoManager.loadPhoto(mQuickContact, entry.photoUri,
    141                             getApproximateImageSize(), isDarkTheme(), isContactPhotoCircular(),
    142                             request);
    143                 }
    144             } else {
    145                 Log.w(TAG, "contactPhotoManager not set");
    146             }
    147 
    148             if (mPushState != null) {
    149                 mPushState.setContentDescription(entry.namePrimary);
    150             } else if (mQuickContact != null) {
    151                 mQuickContact.setContentDescription(entry.namePrimary);
    152             }
    153         } else {
    154             setVisibility(View.INVISIBLE);
    155         }
    156     }
    157 
    158     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 
    174     protected View getPhotoView() {
    175         return mPhoto;
    176     }
    177 
    178     /**
    179      * 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      */
    182     protected String getNameForView(ContactEntry contactEntry) {
    183         return contactEntry.namePrimary;
    184     }
    185 
    186     /**
    187      * 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 
    194     /**
    195      * 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     /**
    206      * 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) {
    215         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;
    224     }
    225 
    226     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 }
    242