package com.sogouchat.ui; import java.io.ByteArrayInputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import com.sogouchat.R; import com.sogouchat.SogouChatApp; import com.sogouchat.bean.ContactNode; import com.sogouchat.bean.TelNode; import com.sogouchat.widget.BadgeView; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.text.TextPaint; import android.text.format.DateFormat; import android.text.format.Time; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.app.Activity; public class NewsListAdapter extends BaseAdapter { public final class ViewHolder{ public View mIcon; public TextView mIconFirst; public TextView mIconSecond; public TextView mName; public TextView mLastBody; public TextView mLastDate; public BadgeView mBadge; } private static final String TAG = "NewsListAdapter"; public ArrayList<TelNode> mData; public ArrayList<TelNode> mPreData; public ArrayList<TelNode> mAllData = new ArrayList<TelNode>(); public ArrayList<TelNode> mContactData = new ArrayList<TelNode>(); public ArrayList<TelNode> mNewData = new ArrayList<TelNode>(); public ArrayList<View> mRowData = new ArrayList<View>(); private static final int Cache_Max=10; private View mItemCache[] = new View[Cache_Max]; private LayoutInflater mInflater; private NewsListActivity mActivity; private SogouChatApp mApp; private LinearLayout news_text_icon_layout; private static final int mDroidGreen = Color.parseColor("#A4C639"); // private Drawable mDefault; public NewsListAdapter(Context context, SogouChatApp app){ mActivity =(NewsListActivity) context; mInflater = LayoutInflater.from(context); mApp = app; mPreData = null; } public void setupList() { Log.i(TAG, "setupList"); mAllData.clear(); mContactData.clear(); int totalNew = 0; Iterator<TelNode> telIt = mApp.mTelList.iterator(); while (telIt.hasNext()) { TelNode telNode = telIt.next(); if (telNode.mMsgCnt > 0) { mAllData.add(telNode); if(telNode.mContactId !=0){ mContactData.add(telNode); } if (telNode.mUnMsgCnt > 0) totalNew += telNode.mUnMsgCnt; } } mData = mContactData; // sort list Collections.sort(mData, new SortByDate()); splitDataByDate(); mData = mAllData; // sort list Collections.sort(mData, new SortByDate()); splitDataByDate(); if (totalNew > 0) { mActivity.setTotalNewMsgCnt(totalNew); } Log.i(TAG, "setupList Ok"); } private void setupRowList(){ int array[] = {0,1,2,10,11,12,13,14,15,16,20,30,40,50,100}; for(int i=0;i<array.length; i++){ TelNode row = new TelNode(); row.mName = getSeparatorName(array[i]); row.mTel = null; View rowView = mInflater.inflate(R.layout.item_news_separator,null); } } public void switchToNew(boolean toNew) { int totalNew = 0; if(mPreData == null){ mPreData = mData; mNewData.clear(); Iterator<TelNode> telIt = mData.iterator(); while (telIt.hasNext()) { TelNode telNode = telIt.next(); if (telNode.mUnMsgCnt > 0) { mNewData.add(telNode); totalNew += telNode.mUnMsgCnt; } } mData = mNewData; // sort list Collections.sort(mData, new SortByDate()); splitDataByDate(); mActivity.setTotalNewMsgCnt(totalNew); } else{ mData = mPreData; mPreData = null; } } public void switchToAll(boolean toAll){ if(toAll){ mData = mAllData; } else { mData = mContactData; } mPreData = null; int totalNew = 0; Iterator<TelNode> telIt = mData.iterator(); while (telIt.hasNext()) { TelNode telNode = telIt.next(); if (telNode.mUnMsgCnt > 0) { mNewData.add(telNode); totalNew += telNode.mUnMsgCnt; } } mActivity.setTotalNewMsgCnt(totalNew); } //倒序 class SortByDate implements Comparator<Object> { public int compare(Object o1, Object o2) { TelNode item1 = (TelNode) o1; TelNode item2 = (TelNode) o2; if (item1.mLastDate > item2.mLastDate) return -1; else return 1; } } public boolean isEnabled(int position) { TelNode node = (TelNode)getItem(position); if(node.mTel == null) return false; else return super.isEnabled(position); } ArrayList<TelNode> getData(){ return mData; } void setData(ArrayList<TelNode> data){ mData = data; } @Override public int getCount() { // TODO Auto-generated method stub return mData.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mData.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // Log.i(TAG, "getView"+position); ViewHolder holder = null; final TelNode item = mData.get(position); if (position == 0){ Log.i(TAG, "getView+++++++++"+position); } if (position < Cache_Max && mItemCache!=null){ // Log.i(TAG, "getView get catche"+position); convertView = mItemCache[position]; } else{ // Log.i(TAG, "getView close catche"); mItemCache = null; } if (convertView == null) { // Log.i(TAG, "convertView is NULL"); holder = new ViewHolder(); if (item.mTel != null) { convertView = mInflater.inflate(R.layout.item_news_list, null); holder.mIcon = convertView.findViewById(R.id.news_text_icon); holder.mIconFirst = (TextView) convertView.findViewById(R.id.news_text_icon_first); holder.mIconSecond = (TextView) convertView.findViewById(R.id.news_text_icon_second); holder.mName = (TextView) convertView.findViewById(R.id.news_text_name); holder.mLastBody = (TextView) convertView .findViewById(R.id.news_text_msg); holder.mLastDate = (TextView) convertView.findViewById(R.id.news_text_date); } else { convertView = mInflater.inflate(R.layout.item_news_separator,null); holder.mName = (TextView) convertView.findViewById(R.id.news_text_separator); holder.mLastDate = (TextView) convertView.findViewById(R.id.news_text_date); } } else { holder = (ViewHolder) convertView.getTag(); } if (item.mTel != null) { Log.i(TAG, "view is list item"); if (holder.mName == null || holder.mName.getId() != R.id.news_text_name){ Log.i(TAG, "view is list item NOT"); convertView = mInflater.inflate(R.layout.item_news_list, null); holder = new ViewHolder(); holder.mIcon = convertView.findViewById(R.id.news_text_icon); holder.mIconFirst = (TextView) convertView.findViewById(R.id.news_text_icon_first); holder.mIconSecond = (TextView) convertView.findViewById(R.id.news_text_icon_second); holder.mName = (TextView) convertView.findViewById(R.id.news_text_name); holder.mLastBody = (TextView) convertView .findViewById(R.id.news_text_msg); holder.mLastDate = (TextView) convertView.findViewById(R.id.news_text_date); } convertView.setTag(holder); if (item.mContactId >0 ){ if (item.mPhotoId == 0){ int in = item.mName.lastIndexOf(" "); if (in < 0 && item.mName.charAt(0) != '+') { in=0; } else in++; String name = item.mName.substring(in, item.mName.length()); if (name.length()> 3){ holder.mIconFirst.setText(name.substring(0,1)); holder.mIconSecond.setText(name.substring(1)); } else if (name.length() == 3){ holder.mIconFirst.setText(name.substring(0,1)); holder.mIconSecond.setText(" "+name.substring(1)); } else if (name.length() == 2){ holder.mIconFirst.setText(name.substring(0,1)); holder.mIconSecond.setText(" "+name.substring(1,2)); } else{ holder.mIconFirst.setText(item.mName.substring(0,1)); } holder.mIcon.setBackgroundResource(R.drawable.bg_photo_icon); } else { holder.mIconFirst.setText(null); holder.mIconSecond.setText(null); setContactPhoto(item, holder.mIcon); } holder.mIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } else{ holder.mIconFirst.setText(""); holder.mIconSecond.setText(""); //holder.mIcon.setBackgroundResource(R.drawable.bg_photo_default); holder.mIcon.setBackgroundResource(R.drawable.add_portrait_normal); holder.mIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i(TAG, "沈小巧----holder.mIcon.setOnClickListener"); final String tel = item.mTel; final String nameString=item.mName; if (tel == null) return; Intent intent = new Intent(Intent.ACTION_INSERT); intent.setType("vnd.android.cursor.dir/person"); intent.setType("vnd.android.cursor.dir/contact"); intent.setType("vnd.android.cursor.dir/raw_contact"); intent.putExtra(android.provider.ContactsContract.Intents.Insert.PHONE, tel); mActivity.startActivity(intent); } }); } if (item.mLastBody != null){ holder.mLastBody.setText(item.mLastBody); } else { holder.mLastBody.setText("(无主题)"); } String dateFormat = null; if (isRecent(item.mLastDate)) { dateFormat = "aahh:mm"; } else { dateFormat = "MM/dd"; } SimpleDateFormat format1 = new SimpleDateFormat(dateFormat); String date = format1.format(item.mLastDate); holder.mLastDate.setText(date); if (item.mUnMsgCnt > 0) { // holder.mBadge.setText(String.valueOf(item.mNewMsgCnt)); // holder.mBadge.show(); holder.mName.setText(item.mName+" ("+item.mUnMsgCnt+")"); // holder.mLastBody.setTextColor(Color.BLACK); TextPaint paint = holder.mLastBody.getPaint(); // paint.setFakeBoldText(true); paint = holder.mName.getPaint(); paint.setFakeBoldText(true); holder.mLastBody.setMaxLines(3); } else { // holder.mBadge.hide(); // holder.mLastBody.setTextColor(Color.BLACK); TextPaint paint = holder.mLastBody.getPaint(); paint.setFakeBoldText(false); paint = holder.mName.getPaint(); paint.setFakeBoldText(false); holder.mLastBody.setMaxLines(1); holder.mName.setText(item.mName); } } else{ // Log.i(TAG, "view is row item"); if (holder.mName== null || holder.mName.getId() != R.id.news_text_separator){ // Log.i(TAG, "view is row item NOT"); convertView = mInflater.inflate(R.layout.item_news_separator,null); holder = new ViewHolder(); holder.mName = (TextView) convertView.findViewById(R.id.news_text_separator); holder.mLastDate = (TextView) convertView.findViewById(R.id.news_text_date); } convertView.setTag(holder); if(item.mType>0){ holder.mName.setText(item.mName); //holder.mLastDate.setText(" "); holder.mBadge = new BadgeView(mActivity, holder.mLastDate); holder.mBadge.setBadgeBackgroundColor(Color.parseColor("#A4C639")); holder.mBadge.setBadgePosition(BadgeView.POSITION_BOTTOM_LEFT); holder.mBadge.setBadgeMargin(0, 0); holder.mBadge.setText(String.valueOf(item.mType)); holder.mBadge.show(); } else{ holder.mName.setText(item.mName); } } ViewHolder holderx = (ViewHolder) convertView.getTag(); // Log.i(TAG, "getView Ok"+position); if (position < Cache_Max && mItemCache!=null&& mItemCache[position]==null){ // Log.i(TAG, "getView save cache"+position); mItemCache[position] = convertView; } return convertView; } private boolean isRecent(long date) { // TODO Auto-generated method stub Time time = new Time(); time.setToNow(); int dayNow = Time.getJulianDay(time.normalize(true), 0); int day = Time.getJulianDay(date, 0); return dayNow - day < 3; } private final void splitDataByDate(){ int sIndex=-1; TelNode row = null; int rowNum=0; for(int i =0; i < mData.size(); i++){ TelNode item =mData.get(i); int ssIndex = beforeToday(item.mLastDate); if (ssIndex != sIndex){ sIndex = ssIndex; TelNode separator = new TelNode(); separator.mName = getSeparatorName(sIndex); separator.mTel = null; separator.mContactId = -1; if(row!=null){ row.mType = rowNum; rowNum = 0; } mData.add(i, separator); row = separator; i++; } rowNum += item.mUnMsgCnt; } } public static int beforeToday(long date) { int sIndex; int bDay; Time nTime = new Time(); nTime.setToNow(); Time oTime = new Time(); oTime.set(date); int dayNow = Time.getJulianDay(nTime.normalize(true), 0); int day = Time.getJulianDay(date, 0); //天数差 bDay = dayNow - day; int wDay = nTime.weekDay; int nMon= nTime.month; int oMon = oTime.month; if (bDay == 0){ sIndex = 0; } else if (bDay == 1){ sIndex = 1; } else if (bDay == 2){ sIndex = 2; } //一周之内 else if (bDay >2 && bDay<= wDay ){ sIndex = oTime.weekDay+10; } //上周 else if (bDay > wDay && bDay <= 7 + wDay && nMon == oMon ){ sIndex = 20; } //两周以前 else if (bDay > 7 + wDay && bDay <= 14 + wDay && nMon == oMon ){ sIndex = 30; } //三周以前 else if (bDay > 14 + wDay -2 && bDay <= 21 + wDay && nMon == oMon ){ sIndex = 40; } //上个月 else if (nMon - oMon == 1 ){ sIndex = 50; } //更早 else { sIndex = 100; } return sIndex; } private String getSeparatorName(int sIndex){ String name="更早"; switch(sIndex){ case 0: name = "今天"; break; case 1: name = "昨天"; break; case 2: name = "前天"; break; case 10: name = "星期天"; break; case 11: name = "星期一"; break; case 12: name = "星期二"; break; case 13: name = "星期三"; break; case 14: name = "星期四"; break; case 15: name = "星期五"; break; case 16: name = "星期六"; break; case 20: name = "上周"; break; case 30: name = "两周以前"; break; case 40: name = "三周以前"; break; case 50: name = "上月"; break; default: name = "更早"; break; } return name; } private void setContactPhoto(TelNode telNode, View image){ if( telNode.mPhotoId !=0 && telNode.mPhoto == null ){ /*有了联系人的photo_id,接下来就要通过这个photo_id在另一张表(data表)中找到具体的头像资源(二进制BLOB)当然这个Uri,定位就是我们说的data表*/ Uri ur = ContactsContract.Data.CONTENT_URI; /*我说一下这里的参数(1、Uri(实际上就是要查询的表)2、需要返回的字段名(这里的字段"data15"存储的就是联系人的头像)3、后面两个是where过滤,传入先前查询到的photo_id,注意:其对应的是data表中"_id"字段)*/ Cursor cursor=mActivity.getContentResolver().query(ur, new String[]{"data15"}, "ContactsContract.Data._ID=?", new String[]{String.valueOf(telNode.mPhotoId)}, null); if (cursor != null) { while (cursor.moveToNext()) { /* 对返回来的Cursor进行一系列的处理,最终转换成Bitmap对象 */ byte[] photoicon = cursor.getBlob(0); ByteArrayInputStream inputStream = new ByteArrayInputStream( photoicon); Drawable contactPhoto = Drawable.createFromStream(inputStream, null); if (contactPhoto != null) { telNode.mPhoto = contactPhoto; image.setBackgroundDrawable(contactPhoto); } } cursor.close(); } } else if (telNode.mPhoto != null) { image.setBackgroundDrawable(telNode.mPhoto); } } }