OSDN Git Service

Add the FasttrackBadgeWidget.
authorEvan Millar <emillar@google.com>
Thu, 27 Aug 2009 18:15:55 +0000 (11:15 -0700)
committerEvan Millar <emillar@google.com>
Tue, 15 Sep 2009 20:00:49 +0000 (13:00 -0700)
This widget is an extension of ImageView that takes care of the standard
fasttrack badging and on-click behavior. It should be used in any
applications that display contact photos.

This view's name will have to be changed before release, and will be
kept private until the name change is made. At that point the view will
be made public api.

Change-Id: I4704e0e979466929ad7b2ef11911681a5028b4a7

core/java/android/widget/FasttrackBadgeWidget.java [new file with mode: 0644]
core/res/res/drawable/fasttrack_badge_middle_large.xml [moved from core/res/res/drawable/fasttrack_badge_middle.xml with 84% similarity]
core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png [new file with mode: 0644]
core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png [new file with mode: 0644]
core/res/res/drawable/fasttrack_badge_middle_normal.9.png [deleted file]
core/res/res/drawable/fasttrack_badge_middle_pressed.9.png [deleted file]
core/res/res/layout/contact_header.xml
core/res/res/values/attrs.xml
core/res/res/values/styles.xml
core/res/res/values/themes.xml

diff --git a/core/java/android/widget/FasttrackBadgeWidget.java b/core/java/android/widget/FasttrackBadgeWidget.java
new file mode 100644 (file)
index 0000000..22ca5fd
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.database.Cursor;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Intents;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+/**
+ * Widget used to show an image with the standard fasttrack badge
+ * and on-click behavior.
+ *
+ * @hide
+ */
+public class FasttrackBadgeWidget extends ImageView implements OnClickListener {
+
+    private Uri mContactUri;
+    private String mContactEmail;
+    private String mContactPhone;
+    private int mMode;
+    private QueryHandler mQueryHandler;
+
+    protected String[] mExcludeMimes = null;
+
+    static final private int TOKEN_EMAIL_LOOKUP = 0;
+    static final private int TOKEN_PHONE_LOOKUP = 1;
+    static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;
+    static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;
+
+    static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
+        RawContacts.CONTACT_ID,
+        Contacts.LOOKUP_KEY,
+    };
+    static int EMAIL_ID_COLUMN_INDEX = 0;
+    static int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;
+
+    static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
+        PhoneLookup._ID,
+        PhoneLookup.LOOKUP_KEY,
+    };
+    static int PHONE_ID_COLUMN_INDEX = 0;
+    static int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;
+
+
+
+    public FasttrackBadgeWidget(Context context) {
+        this(context, null);
+    }
+
+    public FasttrackBadgeWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public FasttrackBadgeWidget(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a =
+            context.obtainStyledAttributes(attrs,
+                    com.android.internal.R.styleable.FasttrackBadgeWidget, defStyle, 0);
+
+        mMode = a.getInt(com.android.internal.R.styleable.FasttrackBadgeWidget_fasttrackWindowSize,
+                Intents.MODE_MEDIUM);
+
+        a.recycle();
+
+        init();
+    }
+
+    private void init() {
+        mQueryHandler = new QueryHandler(mContext.getContentResolver());
+        setOnClickListener(this);
+    }
+
+    /**
+     * Assign the contact uri that this fasttrack badge should be associated with.
+     * Note that this is only used for displaying the fasttrack window and won't
+     * bind the contact's photo for you.
+     *
+     * @param conatctUri Either a {Contacts.CONTENT_URI} or {Contacts.CONTENT_LOOKUP_URI}
+     * style URI.
+     */
+    public void assignContactUri(Uri contactUri) {
+        mContactUri = contactUri;
+    }
+
+    /**
+     * Assign a contact based on an email address. This should only be used when
+     * the contact's URI is not available, as an extra query will have to be
+     * performed to lookup the URI based on the email.
+     *
+     * @param emailAddress The email address of the contact.
+     * @param lazyLookup If this is true, the lookup query will not be performed
+     * until this view is clicked.
+     */
+    public void assignContactFromEmail(String emailAddress, boolean lazyLookup) {
+        mContactEmail = emailAddress;
+        if (!lazyLookup) {
+            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,
+                    Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
+                    EMAIL_LOOKUP_PROJECTION, null, null, null);
+        }
+    }
+
+    /**
+     * Assign a contact based on a phone number. This should only be used when
+     * the contact's URI is not available, as an extra query will have to be
+     * performed to lookup the URI based on the phone number.
+     *
+     * @param phoneNumber The phone number of the contact.
+     * @param lazyLookup If this is true, the lookup query will not be performed
+     * until this view is clicked.
+     */
+    public void assignContactFromPhone(String phoneNumber, boolean lazyLookup) {
+        mContactPhone = phoneNumber;
+        if (!lazyLookup) {
+            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,
+                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
+                    PHONE_LOOKUP_PROJECTION, null, null, null);
+        }
+    }
+
+    /**
+     * Set the fasttrack window mode. Options are {@link Intents.MODE_SMALL},
+     * {@link Intents.MODE_MEDIUM}, {@link Intents.MODE_LARGE}.
+     * @param size
+     */
+    public void setMode(int size) {
+        mMode = size;
+    }
+
+    public void onClick(View v) {
+        final Rect target = getTargetRect(v);
+
+        if (mContactUri != null) {
+            trigger(mContactUri, target);
+        } else if (mContactEmail != null) {
+            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, target,
+                    Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
+                    EMAIL_LOOKUP_PROJECTION, null, null, null);
+        } else if (mContactPhone != null) {
+            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, target,
+                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
+                    PHONE_LOOKUP_PROJECTION, null, null, null);
+        } else {
+            // If a contact hasn't been assigned, don't react to click.
+            return;
+        }
+    }
+
+    /**
+     * Set a list of specific MIME-types to exclude and not display. For
+     * example, this can be used to hide the {@link Contacts#CONTENT_ITEM_TYPE}
+     * profile icon.
+     */
+    public void setExcludeMimes(String[] excludeMimes) {
+        mExcludeMimes = excludeMimes;
+    }
+
+    private void trigger(Uri contactUri, Rect target) {
+        Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, contactUri);
+        intent.putExtra(Intents.EXTRA_TARGET_RECT, target);
+        intent.putExtra(Intents.EXTRA_MODE, mMode);
+        mContext.startActivity(intent);
+    }
+
+    private Rect getTargetRect(View anchor) {
+        final int[] location = new int[2];
+        anchor.getLocationOnScreen(location);
+
+        final Rect rect = new Rect();
+        rect.left = location[0];
+        rect.top = location[1];
+        rect.right = rect.left + anchor.getWidth();
+        rect.bottom = rect.top + anchor.getHeight();
+        return rect;
+    }
+
+    private class QueryHandler extends AsyncQueryHandler {
+
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            Uri contactUri = null;
+            boolean trigger = false;
+
+            try{
+                switch(token) {
+                    case TOKEN_PHONE_LOOKUP_AND_TRIGGER:
+                        trigger = true;
+                    case TOKEN_PHONE_LOOKUP: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
+                            String lookupKey = cursor.getString(PHONE_LOOKUP_STRING_COLUMN_INDEX);
+                            contactUri = Contacts.getLookupUri(contactId, lookupKey);
+                        }
+                        break;
+                    }
+                    case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:
+                        trigger = true;
+                    case TOKEN_EMAIL_LOOKUP: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
+                            String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
+                            contactUri = Contacts.getLookupUri(contactId, lookupKey);
+                        }
+                    }
+                }
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+
+            if (contactUri != null) {
+                mContactUri = contactUri;
+                if (trigger && cookie != null) {
+                    trigger(contactUri, (Rect) cookie);
+                }
+            }
+        }
+    }
+}
         android:state_focused="false"
         android:state_selected="false"
         android:state_pressed="false"
-        android:drawable="@drawable/fasttrack_badge_middle_normal" />
+        android:drawable="@drawable/fasttrack_badge_middle_large_normal" />
 
     <item
         android:state_pressed="true"
-        android:drawable="@drawable/fasttrack_badge_middle_pressed" />
+        android:drawable="@drawable/fasttrack_badge_middle_large_pressed" />
 
 </selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png b/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png
new file mode 100644 (file)
index 0000000..ca275cd
Binary files /dev/null and b/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png b/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png
new file mode 100644 (file)
index 0000000..b69ccbd
Binary files /dev/null and b/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_normal.9.png b/core/res/res/drawable/fasttrack_badge_middle_normal.9.png
deleted file mode 100644 (file)
index 07df063..0000000
Binary files a/core/res/res/drawable/fasttrack_badge_middle_normal.9.png and /dev/null differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png b/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png
deleted file mode 100644 (file)
index ded95f6..0000000
Binary files a/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png and /dev/null differ
index ba91e00..8d7e470 100644 (file)
     android:gravity="center_vertical">
     
     <ImageView android:id="@+id/photo"
-        android:layout_width="48dip"
-        android:layout_height="52dip"
+        android:layout_width="56dip"
+        android:layout_height="62dip"
         android:layout_marginRight="10dip"
         android:layout_marginLeft="10dip"
         android:scaleType="fitCenter"
-        android:background="@drawable/fasttrack_badge_middle"/>
+        android:background="@drawable/fasttrack_badge_middle_large"/>
     
     <LinearLayout
         android:layout_width="0dip"
index 568ed92..a1a179b 100644 (file)
         <attr name="spinnerItemStyle" format="reference" />
         <!-- Default MapView style. -->
         <attr name="mapViewStyle" format="reference" />
+        <!-- Dark Fasttrack badge style. -->
+        <attr name="fasttrackBadgeWidgetStyle" format="reference" />
+        <!-- Dark Fasttrack badge style with small fasttrack window. -->
+        <attr name="fasttrackBadgeWidgetStyleWindowSmall" format="reference" />
+        <!-- Dark Fasttrack badge style with medium fasttrack window. -->
+        <attr name="fasttrackBadgeWidgetStyleWindowMedium" format="reference" />
+        <!-- Dark Fasttrack badge style with large fasttrack window. -->
+        <attr name="fasttrackBadgeWidgetStyleWindowLarge" format="reference" />
 
         <!-- =================== -->
         <!-- Preference styles   -->
         <attr name="orientation" />
     </declare-styleable>
 
+    <declare-styleable name="FasttrackBadgeWidget">
+        <attr name="fasttrackWindowSize">
+            <enum name="modeSmall" value="1" />
+            <enum name="modeMedium" value="2" />
+            <enum name="modeLarge" value="3" />
+        </attr>
+    </declare-styleable>
+
     <!-- ======================================= -->
     <!-- Widget package parent layout attributes -->
     <!-- ======================================= -->
index a2ceb8f..fae612c 100644 (file)
         <item name="android:shadowRadius">2.75</item>
     </style>
 
+    <style name="Widget.FasttrackBadgeWidget">
+        <item name="android:layout_width">48dip</item>
+        <item name="android:layout_height">52dip</item>
+        <item name="android:background">@android:drawable/fasttrack_badge_dark</item>
+        <item name="android:clickable">true</item>
+        <item name="android:scaleType">fitCenter</item>
+    </style>
+
+    <style name="Widget.FasttrackBadgeWidget.WindowSmall">
+        <item name="android:fasttrackWindowSize">modeSmall</item>
+    </style>
+
+    <style name="Widget.FasttrackBadgeWidget.WindowMedium">
+        <item name="android:fasttrackWindowSize">modeMedium</item>
+    </style>
+
+    <style name="Widget.FasttrackBadgeWidget.WindowLarge">
+        <item name="android:fasttrackWindowSize">modeLarge</item>
+    </style>
+
     <!-- Text Appearances -->
     <eat-comment />
 
index 3b9590d..4f76c56 100644 (file)
         <item name="spinnerItemStyle">@android:style/Widget.TextView.SpinnerItem</item>
         <item name="dropDownHintAppearance">@android:style/TextAppearance.Widget.DropDownHint</item>
         <item name="keyboardViewStyle">@android:style/Widget.KeyboardView</item>
+        <item name="fasttrackBadgeWidgetStyleWindowSmall">@android:style/Widget.FasttrackBadgeWidget.WindowSmall</item>
+        <item name="fasttrackBadgeWidgetStyleWindowMedium">@android:style/Widget.FasttrackBadgeWidget.WindowMedium</item>
+        <item name="fasttrackBadgeWidgetStyleWindowLarge">@android:style/Widget.FasttrackBadgeWidget.WindowLarge</item>
         
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>