ContactView.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:10k
源码类别:

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007-2008 Esmertec AG.
  3.  * Copyright (C) 2007-2008 The Android Open Source Project
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package com.android.im.app;
  18. import android.app.Activity;
  19. import android.content.ContentResolver;
  20. import android.content.ContentUris;
  21. import android.content.Context;
  22. import android.content.res.Resources;
  23. import android.database.Cursor;
  24. import android.net.Uri;
  25. import android.os.Handler;
  26. import android.provider.Im;
  27. import android.text.Spannable;
  28. import android.text.SpannableString;
  29. import android.text.SpannableStringBuilder;
  30. import android.text.TextUtils;
  31. import android.text.style.RelativeSizeSpan;
  32. import android.text.style.UnderlineSpan;
  33. import android.util.AttributeSet;
  34. import android.view.View;
  35. import android.view.animation.Animation;
  36. import android.view.animation.TranslateAnimation;
  37. import android.widget.ImageView;
  38. import android.widget.LinearLayout;
  39. import android.widget.TextView;
  40. import com.android.im.R;
  41. import com.android.im.plugin.BrandingResourceIDs;
  42. import java.text.DateFormat;
  43. import java.util.Calendar;
  44. public class ContactView extends LinearLayout {
  45.     static final String[] CONTACT_PROJECTION = {
  46.         Im.Contacts._ID,
  47.         Im.Contacts.PROVIDER,
  48.         Im.Contacts.ACCOUNT,
  49.         Im.Contacts.USERNAME,
  50.         Im.Contacts.NICKNAME,
  51.         Im.Contacts.TYPE,
  52.         Im.Contacts.SUBSCRIPTION_TYPE,
  53.         Im.Contacts.SUBSCRIPTION_STATUS,
  54.         Im.Presence.PRESENCE_STATUS,
  55.         Im.Presence.PRESENCE_CUSTOM_STATUS,
  56.         Im.Chats.LAST_MESSAGE_DATE,
  57.         Im.Chats.LAST_UNREAD_MESSAGE,
  58.     };
  59.     static final int COLUMN_CONTACT_ID = 0;
  60.     static final int COLUMN_CONTACT_PROVIDER = 1;
  61.     static final int COLUMN_CONTACT_ACCOUNT = 2;
  62.     static final int COLUMN_CONTACT_USERNAME = 3;
  63.     static final int COLUMN_CONTACT_NICKNAME = 4;
  64.     static final int COLUMN_CONTACT_TYPE = 5;
  65.     static final int COLUMN_SUBSCRIPTION_TYPE = 6;
  66.     static final int COLUMN_SUBSCRIPTION_STATUS = 7;
  67.     static final int COLUMN_CONTACT_PRESENCE_STATUS = 8;
  68.     static final int COLUMN_CONTACT_CUSTOM_STATUS = 9;
  69.     static final int COLUMN_LAST_MESSAGE_DATE = 10;
  70.     static final int COLUMN_LAST_MESSAGE = 11;
  71.     private ImageView mPresence;
  72.     private TextView mLine1;
  73.     private TextView mLine2;
  74.     private TextView mTimeStamp;
  75.     private Handler mHandler;
  76.     private boolean mLayoutDirty;
  77.     public ContactView(Context context, AttributeSet attrs) {
  78.         super(context, attrs);
  79.         mLayoutDirty = true;
  80.     }
  81.     @Override
  82.     protected void onFinishInflate() {
  83.         super.onFinishInflate();
  84.         mPresence = (ImageView) findViewById(R.id.presence);
  85.         mLine1 = (TextView) findViewById(R.id.line1);
  86.         mLine2 = (TextView) findViewById(R.id.line2);
  87.         mTimeStamp = (TextView)findViewById(R.id.timestamp);
  88.         mHandler = new Handler();
  89.     }
  90.     @Override
  91.     public void setSelected(boolean selected) {
  92.         super.setSelected(selected);
  93.         if(selected) {
  94.             // While layout, the width of children is unknown, we have to start
  95.             // animation when layout is done.
  96.             if (mLayoutDirty) {
  97.                 mHandler.post(new Runnable() {
  98.                     public void run() {
  99.                         startAnimationNow();
  100.                     }
  101.                 });
  102.             } else {
  103.                 startAnimationNow();
  104.             }
  105.         } else {
  106.             mLine2.clearAnimation();
  107.         }
  108.     }
  109.     @Override
  110.     protected void onLayout(boolean changed, int l, int t, int r, int b) {
  111.         mLayoutDirty = false;
  112.         super.onLayout(changed, l, t, r, b);
  113.     }
  114.     @Override
  115.     public void requestLayout() {
  116.         super.requestLayout();
  117.         mLayoutDirty = true;
  118.     }
  119.     /*package*/ void startAnimationNow() {
  120.         View parent = (View)mLine2.getParent();
  121.         int width = mLine2.getWidth();
  122.         int parentWidth = parent.getWidth() - parent.getPaddingLeft()
  123.                 - parent.getPaddingRight();
  124.         if(width > parentWidth) {
  125.             int fromXDelta = parentWidth;
  126.             int toXDelta = - width;
  127.             int duration = (fromXDelta - toXDelta) * 32;
  128.             Animation animation = new TranslateAnimation(fromXDelta, toXDelta, 0, 0);
  129.             animation.setDuration(duration);
  130.             animation.setRepeatMode(Animation.RESTART);
  131.             animation.setRepeatCount(Animation.INFINITE);
  132.             mLine2.startAnimation(animation);
  133.         }
  134.     }
  135.     public void bind(Cursor cursor, String underLineText, boolean scrolling) {
  136.         bind(cursor, underLineText, true, scrolling);
  137.     }
  138.     public void bind(Cursor cursor, String underLineText, boolean showChatMsg, boolean scrolling) {
  139.         Resources r = getResources();
  140.         long providerId = cursor.getLong(COLUMN_CONTACT_PROVIDER);
  141.         String username = cursor.getString(COLUMN_CONTACT_USERNAME);
  142.         String nickname = cursor.getString(COLUMN_CONTACT_NICKNAME);
  143.         int type = cursor.getInt(COLUMN_CONTACT_TYPE);
  144.         String statusText = cursor.getString(COLUMN_CONTACT_CUSTOM_STATUS);
  145.         String lastMsg = cursor.getString(COLUMN_LAST_MESSAGE);
  146.         boolean hasChat = !cursor.isNull(COLUMN_LAST_MESSAGE_DATE);
  147.         ImApp app = ImApp.getApplication((Activity)mContext);
  148.         BrandingResources brandingRes = app.getBrandingResource(providerId);
  149.         int presence = cursor.getInt(COLUMN_CONTACT_PRESENCE_STATUS);
  150.         // status icon
  151.         if (Im.Contacts.TYPE_GROUP == type) {
  152.             int iconId = lastMsg == null ? R.drawable.group_chat
  153.                     : R.drawable.group_chat_new;
  154.             mPresence.setImageResource(iconId);
  155.         } else if (hasChat) {
  156.             int iconId = lastMsg == null ? BrandingResourceIDs.DRAWABLE_READ_CHAT
  157.                     : BrandingResourceIDs.DRAWABLE_UNREAD_CHAT;
  158.             mPresence.setImageDrawable(brandingRes.getDrawable(iconId));
  159.         } else {
  160.             int iconId = PresenceUtils.getStatusIconId(presence);
  161.             mPresence.setImageDrawable(brandingRes.getDrawable(iconId));
  162.         }
  163.         // line1
  164.         CharSequence line1;
  165.         if (Im.Contacts.TYPE_GROUP == type) {
  166.             ContentResolver resolver = getContext().getContentResolver();
  167.             long id = cursor.getLong(ContactView.COLUMN_CONTACT_ID);
  168.             line1 = queryGroupMembers(resolver, id);
  169.         } else {
  170.             line1 = TextUtils.isEmpty(nickname) ?
  171.                     ImpsAddressUtils.getDisplayableAddress(username) : nickname;
  172.             if (!TextUtils.isEmpty(underLineText)) {
  173.                 // highlight/underline the word being searched
  174.                 String lowercase = line1.toString().toLowerCase();
  175.                 int start = lowercase.indexOf(underLineText.toLowerCase());
  176.                 if (start >= 0) {
  177.                     int end = start + underLineText.length();
  178.                     SpannableString str = new SpannableString(line1);
  179.                     str.setSpan(new UnderlineSpan(), start, end,
  180.                             Spannable.SPAN_INCLUSIVE_INCLUSIVE);
  181.                     line1 = str;
  182.                 }
  183.             }
  184.             if (Im.Contacts.TYPE_TEMPORARY == type) {
  185.                 // Add a mark at the front of name if it's only a temporary
  186.                 // contact.
  187.                 SpannableStringBuilder str = new SpannableStringBuilder(
  188.                         r.getText(R.string.unknown_contact));
  189.                 str.setSpan(new RelativeSizeSpan(0.8f), 0, str.length(),
  190.                         Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
  191.                 str.append(line1);
  192.                 line1 = str;
  193.             }
  194.         }
  195.         mLine1.setText(line1);
  196.         // time stamp
  197.         if (showChatMsg && hasChat) {
  198.             mTimeStamp.setVisibility(VISIBLE);
  199.             Calendar cal = Calendar.getInstance();
  200.             cal.setTimeInMillis(cursor.getLong(COLUMN_LAST_MESSAGE_DATE));
  201.             DateFormat formatter = DateFormat.getTimeInstance(DateFormat.SHORT);
  202.             mTimeStamp.setText(formatter.format(cal.getTime()));
  203.         } else {
  204.             mTimeStamp.setVisibility(GONE);
  205.         }
  206.         // line2
  207.         CharSequence line2 = null;
  208.         if (showChatMsg) {
  209.             line2 = lastMsg;
  210.         }
  211.         if (TextUtils.isEmpty(line2)){
  212.             if (Im.Contacts.TYPE_GROUP == type) {
  213.                 // Show nothing in line2 if it's a group and don't
  214.                 // have any unread message.
  215.                 line2 = null;
  216.             } else {
  217.                 // Show the custom status text if there's no new message.
  218.                 line2 = statusText;
  219.             }
  220.         }
  221.         if (TextUtils.isEmpty(line2)) {
  222.             // Show a string of presence if there is neither new message nor
  223.             // custom status text.
  224.             line2 = brandingRes.getString(PresenceUtils.getStatusStringRes(presence));
  225.         }
  226.         mLine2.setText(line2);
  227.         View contactInfoPanel = findViewById(R.id.contactInfo);
  228.         if (hasChat && showChatMsg) {
  229.             contactInfoPanel.setBackgroundResource(R.drawable.list_item_im_bubble);
  230.             mLine1.setTextColor(r.getColor(R.color.chat_contact));
  231.         } else {
  232.             contactInfoPanel.setBackgroundDrawable(null);
  233.             contactInfoPanel.setPadding(4, 0, 0, 0);
  234.             mLine1.setTextColor(r.getColor(R.color.nonchat_contact));
  235.         }
  236.     }
  237.     private String queryGroupMembers(ContentResolver resolver, long groupId) {
  238.         String[] projection = { Im.GroupMembers.NICKNAME };
  239.         Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
  240.         Cursor c = resolver.query(uri, projection, null, null, null);
  241.         StringBuilder buf = new StringBuilder();
  242.         if(c != null) {
  243.             while(c.moveToNext()) {
  244.                 buf.append(c.getString(0));
  245.                 if(!c.isLast()) {
  246.                     buf.append(',');
  247.                 }
  248.             }
  249.             c.close();
  250.         }
  251.         return buf.toString();
  252.     }
  253. }