本周接下来我完成了MainActivity中声明的RecentMsgFragment, 完成界面中的“消息”部分
一. 先写一个BaseFragment,利于之后其他自定义Fragment继承
package com.ezreal.ezchat.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by 张静.
*/
public abstract class BaseFragment extends Fragment {
protected View mRootView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//创建该fragment的视图
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = inflater.inflate(setLayoutID(), container, false);
initView(mRootView);
}
//缓存的rootView需要判断是否已经被加过parent
//如果有parent需要从parent删除,要不然会发生这个rootView已经有parent的错误。
ViewGroup parent = (ViewGroup) mRootView.getParent();
if (parent != null) {
parent.removeView(mRootView);
}
return mRootView;
}
public abstract int setLayoutID(); //设置加载的布局ID
public abstract void initView(View rootView);
}
二. RecentContactBean
设置属性最近联系人,用户资料以及获取和设置两个属性的方法
package com.ezreal.ezchat.bean;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
/**
* Created by 张静.
*/
public class RecentContactBean {
private RecentContact mRecentContact;
private UserInfoProvider.UserInfo mUserInfo;
public RecentContact getRecentContact() {
return mRecentContact;
}
public void setRecentContact(RecentContact recentContact) {
mRecentContact = recentContact;
}
public UserInfoProvider.UserInfo getUserInfo() {
return mUserInfo;
}
public void setUserInfo(UserInfoProvider.UserInfo userInfo) {
mUserInfo = userInfo;
}
}
三. RecentMsgFragment
1. 设置加载的布局ID
@Override
public int setLayoutID() {
return R.layout.fragment_message;
}
其中,fragment_message.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/interval_color">
<android.support.v7.widget.RecyclerView
android:id="@+id/rcv_message_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
2.初始化RecyclerView (RecycleViewAdapter以及RViewHolder已由另一位组员编写完成)
(1)为RecyclerView创建Adapter
a.给item设置加载的布局ID
b.找到目标位置的数据并绑定到holder上
数据:头像,名称,最近对话,该次对话时间
(2)给RecyclerView的item添加点击事件
若点击的该item获取到的会话类型为单聊(P2P),跳转到P2P聊天界面
(3)给RecyclerView设置适配器为mViewAdapter
private void initRecyclerView(){
mLayoutManager = new LinearLayoutManager(getContext());
mContactList = new ArrayList<>();
mRecyclerView.setLayoutManager(mLayoutManager);
mViewAdapter = new RecycleViewAdapter<RecentContactBean>(getContext(),mContactList) {
@Override
public int setItemLayoutId(int position) {
return R.layout.item_recent_msg;
}
@Override
public void bindView(RViewHolder holder, int position) {
RecentContactBean contactBean= mContactList.get(position);
holder.setImageByUrl(getContext(),R.id.iv_head_picture,
contactBean.getUserInfo().getAvatar(),R.mipmap.bg_img_defalut);
holder.setText(R.id.tv_recent_name,contactBean.getUserInfo().getName());
holder.setText(R.id.tv_recent_content,contactBean.getRecentContact().getContent());
String time = mDateFormat.format(new Date(contactBean.getRecentContact().getTime()));
holder.setText(R.id.tv_recent_time,time);
}
};
mViewAdapter.setItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(RViewHolder holder, int position) {
RecentContactBean contactBean = mContactList.get(position);
Intent intent;
if (contactBean.getRecentContact().getSessionType() == SessionTypeEnum.P2P){
intent = new Intent(getContext(), P2PChatActivity.class);
intent.putExtra("NimUserInfo",contactBean.getUserInfo());
startActivity(intent);
}
}
});
mRecyclerView.setAdapter(mViewAdapter);
}
3.初始化监听器
private void initListener(){
mObserver = new Observer<List<RecentContact>>() {
@Override
public void onEvent(List<RecentContact> recentContacts) {
Log.e(TAG,"Observer RecentContact size = " + recentContacts.size());
if (mContactList.isEmpty()){
List<RecentContactBean> contactBeans = createContactBeans(recentContacts);
mContactList.addAll(contactBeans);
mViewAdapter.notifyDataSetChanged();
return;
}
for (RecentContact contact : recentContacts){
refreshRecentList(contact);
}
}
};
}
4. 刷新最近通话列表
private void refreshRecentList(RecentContact contact){
for (int i=0;i<mContactList.size();i++){
RecentContactBean bean = mContactList.get(i);
if (bean.getRecentContact().getContactId().equals(contact.getContactId())){
bean.setRecentContact(contact);
mViewAdapter.notifyItemChanged(i);
break;
}else if (i == mContactList.size()-1){
// 否则为新的最近会话
RecentContactBean newBean = new RecentContactBean();
newBean.setRecentContact(contact);
newBean.setUserInfo(getUserInfoByAccount(contact.getContactId()));
mContactList.add(0,newBean);
}
}
}
5.加载最近联系人列表
通过NimClient的getService接口获取到MsgService(云信消息服务接口)服务实例,调用queryRecentContacts方法查询最近联系人列表数据
若有错则返回,否则加载最近联系人列表
private void loadRecentList(){
NIMClient.getService(MsgService.class).queryRecentContacts()
.setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
@Override
public void onResult(int code, List<RecentContact> result, Throwable exception) {
if (exception != null){
Log.e(TAG,"loadRecentList exception = " + exception.getMessage());
return;
}
if (code != 200){
Log.e(TAG,"loadRecentList error code = " + code);
return;
}
Log.e(TAG,"loadRecentList size = " + result.size());
List<RecentContactBean> contactBeans = createContactBeans(result);
mContactList.clear();
mContactList.addAll(contactBeans);
mViewAdapter.notifyDataSetChanged();
}
});
}
附上完整代码:
RecentMsgFragment.java
package com.ezreal.ezchat.fragment;
import android.content.Intent;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import com.ezreal.ezchat.R;
import com.ezreal.ezchat.activity.P2PChatActivity;
import com.ezreal.ezchat.bean.RecentContactBean;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.suntek.commonlibrary.adapter.OnItemClickListener;
import com.suntek.commonlibrary.adapter.RViewHolder;
import com.suntek.commonlibrary.adapter.RecycleViewAdapter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by 张静.
*/
public class RecentMsgFragment extends BaseFragment {
private static final String TAG = RecentMsgFragment.class.getSimpleName();
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private List<RecentContactBean> mContactList;//最近联系人
private RecycleViewAdapter<RecentContactBean> mViewAdapter;
private Observer<List<RecentContact>> mObserver;
private SimpleDateFormat mDateFormat;
@Override
public int setLayoutID() {
return R.layout.fragment_message;
}
@Override
public void initView(View rootView) {
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.rcv_message_list);
mDateFormat = new SimpleDateFormat("HH:mm");
initRecyclerView();
initListener();
loadRecentList();
NIMClient.getService(MsgServiceObserve.class).observeRecentContact(mObserver,true);
}
private void initRecyclerView(){
mLayoutManager = new LinearLayoutManager(getContext());
mContactList = new ArrayList<>();
mRecyclerView.setLayoutManager(mLayoutManager);
mViewAdapter = new RecycleViewAdapter<RecentContactBean>(getContext(),mContactList) {
@Override
public int setItemLayoutId(int position) {
return R.layout.item_recent_msg;
}
@Override
public void bindView(RViewHolder holder, int position) {
RecentContactBean contactBean= mContactList.get(position);
holder.setImageByUrl(getContext(),R.id.iv_head_picture,
contactBean.getUserInfo().getAvatar(),R.mipmap.bg_img_defalut);
holder.setText(R.id.tv_recent_name,contactBean.getUserInfo().getName());
holder.setText(R.id.tv_recent_content,contactBean.getRecentContact().getContent());
String time = mDateFormat.format(new Date(contactBean.getRecentContact().getTime()));
holder.setText(R.id.tv_recent_time,time);
}
};
mViewAdapter.setItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(RViewHolder holder, int position) {
RecentContactBean contactBean = mContactList.get(position);
Intent intent;
if (contactBean.getRecentContact().getSessionType() == SessionTypeEnum.P2P){
intent = new Intent(getContext(), P2PChatActivity.class);
intent.putExtra("NimUserInfo",contactBean.getUserInfo());
startActivity(intent);
}
}
});
mRecyclerView.setAdapter(mViewAdapter);
}
private void initListener(){
mObserver = new Observer<List<RecentContact>>() {
@Override
public void onEvent(List<RecentContact> recentContacts) {
Log.e(TAG,"Observer RecentContact size = " + recentContacts.size());
if (mContactList.isEmpty()){
List<RecentContactBean> contactBeans = createContactBeans(recentContacts);
mContactList.addAll(contactBeans);
mViewAdapter.notifyDataSetChanged();
return;
}
for (RecentContact contact : recentContacts){
refreshRecentList(contact);
}
}
};
}
private void refreshRecentList(RecentContact contact){
for (int i=0;i<mContactList.size();i++){
RecentContactBean bean = mContactList.get(i);
if (bean.getRecentContact().getContactId().equals(contact.getContactId())){
bean.setRecentContact(contact);
mViewAdapter.notifyItemChanged(i);
break;
}else if (i == mContactList.size()-1){
// 否则为新的最近会话
RecentContactBean newBean = new RecentContactBean();
newBean.setRecentContact(contact);
newBean.setUserInfo(getUserInfoByAccount(contact.getContactId()));
mContactList.add(0,newBean);
}
}
}
@Override
public void onResume() {
super.onResume();
Log.e(TAG,"onResume");
}
@Override
public void onPause() {
super.onPause();
Log.e(TAG,"onPause");
}
private void loadRecentList(){
NIMClient.getService(MsgService.class).queryRecentContacts()
.setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
@Override
public void onResult(int code, List<RecentContact> result, Throwable exception) {
if (exception != null){
Log.e(TAG,"loadRecentList exception = " + exception.getMessage());
return;
}
if (code != 200){
Log.e(TAG,"loadRecentList error code = " + code);
return;
}
Log.e(TAG,"loadRecentList size = " + result.size());
List<RecentContactBean> contactBeans = createContactBeans(result);
mContactList.clear();
mContactList.addAll(contactBeans);
mViewAdapter.notifyDataSetChanged();
}
});
}
private List<RecentContactBean> createContactBeans(List<RecentContact> recentContacts){
List<RecentContactBean> beanList = new ArrayList<>();
RecentContactBean bean;
for (RecentContact contact : recentContacts){
bean = new RecentContactBean();
bean.setRecentContact(contact);
bean.setUserInfo(getUserInfoByAccount(contact.getContactId()));
beanList.add(bean);
}
return beanList;
}
private NimUserInfo getUserInfoByAccount(String account){
return NIMClient.getService(UserService.class).getUserInfo(account);
}
}
item_recent_msg.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@color/white_color"
android:layout_height="61dp"
android:gravity="center_vertical">
<LinearLayout
android:id="@+id/layout_recent_contact"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
<com.joooonho.SelectableRoundedImageView
android:layout_marginTop="5dp"
android:padding="5dp"
android:id="@+id/iv_head_picture"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
app:sriv_oval="true"/>
<LinearLayout
android:id="@+id/msg_detail"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/tv_recent_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/app_black_color"/>
<TextView
android:id="@+id/tv_recent_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxLines="1"
android:text="@string/test_msg"
android:textColor="@color/default_text_color"/>
</LinearLayout>
<TextView
android:id="@+id/tv_recent_time"
android:layout_marginLeft="5dp"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:text="@string/test_time"
android:textColor="@color/default_text_color"
android:visibility="visible"/>
</LinearLayout>
<View
android:layout_marginTop="5dp"
android:layout_below="@+id/layout_notify"
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:background="@color/interval_color"
android:layout_alignParentBottom="true"/>
</RelativeLayout>