環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-會(huì)話界面

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-ChatDemoUI3.0

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-LoginActivity

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-會(huì)話界面

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-通訊錄界面

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-設(shè)置界面

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-EaseUI

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-IM集成開(kāi)發(fā)詳案及具體代碼實(shí)現(xiàn)

現(xiàn)在來(lái)看具體的主界面的三個(gè)Fragment

主界面的三個(gè)fragment

會(huì)話界面

? 我們來(lái)看會(huì)話界面的代碼

package com.hyphenate.chatuidemo.ui;

?

import android.content.Intent;

import android.view.ContextMenu;

import android.view.ContextMenu.ContextMenuInfo;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.AdapterContextMenuInfo;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.Toast;

?

import com.easemob.redpacketsdk.constant.RPConstant;

import com.hyphenate.chat.EMClient;

import com.hyphenate.chat.EMConversation;

import com.hyphenate.chat.EMConversation.EMConversationType;

import com.hyphenate.chat.EMMessage;

import com.hyphenate.chatuidemo.Constant;

import com.hyphenate.chatuidemo.R;

import com.hyphenate.chatuidemo.db.InviteMessgeDao;

import com.hyphenate.easeui.model.EaseAtMessageHelper;

import com.hyphenate.easeui.ui.EaseConversationListFragment;

import com.hyphenate.easeui.widget.EaseConversationList.EaseConversationListHelper;

import com.hyphenate.util.NetUtils;

?

public class ConversationListFragment extends EaseConversationListFragment{

?

private TextView errorText;

?

@Override

protected void initView() {

super.initView();

View errorView = (LinearLayout) View.inflate(getActivity(),R.layout.em_chat_neterror_item, null);

errorItemContainer.addView(errorView);

errorText = (TextView) errorView.findViewById(R.id.tv_connect_errormsg);

}

@Override

protected void setUpView() {

super.setUpView();

// register context menu

registerForContextMenu(conversationListView);

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

String username = conversation.conversationId();

if (username.equals(EMClient.getInstance().getCurrentUser()))

Toast.makeText(getActivity(), R.string.Cant_chat_with_yourself, Toast.LENGTH_SHORT).show();

else {

// start chat acitivity

Intent intent = new Intent(getActivity(), ChatActivity.class);

if(conversation.isGroup()){

if(conversation.getType() == EMConversationType.ChatRoom){

// it's group chat

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_CHATROOM);

}else{

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_GROUP);

}

}

// it's single chat

intent.putExtra(Constant.EXTRA_USER_ID, username);

startActivity(intent);

}

}

});

//red packet code : 紅包回執(zhí)消息在會(huì)話列表最后一條消息的展示

conversationListView.setConversationListHelper(new EaseConversationListHelper() {

@Override

public String onSetItemSecondaryText(EMMessage lastMessage) {

if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {

String sendNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_SENDER_NAME, "");

String receiveNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_RECEIVER_NAME, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg = String.format(getResources().getString(R.string.msg_someone_take_red_packet), receiveNick);

} else {

if (sendNick.equals(receiveNick)) {

msg = getResources().getString(R.string.msg_take_red_packet);

} else {

msg = String.format(getResources().getString(R.string.msg_take_someone_red_packet), sendNick);

}

}

return msg;

} else if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_TRANSFER_PACKET_MESSAGE, false)) {

String transferAmount = lastMessage.getStringAttribute(RPConstant.EXTRA_TRANSFER_AMOUNT, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg =? String.format(getResources().getString(R.string.msg_transfer_to_you), transferAmount);

} else {

msg =? String.format(getResources().getString(R.string.msg_transfer_from_you),transferAmount);

}

return msg;

}

return null;

}

});

super.setUpView();

//end of red packet code

}

?

@Override

protected void onConnectionDisconnected() {

super.onConnectionDisconnected();

if (NetUtils.hasNetwork(getActivity())){

errorText.setText(R.string.can_not_connect_chat_server_connection);

} else {

errorText.setText(R.string.the_current_network);

}

}

@Override

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

getActivity().getMenuInflater().inflate(R.menu.em_delete_message, menu);

}

?

@Override

public boolean onContextItemSelected(MenuItem item) {

boolean deleteMessage = false;

if (item.getItemId() == R.id.delete_message) {

deleteMessage = true;

} else if (item.getItemId() == R.id.delete_conversation) {

deleteMessage = false;

}

EMConversation tobeDeleteCons = conversationListView.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);

if (tobeDeleteCons == null) {

return true;

}

if(tobeDeleteCons.getType() == EMConversationType.GroupChat){

EaseAtMessageHelper.get().removeAtMeGroup(tobeDeleteCons.conversationId());

}

try {

// delete conversation

EMClient.getInstance().chatManager().deleteConversation(tobeDeleteCons.conversationId(), deleteMessage);

InviteMessgeDao inviteMessgeDao = new InviteMessgeDao(getActivity());

inviteMessgeDao.deleteMessage(tobeDeleteCons.conversationId());

} catch (Exception e) {

e.printStackTrace();

}

refresh();

?

// update unread count

((MainActivity) getActivity()).updateUnreadLabel();

return true;

}

?

}

我們還是挨個(gè)來(lái)讀代碼

public class ConversationListFragment extends EaseConversationListFragment

來(lái),我們還是得先去找他爹算賬晋柱。

public class EaseConversationListFragment extends EaseBaseFragment

哎呀宠叼,我們?cè)偃フ宜麪敔敗?/p>

public abstract class EaseBaseFragment extends Fragment

爺爺終于正常點(diǎn)是從Android系統(tǒng)類繼承下來(lái)的了爪喘,我們看具體的代碼

EaseBaseFragment

package com.hyphenate.easeui.ui;

import android.content.Context;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.View;

import android.view.WindowManager;

import android.view.inputmethod.InputMethodManager;

import com.hyphenate.easeui.R;

import com.hyphenate.easeui.widget.EaseTitleBar;

public abstract class EaseBaseFragment extends Fragment{

protected EaseTitleBar titleBar;

protected InputMethodManager inputMethodManager;

@Override

public void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

//noinspection ConstantConditions

titleBar = (EaseTitleBar) getView().findViewById(R.id.title_bar);

initView();

setUpView();

}

public void showTitleBar(){

if(titleBar != null){

titleBar.setVisibility(View.VISIBLE);

}

}

public void hideTitleBar(){

if(titleBar != null){

titleBar.setVisibility(View.GONE);

}

}

protected void hideSoftKeyboard() {

if (getActivity().getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {

if (getActivity().getCurrentFocus() != null)

inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);

}

}

protected abstract void initView();

protected abstract void setUpView();

}

我們還是挨個(gè)來(lái)看代碼,研究他的功能浮庐。

@Override

public void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

//noinspection ConstantConditions

titleBar = (EaseTitleBar) getView().findViewById(R.id.title_bar);

initView();

setUpView();

}

隱藏輸入法

看到inputmethdManager要干嘛啊,隱藏鍵盤。果不其然夷陋。

protected void hideSoftKeyboard() {

if (getActivity().getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {

if (getActivity().getCurrentFocus() != null)

inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);

}

}

然后呢磅废?

初始化標(biāo)題頭?

//noinspection ConstantConditions

titleBar = (EaseTitleBar) getView().findViewById(R.id.title_bar);

最后初始化標(biāo)題頭母廷,并且讓子孫們?nèi)?shí)現(xiàn)抽象方法initView和setUpView().

隱藏和顯示標(biāo)題頭

其中還提供了兩個(gè)方法,隱藏和顯示標(biāo)題頭

public void showTitleBar(){

if(titleBar != null){

titleBar.setVisibility(View.VISIBLE);

}

}

public void hideTitleBar(){

if(titleBar != null){

titleBar.setVisibility(View.GONE);

}

}

好了贮泞,爺爺?shù)膸に阃炅俗拭粒覀儊?lái)找他兒子酬土。

EaseConversationListFragment

我們來(lái)看代碼

package com.hyphenate.easeui.ui;

?

import android.content.Context;

import android.os.Bundle;

import android.os.Handler;

import android.text.Editable;

import android.text.TextWatcher;

import android.util.Pair;

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.view.WindowManager;

import android.view.inputmethod.InputMethodManager;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.EditText;

import android.widget.FrameLayout;

import android.widget.ImageButton;

?

import com.hyphenate.EMConnectionListener;

import com.hyphenate.EMConversationListener;

import com.hyphenate.EMError;

import com.hyphenate.chat.EMClient;

import com.hyphenate.chat.EMConversation;

import com.hyphenate.easeui.R;

import com.hyphenate.easeui.widget.EaseConversationList;

?

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

import java.util.Map;

?

/**

* conversation list fragment

*

*/

public class EaseConversationListFragment extends EaseBaseFragment{

private final static int MSG_REFRESH = 2;

protected EditText query;

protected ImageButton clearSearch;

protected boolean hidden;

protected List conversationList = new ArrayList();

protected EaseConversationList conversationListView;

protected FrameLayout errorItemContainer;

?

protected boolean isConflict;

protected EMConversationListener convListener = new EMConversationListener(){

?

@Override

public void onCoversationUpdate() {

refresh();

}

};

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

return inflater.inflate(R.layout.ease_fragment_conversation_list, container, false);

}

?

@Override

public void onActivityCreated(Bundle savedInstanceState) {

if(savedInstanceState != null && savedInstanceState.getBoolean("isConflict", false))

return;

super.onActivityCreated(savedInstanceState);

}

?

@Override

protected void initView() {

inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

conversationListView = (EaseConversationList) getView().findViewById(R.id.list);

query = (EditText) getView().findViewById(R.id.query);

// button to clear content in search bar

clearSearch = (ImageButton) getView().findViewById(R.id.search_clear);

errorItemContainer = (FrameLayout) getView().findViewById(R.id.fl_error_item);

}

@Override

protected void setUpView() {

conversationList.addAll(loadConversationList());

conversationListView.init(conversationList);

if(listItemClickListener != null){

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

listItemClickListener.onListItemClicked(conversation);

}

});

}

EMClient.getInstance().addConnectionListener(connectionListener);

query.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence s, int start, int before, int count) {

conversationListView.filter(s);

if (s.length() > 0) {

clearSearch.setVisibility(View.VISIBLE);

} else {

clearSearch.setVisibility(View.INVISIBLE);

}

}

?

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

?

public void afterTextChanged(Editable s) {

}

});

clearSearch.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

query.getText().clear();

hideSoftKeyboard();

}

});

conversationListView.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

hideSoftKeyboard();

return false;

}

});

}

protected EMConnectionListener connectionListener = new EMConnectionListener() {

@Override

public void onDisconnected(int error) {

if (error == EMError.USER_REMOVED || error == EMError.USER_LOGIN_ANOTHER_DEVICE || error == EMError.SERVER_SERVICE_RESTRICTED) {

isConflict = true;

} else {

handler.sendEmptyMessage(0);

}

}

@Override

public void onConnected() {

handler.sendEmptyMessage(1);

}

};

private EaseConversationListItemClickListener listItemClickListener;

protected Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case 0:

onConnectionDisconnected();

break;

case 1:

onConnectionConnected();

break;

case MSG_REFRESH:

{

conversationList.clear();

conversationList.addAll(loadConversationList());

conversationListView.refresh();

break;

}

default:

break;

}

}

};

/**

* connected to server

*/

protected void onConnectionConnected(){

errorItemContainer.setVisibility(View.GONE);

}

/**

* disconnected with server

*/

protected void onConnectionDisconnected(){

errorItemContainer.setVisibility(View.VISIBLE);

}

?

/**

* refresh ui

*/

public void refresh() {

if(!handler.hasMessages(MSG_REFRESH)){

handler.sendEmptyMessage(MSG_REFRESH);

}

}

/**

* load conversation list

*

* @return

+? ? */

protected List loadConversationList(){

// get all conversations

Map conversations = EMClient.getInstance().chatManager().getAllConversations();

List> sortList = new ArrayList>();

/**

* lastMsgTime will change if there is new message during sorting

* so use synchronized to make sure timestamp of last message won't change.

*/

synchronized (conversations) {

for (EMConversation conversation : conversations.values()) {

if (conversation.getAllMessages().size() != 0) {

sortList.add(new Pair(conversation.getLastMessage().getMsgTime(), conversation));

}

}

}

try {

// Internal is TimSort algorithm, has bug

sortConversationByLastChatTime(sortList);

} catch (Exception e) {

e.printStackTrace();

}

List list = new ArrayList();

for (Pair sortItem : sortList) {

list.add(sortItem.second);

}

return list;

}

?

/**

* sort conversations according time stamp of last message

*

* @param conversationList

*/

private void sortConversationByLastChatTime(List> conversationList) {

Collections.sort(conversationList, new Comparator>() {

@Override

public int compare(final Pair con1, final Pair con2) {

?

if (con1.first.equals(con2.first)) {

return 0;

} else if (con2.first.longValue() > con1.first.longValue()) {

return 1;

} else {

return -1;

}

}

?

});

}

protected void hideSoftKeyboard() {

if (getActivity().getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {

if (getActivity().getCurrentFocus() != null)

inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);

}

}

?

@Override

public void onHiddenChanged(boolean hidden) {

super.onHiddenChanged(hidden);

this.hidden = hidden;

if (!hidden && !isConflict) {

refresh();

}

}

?

@Override

public void onResume() {

super.onResume();

if (!hidden) {

refresh();

}

}

@Override

public void onDestroy() {

super.onDestroy();

EMClient.getInstance().removeConnectionListener(connectionListener);

}

@Override

public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

if(isConflict){

outState.putBoolean("isConflict", true);

}

}

public interface EaseConversationListItemClickListener {

/**

* click event for conversation list

* @param conversation -- clicked item

*/

void onListItemClicked(EMConversation conversation);

}

/**

* set conversation list item click listener

* @param listItemClickListener

*/

public void setConversationListItemClickListener(EaseConversationListItemClickListener listItemClickListener){

this.listItemClickListener = listItemClickListener;

}

?

}

填充布局

首先onCreateView(),正常的填充了布局

return inflater.inflate(R.layout.ease_fragment_conversation_list, container, false);

繼續(xù)看代碼

@Override

public void onActivityCreated(Bundle savedInstanceState) {

if(savedInstanceState != null && savedInstanceState.getBoolean("isConflict", false))

return;

super.onActivityCreated(savedInstanceState);

}

判斷沖突標(biāo)志位

@Override

protected void initView() {

inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

conversationListView = (EaseConversationList) getView().findViewById(R.id.list);

query = (EditText) getView().findViewById(R.id.query);

// button to clear content in search bar

clearSearch = (ImageButton) getView().findViewById(R.id.search_clear);

errorItemContainer = (FrameLayout) getView().findViewById(R.id.fl_error_item);

}

initView()

覆寫爺爺?shù)募乙?guī),初始化View輸入法管理器

會(huì)話列表List

查找聯(lián)系人的輸入框

清除搜索的按鈕

errorItemContainer 錯(cuò)誤標(biāo)簽容器

繼續(xù)看代碼setUpView()方法

setUpView()

conversationList.addAll(loadConversationList());

conversationListView.init(conversationList);

?

if(listItemClickListener != null){

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

listItemClickListener.onListItemClicked(conversation);

}

});

}

?

EMClient.getInstance().addConnectionListener(connectionListener);

?

query.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence s, int start, int before, int count) {

conversationListView.filter(s);

if (s.length() > 0) {

clearSearch.setVisibility(View.VISIBLE);

} else {

clearSearch.setVisibility(View.INVISIBLE);

}

}

?

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

?

public void afterTextChanged(Editable s) {

}

});

clearSearch.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

query.getText().clear();

hideSoftKeyboard();

}

});

?

conversationListView.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

hideSoftKeyboard();

return false;

}

});

我們一句句的看

conversationList.addAll(loadConversationList());

conversationListView.init(conversationList);

會(huì)話列表添加全部以及數(shù)據(jù)填充初始化格带。

我們來(lái)看具體的方法

/**

* load conversation list

*

* @return

*/

protected List loadConversationList(){

// get all conversations

Map conversations = EMClient.getInstance().chatManager().getAllConversations();

List> sortList = new ArrayList>();

/**

* lastMsgTime will change if there is new message during sorting

* so use synchronized to make sure timestamp of last message won't change.

*/

synchronized (conversations) {

for (EMConversation conversation : conversations.values()) {

if (conversation.getAllMessages().size() != 0) {

sortList.add(new Pair(conversation.getLastMessage().getMsgTime(), conversation));

}

}

}

try {

// Internal is TimSort algorithm, has bug

sortConversationByLastChatTime(sortList);

} catch (Exception e) {

e.printStackTrace();

}

List list = new ArrayList();

for (Pair sortItem : sortList) {

list.add(sortItem.second);

}

return list;

}

loadConversationList()返回一個(gè)EMConversation對(duì)象List撤缴。

// get all conversations

Map conversations = EMClient.getInstance().chatManager().getAllConversations();

List> sortList = new ArrayList>();

通過(guò)封裝的chatManager拿到所有的會(huì)話列表

/**

* lastMsgTime will change if there is new message during sorting

* so use synchronized to make sure timestamp of last message won't change.

*/

synchronized (conversations) {

for (EMConversation conversation : conversations.values()) {

if (conversation.getAllMessages().size() != 0) {

sortList.add(new Pair(conversation.getLastMessage().getMsgTime(), conversation));

}

}

}

lastMsgTime會(huì)隨著新消息的到來(lái)排序發(fā)生改變刹枉,所以我們用同步方法確保最新消息的時(shí)間戳不發(fā)生改變。

英文不好屈呕,大致是這么個(gè)意思微宝。

try {

// Internal is TimSort algorithm, has bug

sortConversationByLastChatTime(sortList);

} catch (Exception e) {

e.printStackTrace();

}

List list = new ArrayList();

for (Pair sortItem : sortList) {

list.add(sortItem.second);

}

return list;

其中還特地注釋了一把,算法有點(diǎn)bug。

/**

* sort conversations according time stamp of last message

*

* @param conversationList

*/

private void sortConversationByLastChatTime(List> conversationList) {

Collections.sort(conversationList, new Comparator>() {

@Override

public int compare(final Pair con1, final Pair con2) {

?

if (con1.first.equals(con2.first)) {

return 0;

} else if (con2.first.longValue() > con1.first.longValue()) {

return 1;

} else {

return -1;

}

}

?

});

根據(jù)最新的會(huì)話時(shí)間戳來(lái)排序虎眨。

我們接著看

List list = new ArrayList();

for (Pair sortItem : sortList) {

list.add(sortItem.second);

}

return list;

添加完了返回list蟋软。

conversationListView.init(conversationList);

接著就初始化了。

if(listItemClickListener != null){

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

listItemClickListener.onListItemClicked(conversation);

}

});

}

然后便是連接接聽(tīng)

EMClient.getInstance().addConnectionListener(connectionListener);

添加了一個(gè)連接的監(jiān)聽(tīng)嗽桩。

protected EMConnectionListener connectionListener = new EMConnectionListener() {

@Override

public void onDisconnected(int error) {

if (error == EMError.USER_REMOVED || error == EMError.USER_LOGIN_ANOTHER_DEVICE || error == EMError.SERVER_SERVICE_RESTRICTED) {

isConflict = true;

} else {

handler.sendEmptyMessage(0);

}

}

@Override

public void onConnected() {

handler.sendEmptyMessage(1);

}

};

在斷開(kāi)連接時(shí)判斷用戶是否移除岳守,是否在其他設(shè)備登陸,或者服務(wù)端的服務(wù)受到限制碌冶,是的話則標(biāo)記沖突湿痢。不是則發(fā)送handler空消息。

protected Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case 0:

onConnectionDisconnected();

break;

case 1:

onConnectionConnected();

break;

case MSG_REFRESH:

{

conversationList.clear();

conversationList.addAll(loadConversationList());

conversationListView.refresh();

break;

}

default:

break;

}

}

};

干嘛捌伺印蒙袍?調(diào)用 onConnectionDisconnected 即連接斷開(kāi)的處理方法

/**

* disconnected with server

*/

protected void onConnectionDisconnected(){

errorItemContainer.setVisibility(View.VISIBLE);

}

即顯示錯(cuò)誤條。

我們?cè)俳又创a

query.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence s, int start, int before, int count) {

conversationListView.filter(s);

if (s.length() > 0) {

clearSearch.setVisibility(View.VISIBLE);

} else {

clearSearch.setVisibility(View.INVISIBLE);

}

}

?

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

?

public void afterTextChanged(Editable s) {

}

});

clearSearch.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

query.getText().clear();

hideSoftKeyboard();

}

});

?

conversationListView.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

hideSoftKeyboard();

return false;

}

});

干了些什么澳奂贰害幅?查詢、清除搜索岂昭、會(huì)話列表點(diǎn)擊監(jiān)聽(tīng)以现。

其他方法?

/**

* connected to server

*/

protected void onConnectionConnected(){

errorItemContainer.setVisibility(View.GONE);

}

連接后將錯(cuò)誤條隱藏

case MSG_REFRESH:

{

conversationList.clear();

conversationList.addAll(loadConversationList());

conversationListView.refresh();

break;

}

服務(wù)器告訴要刷新了,那么我們就去清楚列表约啊,然后去服務(wù)器拿并排序邑遏,然后刷新listview。其中該listview為自定義的EaseConversationList恰矩。

那么兒子齊活了记盒,我們?cè)倏磳O子

ConversationListFragment

package com.hyphenate.chatuidemo.ui;

?

import android.content.Intent;

import android.view.ContextMenu;

import android.view.ContextMenu.ContextMenuInfo;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.AdapterContextMenuInfo;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.Toast;

?

import com.easemob.redpacketsdk.constant.RPConstant;

import com.hyphenate.chat.EMClient;

import com.hyphenate.chat.EMConversation;

import com.hyphenate.chat.EMConversation.EMConversationType;

import com.hyphenate.chat.EMMessage;

import com.hyphenate.chatuidemo.Constant;

import com.hyphenate.chatuidemo.R;

import com.hyphenate.chatuidemo.db.InviteMessgeDao;

import com.hyphenate.easeui.model.EaseAtMessageHelper;

import com.hyphenate.easeui.ui.EaseConversationListFragment;

import com.hyphenate.easeui.widget.EaseConversationList.EaseConversationListHelper;

import com.hyphenate.util.NetUtils;

?

public class ConversationListFragment extends EaseConversationListFragment{

?

private TextView errorText;

?

@Override

protected void initView() {

super.initView();

View errorView = (LinearLayout) View.inflate(getActivity(),R.layout.em_chat_neterror_item, null);

errorItemContainer.addView(errorView);

errorText = (TextView) errorView.findViewById(R.id.tv_connect_errormsg);

}

@Override

protected void setUpView() {

super.setUpView();

// register context menu

registerForContextMenu(conversationListView);

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

String username = conversation.conversationId();

if (username.equals(EMClient.getInstance().getCurrentUser()))

Toast.makeText(getActivity(), R.string.Cant_chat_with_yourself, Toast.LENGTH_SHORT).show();

else {

// start chat acitivity

Intent intent = new Intent(getActivity(), ChatActivity.class);

if(conversation.isGroup()){

if(conversation.getType() == EMConversationType.ChatRoom){

// it's group chat

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_CHATROOM);

}else{

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_GROUP);

}

}

// it's single chat

intent.putExtra(Constant.EXTRA_USER_ID, username);

startActivity(intent);

}

}

});

//red packet code : 紅包回執(zhí)消息在會(huì)話列表最后一條消息的展示

conversationListView.setConversationListHelper(new EaseConversationListHelper() {

@Override

public String onSetItemSecondaryText(EMMessage lastMessage) {

if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {

String sendNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_SENDER_NAME, "");

String receiveNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_RECEIVER_NAME, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg = String.format(getResources().getString(R.string.msg_someone_take_red_packet), receiveNick);

} else {

if (sendNick.equals(receiveNick)) {

msg = getResources().getString(R.string.msg_take_red_packet);

} else {

msg = String.format(getResources().getString(R.string.msg_take_someone_red_packet), sendNick);

}

}

return msg;

} else if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_TRANSFER_PACKET_MESSAGE, false)) {

String transferAmount = lastMessage.getStringAttribute(RPConstant.EXTRA_TRANSFER_AMOUNT, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg =? String.format(getResources().getString(R.string.msg_transfer_to_you), transferAmount);

} else {

msg =? String.format(getResources().getString(R.string.msg_transfer_from_you),transferAmount);

}

return msg;

}

return null;

}

});

super.setUpView();

//end of red packet code

}

?

@Override

protected void onConnectionDisconnected() {

super.onConnectionDisconnected();

if (NetUtils.hasNetwork(getActivity())){

errorText.setText(R.string.can_not_connect_chat_server_connection);

} else {

errorText.setText(R.string.the_current_network);

}

}

@Override

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

getActivity().getMenuInflater().inflate(R.menu.em_delete_message, menu);

}

?

@Override

public boolean onContextItemSelected(MenuItem item) {

boolean deleteMessage = false;

if (item.getItemId() == R.id.delete_message) {

deleteMessage = true;

} else if (item.getItemId() == R.id.delete_conversation) {

deleteMessage = false;

}

EMConversation tobeDeleteCons = conversationListView.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);

if (tobeDeleteCons == null) {

return true;

}

if(tobeDeleteCons.getType() == EMConversationType.GroupChat){

EaseAtMessageHelper.get().removeAtMeGroup(tobeDeleteCons.conversationId());

}

try {

// delete conversation

EMClient.getInstance().chatManager().deleteConversation(tobeDeleteCons.conversationId(), deleteMessage);

InviteMessgeDao inviteMessgeDao = new InviteMessgeDao(getActivity());

inviteMessgeDao.deleteMessage(tobeDeleteCons.conversationId());

} catch (Exception e) {

e.printStackTrace();

}

refresh();

?

// update unread count

((MainActivity) getActivity()).updateUnreadLabel();

return true;

}

?

}

initView()

@Override

protected void initView() {

super.initView();

View errorView = (LinearLayout) View.inflate(getActivity(),R.layout.em_chat_neterror_item, null);

errorItemContainer.addView(errorView);

errorText = (TextView) errorView.findViewById(R.id.tv_connect_errormsg);

}

添加了錯(cuò)誤的容器、初始化錯(cuò)誤消息控件外傅。

registerForContextMenu(conversationListView);

注冊(cè)上下文菜單

conversationListView.setOnItemClickListener(new OnItemClickListener() {

?

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

EMConversation conversation = conversationListView.getItem(position);

String username = conversation.conversationId();

if (username.equals(EMClient.getInstance().getCurrentUser()))

Toast.makeText(getActivity(), R.string.Cant_chat_with_yourself, Toast.LENGTH_SHORT).show();

else {

// start chat acitivity

Intent intent = new Intent(getActivity(), ChatActivity.class);

if(conversation.isGroup()){

if(conversation.getType() == EMConversationType.ChatRoom){

// it's group chat

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_CHATROOM);

}else{

intent.putExtra(Constant.EXTRA_CHAT_TYPE, Constant.CHATTYPE_GROUP);

}

}

// it's single chat

intent.putExtra(Constant.EXTRA_USER_ID, username);

startActivity(intent);

}

}

});

條目的點(diǎn)擊監(jiān)聽(tīng)

其中做了這么些事情:

判斷用戶名是否等于當(dāng)前登陸用戶纪吮,是則提示不能跟自己聊天

如果是群聊的話,則繼續(xù)判斷是聊天室還是群組萎胰,并帶值給ChatActivity即聊天界面

最后將用戶名帶上碾盟,跳轉(zhuǎn)ChatActivity。

//red packet code : 紅包回執(zhí)消息在會(huì)話列表最后一條消息的展示

conversationListView.setConversationListHelper(new EaseConversationListHelper() {

@Override

public String onSetItemSecondaryText(EMMessage lastMessage) {

if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {

String sendNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_SENDER_NAME, "");

String receiveNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_RECEIVER_NAME, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg = String.format(getResources().getString(R.string.msg_someone_take_red_packet), receiveNick);

} else {

if (sendNick.equals(receiveNick)) {

msg = getResources().getString(R.string.msg_take_red_packet);

} else {

msg = String.format(getResources().getString(R.string.msg_take_someone_red_packet), sendNick);

}

}

return msg;

} else if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_TRANSFER_PACKET_MESSAGE, false)) {

String transferAmount = lastMessage.getStringAttribute(RPConstant.EXTRA_TRANSFER_AMOUNT, "");

String msg;

if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {

msg =? String.format(getResources().getString(R.string.msg_transfer_to_you), transferAmount);

} else {

msg =? String.format(getResources().getString(R.string.msg_transfer_from_you),transferAmount);

}

return msg;

}

return null;

}

});

super.setUpView();

最后是紅包回執(zhí)信息技竟。

我們接著看其他的方法

@Override

protected void onConnectionDisconnected() {

super.onConnectionDisconnected();

if (NetUtils.hasNetwork(getActivity())){

errorText.setText(R.string.can_not_connect_chat_server_connection);

} else {

errorText.setText(R.string.the_current_network);

}

}

端口網(wǎng)絡(luò)則提示沒(méi)網(wǎng)標(biāo)簽冰肴。

@Override

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

getActivity().getMenuInflater().inflate(R.menu.em_delete_message, menu);

}

創(chuàng)建上下文菜單

@Overridepublic boolean onContextItemSelected(MenuItem item) {? ? boolean deleteMessage = false;? ? if (item.getItemId() == R.id.delete_message) {? ? ? ? deleteMessage = true;? ? } else if (item.getItemId() == R.id.delete_conversation) {? ? ? ? deleteMessage = false;? ? }? EMConversation tobeDeleteCons = conversationListView.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);? if (tobeDeleteCons == null) {? ? ? return true;? }? ? if(tobeDeleteCons.getType() == EMConversationType.GroupChat){? ? ? ? EaseAtMessageHelper.get().removeAtMeGroup(tobeDeleteCons.conversationId());? ? }? ? try {? ? ? ? // delete conversation? ? ? ? EMClient.getInstance().chatManager().deleteConversation(tobeDeleteCons.conversationId(), deleteMessage);? ? ? ? InviteMessgeDao inviteMessgeDao = new InviteMessgeDao(getActivity());? ? ? ? inviteMessgeDao.deleteMessage(tobeDeleteCons.conversationId());? ? } catch (Exception e) {? ? ? ? e.printStackTrace();? ? }? ? refresh();?? ? // update unread count[url=http://www.imgeek.org/article/825308690]環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-通訊錄界面[/url]? ? ((MainActivity) getActivity()).updateUnreadLabel();? ? return true;}

上下文菜單選擇的處理方法

刪除消息并更新未讀消息。

好,至此熙尉,第一個(gè)界面联逻,會(huì)話界面到此結(jié)束。

我們?cè)賮?lái)看通訊錄界面检痰。

環(huán)信官方Demo源碼分析及SDK簡(jiǎn)單應(yīng)用-主界面的三個(gè)fragment-通訊錄界面

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末包归,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子攀细,更是在濱河造成了極大的恐慌,老刑警劉巖爱态,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谭贪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡锦担,警方通過(guò)查閱死者的電腦和手機(jī)俭识,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洞渔,“玉大人套媚,你說(shuō)我怎么就攤上這事〈沤罚” “怎么了堤瘤?”我有些...
    開(kāi)封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)浆熔。 經(jīng)常有香客問(wèn)我本辐,道長(zhǎng),這世上最難降的妖魔是什么医增? 我笑而不...
    開(kāi)封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任慎皱,我火速辦了婚禮,結(jié)果婚禮上叶骨,老公的妹妹穿的比我還像新娘茫多。我一直安慰自己,他們只是感情好忽刽,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布天揖。 她就那樣靜靜地躺著,像睡著了一般跪帝。 火紅的嫁衣襯著肌膚如雪宝剖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天歉甚,我揣著相機(jī)與錄音万细,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赖钞,可吹牛的內(nèi)容都是我干的腰素。 我是一名探鬼主播雪营,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谴餐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起器紧,我...
    開(kāi)封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤桥状,失蹤者是張志新(化名)和其女友劉穎芦拿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年日月,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尺借。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片串前。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玫膀,我是刑警寧澤灵妨,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響呀酸,放射性物質(zhì)發(fā)生泄漏茎杂。R本人自食惡果不足惜羞海,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望院水。 院中可真熱鬧腊徙,春花似錦、人聲如沸檬某。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)恢恼。三九已至民傻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厅瞎,已是汗流浹背饰潜。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留和簸,地道東北人彭雾。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锁保,于是被迫代替她去往敵國(guó)和親薯酝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子半沽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容