package com.partynetwork.iparty.imessage;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Scroller;
import android.widget.TextView;
import com.baidu.mobstat.StatService;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.view.ViewHelper;
import com.partynetwork.dataprovider.util.MediaFile;
import com.partynetwork.dataprovider.util.OpenfireUtil;
import com.partynetwork.dataprovider.util.TimeUtil;
import com.partynetwork.iparty.R;
import com.partynetwork.iparty.app.AppContext;
import com.partynetwork.iparty.app.AppException;
import com.partynetwork.iparty.app.bean.NoticeList;
import com.partynetwork.iparty.app.common.BitmapManager;
import com.partynetwork.iparty.app.common.UIHelper;
import com.partynetwork.iparty.app.entities.ChartHisBean;
import com.partynetwork.iparty.app.entities.CommonUser;
import com.partynetwork.iparty.app.entities.IMessage;
import com.partynetwork.iparty.app.manager.MessageManager;
import com.partynetwork.iparty.app.manager.NoticeManager;
import com.partynetwork.iparty.app.manager.UserManager;
import com.partynetwork.iparty.app.util.StringUtils;
import com.partynetwork.iparty.app.widget.SlideView;
import com.partynetwork.iparty.info.MessageTypeInfo;
import com.partynetwork.iparty.info.UserInfo;
public class ImessagePage extends LinearLayout implements OnClickListener,
OnItemClickListener, OnTouchListener, Callback {
private Context mContext;
private ListView mListView;
private SlideAdapter slideAdapter;
// 历史聊天记录
private List<ChartHisBean> inviteNotices = new ArrayList<ChartHisBean>();
// 上次处于打开状态的SlideView
private SlideView mPointView;
private SlideView mLastView;
// 弹性滑动对象,提供弹性滑动效果
private Scroller mPointScroller;
// 内置容器的宽度 单位:dp
private int mHolderWidth = 120;
// 分别记录上次滑动的坐标
private int mLastX = 0;
private int mLastY = 0;
// 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2
private static final int TAN = 2;
// 当前状态
private int state = 2;
// SlideView的三种状态:开始滑动,打开,关闭
public static final int SLIDE_STATUS_OFF = 0;
public static final int SLIDE_STATUS_START_SCROLL = 1;
public static final int SLIDE_STATUS_ON = 2;
private BitmapManager bitmapManager;
private AppContext appContext;
private Handler mHandler;
public ImessagePage(Context context) {
super(context);
mContext=context;
initView();
}
/**
* 实例化控件
*/
private void initView() {
// mContext = getContext();
appContext = (AppContext) mContext.getApplicationContext();
bitmapManager = new BitmapManager();
View.inflate(mContext, R.layout.imessage, this);
mListView = (ListView) findViewById(R.id.imessage_list);
TextView emptyView = new TextView(mContext);
emptyView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
emptyView.setGravity(Gravity.CENTER);
emptyView.setText("暂无消息……");
emptyView.setVisibility(View.GONE);
((ViewGroup) mListView.getParent()).addView(emptyView);
mListView.setEmptyView(emptyView);
slideAdapter = new SlideAdapter(mContext, inviteNotices);
mListView.setAdapter(slideAdapter);
mListView.setOnItemClickListener(this);
mListView.setOnTouchListener(this);
mHandler = new Handler(this);
}
/**
* 获得通知
*/
public void getNotices() {
new Thread() {
@Override
public void run() {
mHandler.sendEmptyMessage(0);
Message msg = new Message();
try {
NoticeList infos = appContext.getNoticeList();
msg.what = 1;// 成功
msg.obj = infos;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
mHandler.sendMessage(msg);
}
}.start();
}
/**
* 获得用户信息
*
* @param userId
*/
private void getUserInfo(final int userId) {
new Thread() {
public void run() {
Message msg = new Message();
try {
UserInfo info = appContext.getUserInfo(userId);
CommonUser user = new CommonUser();
user.setUserAge(info.getUserAge());
user.setUserHeadUrl(info.getUserHeadUrl());
user.setUserId(info.getUserId());
user.setUserName(info.getUserName());
user.setUserSex(info.getUserSex());
user.setUserState(info.getUserState());
msg.what = 2;// 成功
msg.obj = user;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
mHandler.sendMessage(msg);
}
}.start();
}
@Override
public boolean handleMessage(Message arg0) {
switch (arg0.what) {
case 0:
// 刷新
System.out.println("arg0.what=========0");
inviteNotices.removeAll(inviteNotices);
inviteNotices.addAll(NoticeManager.getInstance(mContext)
.getRecentContactsWithLastMsg());
inviteNotices.addAll(MessageManager.getInstance(mContext)
.getRecentContactsWithLastMsg());
System.out.println("我的标记inviteNotices==="+inviteNotices.size());
slideAdapter.notifyDataSetChanged();
break;
case 1:
System.out.println("arg0.what=========1");
NoticeList list = (NoticeList) arg0.obj;
if (list == null) {
return false;
}
// 对通知进行操作
// ......
List<MessageTypeInfo> typeLists = list.getNoticeList();
System.out.println("NoticeList.size=="+typeLists.size());
List<ChartHisBean> hisList = new ArrayList<ChartHisBean>();
for (MessageTypeInfo info : typeLists) {
boolean has = false;
// System.out.println("(info.getMessageNumber()=="+info.getMessageNumber());
if (info.getMessageNumber() > 0) {
for (ChartHisBean ch : inviteNotices) {
if (ch.getFrom() != null
&& ch.getFrom().equals(
info.getMessageType() + "")) {
has = true;
ch.setNoticeSum(info.getMessageNumber());
}
}
}
//这段代码移动位置
if (!has) {
ChartHisBean hisBean = new ChartHisBean();
hisBean.setNoticeType(ChartHisBean.SYS_MSG);
hisBean.setContent(info.getMessageStr());
hisBean.setTitle(info.getMessageStr());
hisBean.setFrom(info.getMessageType() + "");
hisBean.setNoticeSum(info.getMessageNumber());
hisList.add(hisBean);
}
}
hisList.addAll(inviteNotices);
inviteNotices.removeAll(inviteNotices);
inviteNotices.addAll(hisList);
slideAdapter.notifyDataSetChanged();
System.out.println("我的标记inviteNotices==="+inviteNotices.size());
System.out.println("我的标记hisList==="+hisList.size());
break;
case 2:
// 成功获取用户信息
System.out.println("arg0.what=========2 ");
CommonUser user = (CommonUser) arg0.obj;
if (user == null) {
return false;
}
UserManager.getInstance(mContext).saveOrUpdateUser(user);
slideAdapter.notifyDataSetChanged();
break;
case -1:
System.out.println("arg0.what=========-1 ");
AppException e = (AppException) arg0.obj;
if (AppContext.getInstance().isLogin()) {
e.makeToast(mContext);
}
break;
default:
break;
}
return false;
}
/**
* 页面恢复方法
*/
public void onResume() {
getNotices();
StatService.onPageStart(mContext, "imessagePage");
}
public void onPause() {
StatService.onPageEnd(mContext, "imessagePage");
}
public void msgReceive(IMessage msg) {
boolean has = false;
for (ChartHisBean ch : inviteNotices) {
if (ch.getFrom() != null && ch.getFrom().equals(msg.getWithUser())) {
has = true;
ch.setContent(msg.getContent());
ch.setNoticeTime(msg.getTime());
ch.setNoticeSum(ch.getNoticeSum() + 1);
}
}
if (inviteNotices.size() == 0) {
getNotices();
}
if (!has) {
ChartHisBean bean = new ChartHisBean();
bean.setContent(msg.getContent());
bean.setFrom(msg.getWithUser());
bean.setNoticeSum(1);
bean.setNoticeTime(msg.getTime());
bean.setNoticeType(ChartHisBean.CHAT_MSG);
inviteNotices.add(bean);
}
slideAdapter.notifyDataSetChanged();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if (state == SLIDE_STATUS_OFF) {
if (inviteNotices.get(position).getNoticeType() == ChartHisBean.SYS_MSG) {
UIHelper.showNotice(mContext, StringUtils.toInt(inviteNotices
.get(position).getFrom(), 0));
} else {
System.out.println("getFrom()========="+inviteNotices.get(position).getFrom());
UIHelper.showChat(mContext, inviteNotices.get(position)
.getFrom());
}
}
}
@Override
public void onClick(View v) {
// 这里处理删除按钮的点击事件,可以删除对话
if (v.getId() == R.id.holder) {
final int position = mListView.getPositionForView(v);
if (position != ListView.INVALID_POSITION) {
// 在此方法中执行item删除之后,其他的item向上或者向下滚动的动画
final View dismissView = mListView.getChildAt(position);
final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();// 获取item的布局参数
final int originalHeight = dismissView.getHeight();// item的高度
ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 0)
.setDuration(150);
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
MessageManager.getInstance(mContext).delChatHisWithSb(
inviteNotices.get(position).getFrom());
NoticeManager.getInstance(mContext).delNoticeByType(
StringUtils.toInt(inviteNotices.get(position)
.getFrom(), 0));
inviteNotices.remove(position);
slideAdapter.notifyDataSetChanged();
// 这段代码很重要,因为我们并没有将item从ListView中移除,而是将item的高度设置为0
// 所以我们在动画执行完毕之后将item设置回来
ViewHelper.setAlpha(dismissView, 1f);
ViewHelper.setTranslationX(dismissView, 0);
ViewGroup.LayoutParams lp = dismissView
.getLayoutParams();
lp.height = originalHeight;
dismissView.setLayoutParams(lp);
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// 这段代码的效果是ListView删除某item之后,其他的item向上滑动的效果
lp.height = (Integer) valueAnimator.getAnimatedValue();
dismissView.setLayoutParams(lp);
}
});
}
}
}
private class SlideAdapter extends ArrayAdapter<ChartHisBean> {
SlideAdapter(Context context, List<ChartHisBean> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ChartHisBean notice = (ChartHisBean) getItem(position);
ViewHolder holder;
SlideView slideView = (SlideView) convertView;
if (slideView == null) {
View itemView = null;
itemView = LayoutInflater.from(mContext).inflate(
R.layout.message_item_chat, null);
slideView = new SlideView(mContext);
// 这里把item加入到slideView
slideView.setContentView(itemView);
// 下面是做一些数据缓存
holder = new ViewHolder(slideView);
slideView.setTag(holder);
// convertView.setTag(holder);
} else {
holder = (ViewHolder) slideView.getTag();
}
notice.setSlideView(slideView);
setDate(holder, notice);
return slideView;
}
}
/**
* 处理数据
*
* @param notice
*/
private void setDate(ViewHolder holder, ChartHisBean notice) {
Integer ppCount = notice.getNoticeSum();
if (notice.getNoticeType() == ChartHisBean.SYS_MSG) {
holder.newTitle.setText(notice.getTitle());
holder.newTitle.setVisibility(View.GONE);
holder.newDate.setVisibility(View.GONE);
int from = StringUtils.toInt(notice.getFrom(), 0);
// 0:系统消息
// 1:iParty提醒
// 2:打招呼
// 3:新的i好友
// 4:提到我的
// 5:投票
// 6:评论
// 7:赞
int res = 0;
String content = "";
switch (from) {
case 0:
res = R.drawable.message_sys_notice_icon;
content = "系统消息";
break;
case 1:
res = R.drawable.message_sys_party_icon;
content = "iParty提醒";
break;
case 2:
res = R.drawable.message_sys_hi_icon;
content = "打招呼";
break;
case 3:
res = R.drawable.message_sys_friend_icon;
content = "新的i好友";
break;
case 4:
res = R.drawable.message_sys_at_icon;
content = "提到我的";
break;
case 5:
res = R.drawable.message_sys_vote_icon;
content = "投票";
break;
case 6:
res = R.drawable.message_sys_discuss_icon;
content = "评论";
break;
case 7:
res = R.drawable.message_sys_praise_icon;
content = "赞";
break;
default:
res = R.drawable.message_sys_notice_icon;
content = "系统消息";
break;
}
holder.itemIcon.setImageResource(res);
holder.newContent.setText(content);
} else {
holder.newTitle.setVisibility(View.VISIBLE);
holder.newDate.setVisibility(View.VISIBLE);
String userId = OpenfireUtil.getUserNameByJid(notice.getFrom());
CommonUser user = null;
user = UserManager.getInstance(mContext).getUserbyId(userId);
if (user != null) {
bitmapManager
.loadBitmap(user.getUserHeadUrl(), holder.itemIcon);
holder.newTitle.setText(user.getUserName());
} else {
getUserInfo(Integer.parseInt(userId));
}
if (MediaFile.isAudioFileType(notice.getContent())) {
holder.newContent.setText("[语音]");
} else if (MediaFile.isImageFileType(notice.getContent())) {
holder.newContent.setText("[图片]");
} else {
holder.newContent.setText(notice.getContent());
}
}
holder.newDate.setText(TimeUtil.friendly_time(notice.getNoticeTime()));
holder.deleteHolder.setOnClickListener(this);
if (ppCount != null && ppCount > 0) {
holder.paopao.setText(ppCount + "");
holder.paopao.setVisibility(View.VISIBLE);
holder.newDate.setVisibility(View.GONE);
} else {
holder.paopao.setVisibility(View.GONE);
if (notice.getNoticeType() == ChartHisBean.CHAT_MSG) {
holder.newDate.setVisibility(View.VISIBLE);
}
}
}
private static class ViewHolder {
public ImageView itemIcon;
public TextView newTitle;
public TextView newContent;
public TextView newDate;
public TextView paopao;
public ViewGroup deleteHolder;
ViewHolder(View view) {
itemIcon = (ImageView) view.findViewById(R.id.icon);
newTitle = (TextView) view.findViewById(R.id.title);
newContent = (TextView) view.findViewById(R.id.content);
newDate = (TextView) view.findViewById(R.id.time);
paopao = (TextView) view.findViewById(R.id.number);
deleteHolder = (ViewGroup) view.findViewById(R.id.holder);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
int scrollX = 0;
if (mPointView != null) {
scrollX = mPointView.getScrollX();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (mPointScroller != null && !mPointScroller.isFinished()) {
mPointScroller.abortAnimation();
}
int position = mListView.pointToPosition(x, y);
mPointView = (SlideView) mListView.getChildAt(position);
if (mPointView != null) {
mPointScroller = new Scroller(mPointView.getContext());
// 初始化弹性滑动对象
state = SLIDE_STATUS_START_SCROLL;
onSlide(mPointView, state);
}
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
// 滑动不满足条件,不做横向滑动
break;
}
// 计算滑动终点是否合法,防止滑动越界
int newScrollX = scrollX - deltaX;
if (deltaX != 0) {
if (newScrollX < 0) {
newScrollX = 0;
} else if (newScrollX > mHolderWidth) {
newScrollX = mHolderWidth;
}
if (mPointView != null) {
mPointView.scrollTo(newScrollX, 0);
}
}
break;
}
case MotionEvent.ACTION_UP: {
int newScrollX = 0;
// 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置
if (scrollX - mHolderWidth * 0.75 > 0) {
newScrollX = mHolderWidth;
}
// 慢慢滑向终点
smoothScrollTo(mPointView, mPointScroller, newScrollX, 0);
// 通知上层滑动事件
state = scrollX < 10 ? SLIDE_STATUS_OFF : SLIDE_STATUS_ON;
onSlide(mPointView, state);
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return super.onTouchEvent(event);
}
private void smoothScrollTo(SlideView slideView, Scroller scroller,
int destX, int destY) {
// 缓慢滚动到指定位置
int scrollX = 0;
if (slideView != null) {
scrollX = slideView.getScrollX();
}
int delta = destX - scrollX;
// 以三倍时长滑向destX,效果就是慢慢滑动
if (scroller != null) {
scroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
}
invalidate();
}
public void computeScroll() {
if (mPointView != null && mPointScroller != null
&& mPointScroller.computeScrollOffset()) {
mPointView.scrollTo(mPointScroller.getCurrX(),
mPointScroller.getCurrY());
postInvalidate();
}
}
public void onSlide(View view, int status) {
// 如果当前存在已经打开的SlideView,那么将其关闭
if (mLastView != null && mLastView != view) {
// shrink();
mLastView.scrollTo(0, 0);
}
// 记录本次处于打开状态的view
if (status == SLIDE_STATUS_ON) {
mLastView = (SlideView) view;
}
}
}