首次提交
46
tuiconversation/build.gradle
Normal file
@@ -0,0 +1,46 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
}
|
||||
//apply from: "../MobSdk.gradle"
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
res.srcDirs += "src/main/res-minimalistui"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate{
|
||||
generateReleaseBuildConfig.enabled =false
|
||||
generateDebugBuildConfig.enabled =false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.7'
|
||||
api 'org.greenrobot:eventbus:3.1.1'
|
||||
|
||||
api project(':tuicore')
|
||||
}
|
||||
39
tuiconversation/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tencent.qcloud.tuikit.tuiconversation">
|
||||
|
||||
<application>
|
||||
<provider
|
||||
android:name=".TUIConversationService"
|
||||
android:authorities="${applicationId}.TUIConversation.Init"
|
||||
android:enabled="true"
|
||||
android:exported="false"/>
|
||||
|
||||
|
||||
<!-- **************** Classic UI Activity Start **************** -->
|
||||
<activity
|
||||
android:name=".classicui.page.TUIForwardSelectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".classicui.page.TUIFoldedConversationActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<!-- **************** Classic UI Activity End **************** -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- **************** Minimalist UI Activity Start **************** -->
|
||||
<activity
|
||||
android:name=".minimalistui.page.TUIForwardSelectMinimalistActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".minimalistui.page.TUIFoldedConversationMinimalistActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<!-- **************** Minimalist UI Activity End **************** -->
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation;
|
||||
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUINotification;
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIService;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ITUIConversationService extends ITUIService, ITUINotification {
|
||||
|
||||
/**
|
||||
* 1、获取会话是否置顶;
|
||||
* @param method TUIConstants.TUIConversation.METHOD_IS_TOP_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CHAT_ID : String}
|
||||
* @return {TUIConstants.TUIConversation.IS_TOP : Boolean}
|
||||
* 2、设置会话置顶;
|
||||
* @param method TUIConstants.TUIConversation.METHOD_SET_TOP_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CHAT_ID : String, TUIConstants.TUIConversation.IS_SET_TOP : Boolean}
|
||||
* 3、获取未读总数;
|
||||
* @param method TUIConstants.TUIConversation.METHOD_GET_TOTAL_UNREAD_COUNT
|
||||
* @return 未读总数
|
||||
* 4、更新未读总数;
|
||||
* @param method TUIConstants.TUIConversation.METHOD_UPDATE_TOTAL_UNREAD_COUNT
|
||||
* 5、删除会话。
|
||||
* @param method TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CONVERSATION_ID : String}
|
||||
*
|
||||
*
|
||||
* 1、Get whether the conversation is sticky
|
||||
* @param method TUIConstants.TUIConversation.METHOD_IS_TOP_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CHAT_ID : String}
|
||||
* @return {TUIConstants.TUIConversation.IS_TOP : Boolean}
|
||||
* 2、Set session sticky
|
||||
* @param method TUIConstants.TUIConversation.METHOD_SET_TOP_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CHAT_ID : String, TUIConstants.TUIConversation.IS_SET_TOP : Boolean}
|
||||
* 3、Get the total number of unreads
|
||||
* @param method TUIConstants.TUIConversation.METHOD_GET_TOTAL_UNREAD_COUNT
|
||||
* @return the total number of unreads
|
||||
* 4、Update the total number of unreads
|
||||
* @param method TUIConstants.TUIConversation.METHOD_UPDATE_TOTAL_UNREAD_COUNT
|
||||
* 5、Delete conversation
|
||||
* @param method TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION
|
||||
* @param param {TUIConstants.TUIConversation.CONVERSATION_ID : String}
|
||||
*/
|
||||
@Override
|
||||
Object onCall(String method, Map<String, Object> param);
|
||||
|
||||
/**
|
||||
* 1、接收退群通知;
|
||||
* @param key TUIConstants.TUIGroup.EVENT_GROUP
|
||||
* @param subKey TUIConstants.TUIGroup.EVENT_SUB_KEY_EXIT_GROUP,
|
||||
* TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_DISMISS,
|
||||
* TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_RECYCLE
|
||||
* @param param {TUIConstants.TUIGroup.GROUP_ID : String}
|
||||
* 2、接收群成员退出群通知:
|
||||
* @param key TUIConstants.TUIGroup.EVENT_GROUP
|
||||
* @param subKey TUIConstants.TUIGroup.EVENT_SUB_KEY_MEMBER_KICKED_GROUP
|
||||
* @param param {TUIConstants.TUIGroup.GROUP_ID : String, TUIConstants.TUIGroup.GROUP_MEMBER_ID_LIST : ArrayList<String>}
|
||||
* 3、接收好友备注修改通知。
|
||||
* @param key TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED
|
||||
* @param subKey TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED
|
||||
* @param param {TUIConstants.TUIContact.FRIEND_ID : String, TUIConstants.TUIContact.FRIEND_REMARK : String}
|
||||
*
|
||||
*
|
||||
* 1、Receive notifications of exit group
|
||||
* @param key TUIConstants.TUIGroup.EVENT_GROUP
|
||||
* @param subKey TUIConstants.TUIGroup.EVENT_SUB_KEY_EXIT_GROUP,
|
||||
* TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_DISMISS,
|
||||
* TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_RECYCLE
|
||||
* @param param {TUIConstants.TUIGroup.GROUP_ID : String}
|
||||
* 2、Receive group members leaving the group notification
|
||||
* @param key TUIConstants.TUIGroup.EVENT_GROUP
|
||||
* @param subKey TUIConstants.TUIGroup.EVENT_SUB_KEY_MEMBER_KICKED_GROUP
|
||||
* @param param {TUIConstants.TUIGroup.GROUP_ID : String, TUIConstants.TUIGroup.GROUP_MEMBER_ID_LIST : ArrayList<String>}
|
||||
* 3、Receive notification of friend's note modification
|
||||
* @param key TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED
|
||||
* @param subKey TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED
|
||||
* @param param {TUIConstants.TUIContact.FRIEND_ID : String, TUIConstants.TUIContact.FRIEND_REMARK : String}
|
||||
*/
|
||||
@Override
|
||||
void onNotifyEvent(String key, String subKey, Map<String, Object> param);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation;
|
||||
|
||||
public class TUIConversationConstants {
|
||||
public static final String FORWARD_SELECT_CONVERSATION_KEY = "forward_select_conversation_key";
|
||||
public static final int FORWARD_SELECT_ACTIVTY_CODE = 101;
|
||||
public static final int FORWARD_SELECT_MEMBERS_CODE = 102;
|
||||
public static final int FORWARD_CREATE_GROUP_CODE = 103;
|
||||
public static final String FORWARD_CREATE_NEW_CHAT = "forward_create_new_chat";
|
||||
|
||||
public static String covert2HTMLString(String original) {
|
||||
return "\"<font color=\"#5B6B92\">" + original + "</font>\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* 1: 仅仅是一个带链接的文本消息
|
||||
* 2: iOS支持的视频通话版本,后续已经不兼容
|
||||
* 3: 未发布版本
|
||||
* 4: Android/iOS/Web互通的视频通话版本
|
||||
*
|
||||
* 1: Just a text message with a link
|
||||
* 2: The video calling version supported by iOS is no longer compatible
|
||||
* 3: unreleased version
|
||||
* 4: Android/iOS/Web interoperable version for video call
|
||||
*/
|
||||
public static final int JSON_VERSION_UNKNOWN = 0;
|
||||
public static final int JSON_VERSION_1 = 1;
|
||||
public static final int JSON_VERSION_4 = 4;
|
||||
public static int version = JSON_VERSION_4;
|
||||
|
||||
public static class GroupType {
|
||||
public static final String TYPE = "type";
|
||||
public static final String GROUP = "isGroup";
|
||||
public static final int PRIVATE = 0;
|
||||
public static final int PUBLIC = 1;
|
||||
public static final int CHAT_ROOM = 2;
|
||||
public static final int COMMUNITY = 3;
|
||||
}
|
||||
|
||||
public static final String CONVERSATION_SETTINGS_SP_NAME = "conversation_settings_sp";
|
||||
public static final String HIDE_FOLD_ITEM_SP_KEY_PREFIX = "hide_fold_item_";
|
||||
public static final String FOLD_ITEM_IS_UNREAD_SP_KEY_PREFIX = "fold_item_is_unread_";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListener;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMSDKListener;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.ServiceInitializer;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationEventListener;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIConversationService extends ServiceInitializer implements ITUIConversationService {
|
||||
public static final String TAG = TUIConversationService.class.getSimpleName();
|
||||
private static TUIConversationService instance;
|
||||
|
||||
public static TUIConversationService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
private boolean syncFinished = false;
|
||||
|
||||
private WeakReference<ConversationEventListener> conversationEventListener;
|
||||
private final List<WeakReference<ConversationEventListener>> conversationEventListenerList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
instance = this;
|
||||
initService();
|
||||
initEvent();
|
||||
initIMListener();
|
||||
}
|
||||
|
||||
private void initService() {
|
||||
TUICore.registerService(TUIConstants.TUIConversation.SERVICE_NAME, this);
|
||||
}
|
||||
|
||||
private void initEvent() {
|
||||
TUICore.registerEvent(TUIConstants.TUIGroup.EVENT_GROUP, TUIConstants.TUIGroup.EVENT_SUB_KEY_EXIT_GROUP, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIGroup.EVENT_GROUP, TUIConstants.TUIGroup.EVENT_SUB_KEY_MEMBER_KICKED_GROUP, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIGroup.EVENT_GROUP, TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_DISMISS, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIGroup.EVENT_GROUP, TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_RECYCLE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED, TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIGroup.EVENT_GROUP, TUIConstants.TUIGroup.EVENT_SUB_KEY_CLEAR_MESSAGE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_USER, TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_MESSAGE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIChat.EVENT_KEY_RECEIVE_MESSAGE, TUIConstants.TUIChat.EVENT_SUB_KEY_CONVERSATION_ID, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIConversation.EVENT_KEY_MESSAGE_SEND_FOR_CONVERSATION, TUIConstants.TUIConversation.EVENT_SUB_KEY_MESSAGE_SEND_FOR_CONVERSATION, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onCall(String method, Map<String, Object> param) {
|
||||
Bundle result = new Bundle();
|
||||
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener == null) {
|
||||
TUIConversationLog.e(TAG, "execute " + method + " failed , conversationEvent listener is null");
|
||||
return result;
|
||||
}
|
||||
if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_IS_TOP_CONVERSATION, method)) {
|
||||
String chatId = (String) param.get(TUIConstants.TUIConversation.CHAT_ID);
|
||||
if (!TextUtils.isEmpty(chatId)) {
|
||||
boolean isTop = conversationEventListener.isTopConversation(chatId);
|
||||
result.putBoolean(TUIConstants.TUIConversation.IS_TOP, isTop);
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_SET_TOP_CONVERSATION, method)) {
|
||||
String chatId = (String) param.get(TUIConstants.TUIConversation.CHAT_ID);
|
||||
boolean isTop = (boolean) param.get(TUIConstants.TUIConversation.IS_SET_TOP);
|
||||
if (!TextUtils.isEmpty(chatId)) {
|
||||
conversationEventListener.setConversationTop(chatId, isTop, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_GET_TOTAL_UNREAD_COUNT, method)) {
|
||||
return conversationEventListener.getUnreadTotal();
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_UPDATE_TOTAL_UNREAD_COUNT, method)) {
|
||||
HashMap<String, Object> unreadMap = new HashMap<>();
|
||||
long totalUnread = conversationEventListener.getUnreadTotal();
|
||||
unreadMap.put(TUIConstants.TUIConversation.TOTAL_UNREAD_COUNT, totalUnread);
|
||||
TUICore.notifyEvent(TUIConstants.TUIConversation.EVENT_UNREAD, TUIConstants.TUIConversation.EVENT_SUB_KEY_UNREAD_CHANGED, unreadMap);
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION, method)) {
|
||||
String conversationId = (String) param.get(TUIConstants.TUIConversation.CONVERSATION_ID);
|
||||
conversationEventListener.clearFoldMarkAndDeleteConversation(conversationId);
|
||||
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.clearFoldMarkAndDeleteConversation(conversationId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyEvent(String key, String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(key, TUIConstants.TUIGroup.EVENT_GROUP)) {
|
||||
if (TextUtils.equals(subKey, TUIConstants.TUIGroup.EVENT_SUB_KEY_EXIT_GROUP)
|
||||
|| TextUtils.equals(subKey, TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_DISMISS)
|
||||
|| TextUtils.equals(subKey, TUIConstants.TUIGroup.EVENT_SUB_KEY_GROUP_RECYCLE)) {
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
String groupId = null;
|
||||
if (param != null) {
|
||||
groupId = (String) getOrDefault(param.get(TUIConstants.TUIGroup.GROUP_ID), "");
|
||||
}
|
||||
if (eventListener != null) {
|
||||
eventListener.deleteConversation(groupId, true);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.deleteConversation(groupId, true);
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConstants.TUIGroup.EVENT_SUB_KEY_MEMBER_KICKED_GROUP)) {
|
||||
if (param == null) {
|
||||
return;
|
||||
}
|
||||
String groupId = (String) getOrDefault(param.get(TUIConstants.TUIGroup.GROUP_ID), "");
|
||||
ArrayList<String> memberList = (ArrayList<String>) param.get(TUIConstants.TUIGroup.GROUP_MEMBER_ID_LIST);
|
||||
if (TextUtils.isEmpty(groupId) || memberList == null || memberList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String id : memberList) {
|
||||
if (TextUtils.equals(id, TUILogin.getLoginUser())) {
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.deleteConversation(groupId, true);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.deleteConversation(groupId, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConstants.TUIGroup.EVENT_SUB_KEY_CLEAR_MESSAGE)) {
|
||||
String groupId = (String) getOrDefault(param.get(TUIConstants.TUIGroup.GROUP_ID), "");
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.clearConversationMessage(groupId, true);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.clearConversationMessage(groupId, true);
|
||||
}
|
||||
}
|
||||
} else if (key.equals(TUIConstants.TUIContact.EVENT_USER)) {
|
||||
if (subKey.equals(TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_MESSAGE)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String userID = (String) getOrDefault(param.get(TUIConstants.TUIContact.FRIEND_ID), "");
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.clearConversationMessage(userID, false);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.clearConversationMessage(userID, false);
|
||||
}
|
||||
}
|
||||
} else if (key.equals(TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED)) {
|
||||
if (subKey.equals(TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener == null) {
|
||||
return;
|
||||
}
|
||||
String id = (String) param.get(TUIConstants.TUIContact.FRIEND_ID);
|
||||
String remark = (String) param.get(TUIConstants.TUIContact.FRIEND_REMARK);
|
||||
conversationEventListener.onFriendRemarkChanged(id ,remark);
|
||||
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onFriendRemarkChanged(id, remark);
|
||||
}
|
||||
}
|
||||
} else if (key.equals(TUIConstants.TUIChat.EVENT_KEY_RECEIVE_MESSAGE)) {
|
||||
if (subKey.equals(TUIConstants.TUIChat.EVENT_SUB_KEY_CONVERSATION_ID)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String conversationID = (String) param.get(TUIConstants.TUIChat.CONVERSATION_ID);
|
||||
boolean isTypingMessage = false;
|
||||
if (param.containsKey(TUIConstants.TUIChat.IS_TYPING_MESSAGE)) {
|
||||
isTypingMessage = (Boolean) param.get(TUIConstants.TUIChat.IS_TYPING_MESSAGE);
|
||||
}
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onReceiveMessage(conversationID, isTypingMessage);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onReceiveMessage(conversationID, isTypingMessage);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (TextUtils.equals(key, TUIConstants.TUIConversation.EVENT_KEY_MESSAGE_SEND_FOR_CONVERSATION)) {
|
||||
if (TextUtils.equals(subKey, TUIConstants.TUIConversation.EVENT_SUB_KEY_MESSAGE_SEND_FOR_CONVERSATION)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String conversationID = (String) param.get(TUIConstants.TUIConversation.CONVERSATION_ID);
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.onMessageSendForHideConversation(conversationID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object getOrDefault(Object value, Object defaultValue) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private void initIMListener() {
|
||||
V2TIMManager.getConversationManager().addConversationListener(new V2TIMConversationListener() {
|
||||
@Override
|
||||
public void onSyncServerStart() {
|
||||
syncFinished = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFinish() {
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onSyncServerFinish();
|
||||
}
|
||||
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onSyncServerFinish();
|
||||
}
|
||||
|
||||
syncFinished = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFailed() {
|
||||
syncFinished = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewConversation(List<V2TIMConversation> conversationList) {
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onNewConversation(conversationInfoList);
|
||||
}
|
||||
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onNewConversation(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<V2TIMConversation> conversationList) {
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.updateTotalUnreadMessageCount(totalUnreadCount);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.updateTotalUnreadMessageCount(totalUnreadCount);
|
||||
}
|
||||
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.TOTAL_UNREAD_COUNT, totalUnreadCount);
|
||||
TUICore.notifyEvent(TUIConstants.TUIConversation.EVENT_UNREAD, TUIConstants.TUIConversation.EVENT_SUB_KEY_UNREAD_CHANGED, param);
|
||||
}
|
||||
});
|
||||
|
||||
V2TIMSDKListener v2TIMSDKListener = new V2TIMSDKListener() {
|
||||
@Override
|
||||
public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {
|
||||
ConversationEventListener conversationEventListener = getInstance().getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onUserStatusChanged(userStatusList);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for(ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onUserStatusChanged(userStatusList);
|
||||
}
|
||||
}
|
||||
};
|
||||
V2TIMManager.getInstance().addIMSDKListener(v2TIMSDKListener);
|
||||
}
|
||||
|
||||
public void addConversationEventListener(ConversationEventListener conversationEventListener) {
|
||||
if (conversationEventListener == null) {
|
||||
return;
|
||||
}
|
||||
for (WeakReference<ConversationEventListener> listenerWeakReference : conversationEventListenerList) {
|
||||
if (listenerWeakReference.get() == conversationEventListener) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
conversationEventListenerList.add(new WeakReference<>(conversationEventListener));
|
||||
}
|
||||
|
||||
public List<ConversationEventListener> getConversationEventListenerList() {
|
||||
List<ConversationEventListener> listeners = new ArrayList<>();
|
||||
Iterator<WeakReference<ConversationEventListener>> iterator = conversationEventListenerList.listIterator();
|
||||
while(iterator.hasNext()) {
|
||||
WeakReference<ConversationEventListener> listenerWeakReference = iterator.next();
|
||||
ConversationEventListener listener = listenerWeakReference.get();
|
||||
if (listener == null) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public void setConversationEventListener(ConversationEventListener conversationManagerKit) {
|
||||
this.conversationEventListener = new WeakReference<>(conversationManagerKit);
|
||||
if (syncFinished) {
|
||||
conversationManagerKit.onSyncServerFinish();
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationEventListener getConversationEventListener() {
|
||||
if (conversationEventListener != null) {
|
||||
return conversationEventListener.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addMessageListener() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupAtInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationInfo implements Serializable, Comparable<ConversationInfo> {
|
||||
|
||||
public static final int TYPE_COMMON = 1;
|
||||
public static final int TYPE_CUSTOM = 2;
|
||||
|
||||
public static final int TYPE_FORWAR_SELECT = 3;
|
||||
public static final int TYPE_RECENT_LABEL = 4;
|
||||
/**
|
||||
* 会话类型,自定义会话or普通会话
|
||||
*
|
||||
* conversation type
|
||||
*/
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* 消息未读数
|
||||
*
|
||||
* unread message number
|
||||
*/
|
||||
private int unRead;
|
||||
/**
|
||||
* 会话ID
|
||||
*
|
||||
* conversation ID
|
||||
*/
|
||||
private String conversationId;
|
||||
/**
|
||||
* 会话标识,C2C为对方用户ID,群聊为群组ID
|
||||
*
|
||||
* ID, C2C is UserID, Group is group ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
private int statusType = V2TIMUserStatus.V2TIM_USER_STATUS_UNKNOWN;
|
||||
|
||||
private V2TIMConversation conversation;
|
||||
|
||||
|
||||
private List<Object> iconUrlList = new ArrayList<>();
|
||||
|
||||
public List<Object> getIconUrlList() {
|
||||
return iconUrlList;
|
||||
}
|
||||
|
||||
public void setIconUrlList(List<Object> iconUrlList) {
|
||||
this.iconUrlList = iconUrlList;
|
||||
}
|
||||
|
||||
public V2TIMConversation getConversation() {
|
||||
return conversation;
|
||||
}
|
||||
|
||||
public void setConversation(V2TIMConversation conversation) {
|
||||
this.conversation = conversation;
|
||||
}
|
||||
|
||||
public String getShowName() {
|
||||
if (conversation != null) {
|
||||
return conversation.getShowName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String title;
|
||||
private String iconPath;
|
||||
private boolean isGroup;
|
||||
private boolean top;
|
||||
/**
|
||||
* 是否为折叠会话 Is folded conversation or not
|
||||
*/
|
||||
private boolean isMarkFold;
|
||||
/**
|
||||
* 是否标记会话未读 Is marked conversation unread or not
|
||||
*/
|
||||
private boolean isMarkUnread;
|
||||
/**
|
||||
* 是否标记会话隐藏 Is marked conversation hidden or not
|
||||
*/
|
||||
private boolean isMarkHidden;
|
||||
/**
|
||||
* 本地记录未读状态 Is marked conversation local-unread or not
|
||||
*/
|
||||
private boolean isMarkLocalUnread;
|
||||
/**
|
||||
* 最后一条消息时间
|
||||
*/
|
||||
private long lastMessageTime;
|
||||
private V2TIMMessage lastMessage;
|
||||
|
||||
/**
|
||||
* 会话界面显示的@提示消息
|
||||
*
|
||||
* "@" message in group
|
||||
*/
|
||||
private String atInfoText;
|
||||
|
||||
/**
|
||||
* 会话界面显示消息免打扰图标
|
||||
*
|
||||
* the conversation item displays the icon of Do Not Disturb
|
||||
*/
|
||||
private boolean showDisturbIcon;
|
||||
|
||||
private DraftInfo draft;
|
||||
private String groupType;
|
||||
|
||||
/**
|
||||
* 会话排序键值
|
||||
*
|
||||
* conversation sort key
|
||||
*/
|
||||
private long orderKey;
|
||||
|
||||
|
||||
private String room_id;
|
||||
public ConversationInfo() {
|
||||
|
||||
}
|
||||
|
||||
public String getRoom_id() {
|
||||
return room_id;
|
||||
}
|
||||
|
||||
public void setRoom_id(String room_id) {
|
||||
this.room_id = room_id;
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
public void setConversationId(String conversationId) {
|
||||
this.conversationId = conversationId;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getUnRead() {
|
||||
return unRead;
|
||||
}
|
||||
|
||||
public void setUnRead(int unRead) {
|
||||
this.unRead = unRead;
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return isGroup;
|
||||
}
|
||||
|
||||
public void setGroup(boolean group) {
|
||||
isGroup = group;
|
||||
}
|
||||
|
||||
public boolean isTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
public void setTop(boolean top) {
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
public boolean isMarkFold() {
|
||||
return isMarkFold;
|
||||
}
|
||||
|
||||
public void setMarkFold(boolean markFold) {
|
||||
isMarkFold = markFold;
|
||||
}
|
||||
|
||||
public boolean isMarkUnread() {
|
||||
return isMarkUnread;
|
||||
}
|
||||
|
||||
public void setMarkUnread(boolean markUnread) {
|
||||
isMarkUnread = markUnread;
|
||||
}
|
||||
|
||||
public boolean isMarkHidden() {
|
||||
return isMarkHidden;
|
||||
}
|
||||
|
||||
public void setMarkHidden(boolean markHidden) {
|
||||
isMarkHidden = markHidden;
|
||||
}
|
||||
|
||||
public boolean isMarkLocalUnread() {
|
||||
return isMarkLocalUnread;
|
||||
}
|
||||
|
||||
public void setMarkLocalUnread(boolean markLocalUnread) {
|
||||
isMarkLocalUnread = markLocalUnread;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得最后一条消息的时间,单位是秒
|
||||
*
|
||||
* Get the time of the last message, in seconds
|
||||
*/
|
||||
public long getLastMessageTime() {
|
||||
return lastMessageTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最后一条消息的时间,单位是秒
|
||||
*
|
||||
* Set the time of the last message, in seconds
|
||||
* @param lastMessageTime
|
||||
*/
|
||||
public void setLastMessageTime(long lastMessageTime) {
|
||||
this.lastMessageTime = lastMessageTime;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public V2TIMMessage getLastMessage() {
|
||||
return lastMessage;
|
||||
}
|
||||
|
||||
public void setLastMessage(V2TIMMessage lastMessage) {
|
||||
this.lastMessage = lastMessage;
|
||||
}
|
||||
|
||||
public void setAtInfoText(String atInfoText) {
|
||||
this.atInfoText = atInfoText;
|
||||
}
|
||||
|
||||
public String getAtInfoText() {
|
||||
return atInfoText;
|
||||
}
|
||||
|
||||
public boolean isShowDisturbIcon() {
|
||||
return showDisturbIcon;
|
||||
}
|
||||
|
||||
public void setShowDisturbIcon(boolean showDisturbIcon) {
|
||||
this.showDisturbIcon = showDisturbIcon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setDraft(DraftInfo draft) {
|
||||
this.draft = draft;
|
||||
}
|
||||
|
||||
public DraftInfo getDraft() {
|
||||
return this.draft;
|
||||
}
|
||||
|
||||
public String getGroupType() {
|
||||
return groupType;
|
||||
}
|
||||
|
||||
public void setGroupType(String groupType) {
|
||||
this.groupType = groupType;
|
||||
}
|
||||
|
||||
public String getIconPath() {
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
public void setIconPath(String iconPath) {
|
||||
this.iconPath = iconPath;
|
||||
}
|
||||
|
||||
public void setOrderKey(long orderKey) {
|
||||
this.orderKey = orderKey;
|
||||
}
|
||||
|
||||
public long getOrderKey() {
|
||||
return orderKey;
|
||||
}
|
||||
|
||||
public List<V2TIMGroupAtInfo> getGroupAtInfoList() {
|
||||
if (conversation != null) {
|
||||
return conversation.getGroupAtInfoList();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStatusType() {
|
||||
return statusType;
|
||||
}
|
||||
|
||||
public void setStatusType(int statusType) {
|
||||
this.statusType = statusType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull ConversationInfo other) {
|
||||
if (this.isTop() && !other.isTop()) {
|
||||
return -1;
|
||||
} else if (!this.isTop() && other.isTop()) {
|
||||
return 1;
|
||||
} else {
|
||||
long thisOrderKey = this.orderKey;
|
||||
long otherOrderKey = other.orderKey;
|
||||
if (thisOrderKey > otherOrderKey) {
|
||||
return -1;
|
||||
} else if (thisOrderKey == otherOrderKey) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConversationInfo{" +
|
||||
"type=" + type +
|
||||
", unRead=" + unRead +
|
||||
", conversationId='" + conversationId + '\'' +
|
||||
", id='" + id + '\'' +
|
||||
", iconUrl='" + iconUrlList.size() + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", iconPath=" + iconPath +
|
||||
", isGroup=" + isGroup +
|
||||
", top=" + top +
|
||||
", lastMessageTime=" + lastMessageTime +
|
||||
", lastMessage=" + lastMessage +
|
||||
", draftText=" + draft +
|
||||
", groupType=" + groupType +
|
||||
", statusType=" + statusType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class DraftInfo implements Serializable {
|
||||
private String draftText;
|
||||
private long draftTime;
|
||||
|
||||
public String getDraftText() {
|
||||
return draftText;
|
||||
}
|
||||
|
||||
public void setDraftText(String draftText) {
|
||||
this.draftText = draftText;
|
||||
}
|
||||
|
||||
public long getDraftTime() {
|
||||
return draftTime;
|
||||
}
|
||||
|
||||
public void setDraftTime(long draftTime) {
|
||||
this.draftTime = draftTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DraftInfo{" +
|
||||
"draftText='" + draftText + '\'' +
|
||||
", draftTime=" + draftTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ILayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public interface IConversationLayout extends ILayout {
|
||||
View getConversationList();
|
||||
void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack);
|
||||
void deleteConversation(ConversationInfo conversation);
|
||||
void clearConversationMessage(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* 隐藏普通会话
|
||||
* Hide normal conversation
|
||||
*/
|
||||
void markConversationHidden(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* 标记会话已读/未读
|
||||
* Mark conversation read or unread
|
||||
*/
|
||||
void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread);
|
||||
|
||||
/**
|
||||
* 隐藏整个折叠的会话 item
|
||||
* Hide folded conversation item
|
||||
*/
|
||||
void hideFoldedItem(boolean needHide);
|
||||
|
||||
/**
|
||||
* 清除折叠 item 本地未读状态
|
||||
* Clear unread status of fold item
|
||||
*/
|
||||
void clearUnreadStatusOfFoldItem();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
public interface IConversationListLayout {
|
||||
void setBackground(int resId);
|
||||
void setOnConversationAdapterListener(OnConversationAdapterListener listener);
|
||||
|
||||
/**
|
||||
* 不显示小红点未读消息条数开关
|
||||
*
|
||||
* Do not display the switch for the number of unread messages with the small red dot
|
||||
*
|
||||
* @param flag 默认false,表示显示
|
||||
*/
|
||||
void disableItemUnreadDot(boolean flag);
|
||||
|
||||
/**
|
||||
* 设置会话Item头像圆角
|
||||
*
|
||||
* Set session item avatar rounded corners
|
||||
*
|
||||
* @param radius
|
||||
*/
|
||||
void setItemAvatarRadius(int radius);
|
||||
|
||||
/**
|
||||
* 设置会话Item顶部字体大小
|
||||
*
|
||||
* Set the font size at the top of the session item
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemTopTextSize(int size);
|
||||
|
||||
/**
|
||||
* 设置会话Item底部字体大小
|
||||
*
|
||||
* Set the font size at the bottom of the session item
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemBottomTextSize(int size);
|
||||
|
||||
/**
|
||||
* 设置会话Item日期字体大小
|
||||
*
|
||||
* Set the session item date font size
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemDateTextSize(int size);
|
||||
|
||||
|
||||
View getListLayout();
|
||||
ConversationListAdapter getAdapter();
|
||||
void setAdapter(IConversationListAdapter adapter);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface IConversationProvider {
|
||||
|
||||
/**
|
||||
* 获取具体的会话数据集合,ConversationContainer依据该数据集合展示会话列表
|
||||
*
|
||||
* Get a specific session data set, and ConversationContainer displays the session list based on the data set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ConversationInfo> getDataSource();
|
||||
|
||||
/**
|
||||
* 批量添加会话条目
|
||||
*
|
||||
* Bulk add session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean addConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* 删除会话条目
|
||||
*
|
||||
* Delete session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean deleteConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* 更新会话条目
|
||||
*
|
||||
* Update session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean updateConversations(List<ConversationInfo> conversations);
|
||||
|
||||
|
||||
/**
|
||||
* 绑定会话适配器时触发的调用,在调用{@link com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider}时自动调用
|
||||
*
|
||||
* Called when a session adapter is bound, automatically called when {@link com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider} is called
|
||||
*
|
||||
* @param adapter 会话UI显示适配器
|
||||
* @return
|
||||
*/
|
||||
|
||||
void attachAdapter(IConversationListAdapter adapter);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OnConversationAdapterListener {
|
||||
void onItemClick(View view, int viewType, ConversationInfo conversationInfo);
|
||||
void OnItemLongClick(View view, ConversationInfo conversationInfo);
|
||||
void onConversationChanged(List<ConversationInfo> dataSource);
|
||||
void onUserIconClick( ConversationInfo conversationInfo);
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.setting.ConversationLayoutSetting;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIConversationFragment extends BaseFragment {
|
||||
private View mBaseView;
|
||||
private ConversationLayout mConversationLayout;
|
||||
private ListView mConversationPopList;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.conversation_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
// 从布局文件中获取会话列表面板
|
||||
mConversationLayout = mBaseView.findViewById(R.id.conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
presenter.setConversationListener();
|
||||
presenter.setShowType(ConversationPresenter.SHOW_TYPE_CONVERSATION_LIST_WITH_FOLD);
|
||||
mConversationLayout.setPresenter(presenter);
|
||||
|
||||
// 会话列表面板的默认UI和交互初始化
|
||||
mConversationLayout.initDefault();
|
||||
// 通过API设置ConversataonLayout各种属性的样例,开发者可以打开注释,体验效果
|
||||
ConversationLayoutSetting.customizeConversation(mConversationLayout);
|
||||
|
||||
mConversationLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
//此处为demo的实现逻辑,更根据会话类型跳转到相关界面,开发者可根据自己的应用场景灵活实现
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.clearUnreadStatusOfFoldItem();
|
||||
startFoldedConversationActivity();
|
||||
} else {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null)return;
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null)return;
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserIconClick(ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
public void restoreConversationItemBackground() {
|
||||
if (mConversationLayout.getConversationList().getAdapter() != null &&
|
||||
mConversationLayout.getConversationList().getAdapter().isClick()) {
|
||||
mConversationLayout.getConversationList().getAdapter().setClick(false);
|
||||
mConversationLayout.getConversationList().getAdapter().notifyItemChanged(mConversationLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
// 设置长按conversation显示PopAction
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.hideFoldedItem(true);
|
||||
} else {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mConversationLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void addDeletePopMenuAction() {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mConversationLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
mConversationPopActions.add(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 长按会话item弹框
|
||||
* @param view 长按 view
|
||||
* @param conversationInfo 会话数据对象
|
||||
*/
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (!conversationInfo.isMarkFold()) {
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
addDeletePopMenuAction();
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = - view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mConversationLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
|
||||
private void startFoldedConversationActivity() {
|
||||
Intent intent = new Intent(getActivity(), TUIFoldedConversationActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
|
||||
public class TUIFoldedConversationActivity extends BaseLightActivity {
|
||||
private TUIFoldedConversationFragment mTUIFoldedConversationFragment;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.folded_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIFoldedConversationFragment = new TUIFoldedConversationFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIFoldedConversationFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.FoldedConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIFoldedConversationFragment extends BaseFragment {
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private FoldedConversationLayout mFoldedLayout;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private ListView mConversationPopList;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.folded_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mFoldedLayout = mBaseView.findViewById(R.id.folded_conversation_layout);
|
||||
mTitleBarLayout = mFoldedLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle(getResources().getString(R.string.folded_group_chat), ITitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
presenter = new ConversationFoldPresenter();
|
||||
presenter.initListener();
|
||||
|
||||
mFoldedLayout.setPresenter(presenter);
|
||||
mFoldedLayout.initDefault();
|
||||
|
||||
mFoldedLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null)return;
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null)return;
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserIconClick(ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
// 设置长按conversation显示PopAction
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
mFoldedLayout.markConversationHidden((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
conversationPopActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void restoreConversationItemBackground() {
|
||||
if (mFoldedLayout.getConversationList().getAdapter() != null &&
|
||||
mFoldedLayout.getConversationList().getAdapter().isClick()) {
|
||||
mFoldedLayout.getConversationList().getAdapter().setClick(false);
|
||||
mFoldedLayout.getConversationList().getAdapter().notifyItemChanged(mFoldedLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = - view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mFoldedLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
|
||||
public class TUIForwardSelectActivity extends BaseLightActivity {
|
||||
private static final String TAG = TUIForwardSelectActivity.class.getSimpleName();
|
||||
|
||||
private TUIForwardSelectFragment mTUIForwardSelectFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.forward_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
TUIConversationLog.i(TAG, "onNewIntent");
|
||||
super.onNewIntent(intent);;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
TUIConversationLog.i(TAG, "onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIForwardSelectFragment = new TUIForwardSelectFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIForwardSelectFragment).commitAllowingStateLoss();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ForwardConversationSelectorAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ForwardSelectLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIForwardSelectFragment extends BaseFragment {
|
||||
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private ForwardSelectLayout mForwardLayout;
|
||||
|
||||
private RecyclerView mForwardSelectlistView;
|
||||
private ForwardConversationSelectorAdapter mAdapter;
|
||||
private List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mContactDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mAllSelectedConversations = new ArrayList<>();
|
||||
private RelativeLayout mForwardSelectlistViewLayout;
|
||||
private TextView mSureView;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
private static final String TAG = TUIForwardSelectFragment.class.getSimpleName();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.forward_fragment, container, false);
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
mForwardLayout = view.findViewById(R.id.forward_conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
mForwardLayout.setPresenter(presenter);
|
||||
|
||||
mForwardLayout.initDefault();
|
||||
|
||||
customizeConversation();
|
||||
mForwardLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
if (viewType == ConversationInfo.TYPE_RECENT_LABEL){
|
||||
return;
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT){
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))){
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, false);
|
||||
TUICore.startActivity(TUIForwardSelectFragment.this, "ForwardSelectGroupActivity", param, TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE);
|
||||
}else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, true);
|
||||
TUICore.startActivity(TUIForwardSelectFragment.this, "ForwardSelectGroupActivity", param, TUIConversationConstants.FORWARD_CREATE_GROUP_CODE);
|
||||
}else{
|
||||
TUIConversationLog.d(TAG,"Titlebar exception");
|
||||
}
|
||||
} else {
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))) {
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
checkRepeat();
|
||||
refreshSelectConversations();
|
||||
} else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
forwardMessages(conversationInfo);
|
||||
} else {
|
||||
forwardMessages(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserIconClick(ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mForwardSelectlistViewLayout = view.findViewById(R.id.forward_select_list_layout);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mForwardSelectlistView = view.findViewById(R.id.forward_select_list);
|
||||
mForwardSelectlistView.setLayoutManager(new CustomLinearLayoutManager(getContext(), CustomLinearLayoutManager.HORIZONTAL, false));
|
||||
mAdapter = new ForwardConversationSelectorAdapter(this.getContext());
|
||||
mForwardSelectlistView.setAdapter(mAdapter);
|
||||
|
||||
mAdapter.setOnItemClickListener(new ForwardConversationSelectorAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position) {
|
||||
boolean needFresh = false;
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
if(position < mDataSource.size()) {
|
||||
mDataSource.remove(position);
|
||||
mForwardLayout.getConversationList().getAdapter().setSelectConversations(mDataSource);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!needFresh) {
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0) {
|
||||
int dataSourcePosition = mDataSource == null ? 0 : mDataSource.size();
|
||||
if (position - dataSourcePosition < mContactDataSource.size()) {
|
||||
mContactDataSource.remove(position - dataSourcePosition);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needFresh) {
|
||||
refreshSelectConversations();
|
||||
}
|
||||
}
|
||||
});
|
||||
mSureView = view.findViewById(R.id.btn_msg_ok);
|
||||
mSureView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> conversationMap = new HashMap<>();
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
for (int i=0;i<mDataSource.size();i++){
|
||||
conversationMap.put(mDataSource.get(i).getId(), mDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0){
|
||||
for (int i=0;i<mContactDataSource.size();i++){
|
||||
conversationMap.put(mContactDataSource.get(i).getId(), mContactDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, conversationMap);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelectConversations();
|
||||
initTitleAction();
|
||||
}
|
||||
|
||||
private void refreshSelectConversations(){
|
||||
mAllSelectedConversations.clear();
|
||||
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
mAllSelectedConversations.addAll(mDataSource);
|
||||
}
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0){
|
||||
mAllSelectedConversations.addAll(mContactDataSource);
|
||||
}
|
||||
|
||||
mAdapter.setDataSource(mAllSelectedConversations);
|
||||
|
||||
if (mAllSelectedConversations == null || mAllSelectedConversations.size() == 0){
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure));
|
||||
mSureView.setVisibility(View.GONE);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mSureView.setVisibility(View.VISIBLE);
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure) + "(" + mAllSelectedConversations.size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void forwardMessages(final ConversationInfo conversationInfo){
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle("");
|
||||
builder.setMessage(getString(R.string.forward_alert_title));
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(getString(com.tencent.qcloud.tuicore.R.string.sure), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> chatInfo = new HashMap<>();
|
||||
chatInfo.put(conversationInfo.getId(), conversationInfo.isGroup());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, chatInfo);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(com.tencent.qcloud.tuicore.R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void customizeConversation(){
|
||||
mTitleBarLayout = mForwardLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle("", TitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.getLeftGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), ITitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
mTitleBarLayout.getLeftIcon().setVisibility(View.GONE);
|
||||
mTitleBarLayout.getRightIcon().setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
private void initTitleAction() {
|
||||
mForwardLayout.getTitleBar().setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))){
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), TitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(false);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
mAdapter.setDataSource(null);
|
||||
mAllSelectedConversations.clear();
|
||||
}else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
getActivity().finish();
|
||||
}else{
|
||||
TUIConversationLog.d(TAG,"Titlebar exception");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mForwardLayout.getTitleBar().setOnRightClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.GONE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_cancle), TitleBarLayout.Position.LEFT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(true);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == TUIConversationConstants.FORWARD_CREATE_GROUP_CODE && resultCode == TUIConversationConstants.FORWARD_CREATE_GROUP_CODE) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, data);
|
||||
getActivity().finish();
|
||||
}
|
||||
} else if (requestCode == TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE && resultCode == TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE){
|
||||
HashMap<String, String> conversationMap = (HashMap<String, String>) data.getSerializableExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY);
|
||||
if (conversationMap == null || conversationMap.isEmpty()){
|
||||
mContactDataSource.clear();
|
||||
refreshSelectConversations();
|
||||
return;
|
||||
}
|
||||
|
||||
mContactDataSource.clear();
|
||||
for (Map.Entry<String, String> entry: conversationMap.entrySet()){
|
||||
ConversationInfo conversationInfo = new ConversationInfo();
|
||||
List<Object> iconList = new ArrayList<>();
|
||||
iconList.add(entry.getValue());
|
||||
conversationInfo.setIconUrlList(iconList);
|
||||
conversationInfo.setId(entry.getKey());
|
||||
conversationInfo.setGroup(false);
|
||||
mContactDataSource.add(conversationInfo);
|
||||
}
|
||||
checkRepeat();
|
||||
|
||||
refreshSelectConversations();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRepeat() {
|
||||
Iterator<ConversationInfo> iterator = mContactDataSource.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConversationInfo conversationInfo = iterator.next();
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
for (int i = 0; i < mDataSource.size(); i++) {
|
||||
if (conversationInfo.getId().equals(mDataSource.get(i).getId())) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.setting;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationListLayout;
|
||||
|
||||
public class ConversationLayoutSetting {
|
||||
|
||||
public static void customizeConversation(final ConversationLayout layout) {
|
||||
|
||||
ConversationListLayout listLayout = (ConversationListLayout) layout.getConversationList();
|
||||
|
||||
listLayout.setItemTopTextSize(16);
|
||||
listLayout.setItemBottomTextSize(12);
|
||||
listLayout.setItemDateTextSize(10);
|
||||
listLayout.setItemAvatarRadius(180);
|
||||
listLayout.disableItemUnreadDot(false);
|
||||
|
||||
// 动态插入,删除Item,包括自定义会话
|
||||
// final ConversationInfo customInfo = new ConversationInfo();
|
||||
// customInfo.setType(ConversationInfo.TYPE_CUSTOM);
|
||||
// customInfo.setId("自定义会话");
|
||||
// customInfo.setGroup(false);
|
||||
// customInfo.setTitle("乔丹风行8代跑鞋 风随我动!");
|
||||
// customInfo.setIconUrl("https://img1.gtimg.com/ninja/2/2019/03/ninja155375585738456.jpg");
|
||||
//
|
||||
//
|
||||
// new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// layout.addConversationInfo(0, customInfo);
|
||||
// }
|
||||
// }, 3000);
|
||||
|
||||
// new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// layout.removeConversationInfo(0);
|
||||
// }
|
||||
// }, 5000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
public static void startChatActivity(ConversationInfo conversationInfo) {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConstants.TUIChat.CHAT_TYPE, conversationInfo.isGroup() ? V2TIMConversation.V2TIM_GROUP : V2TIMConversation.V2TIM_C2C);
|
||||
param.putString(TUIConstants.TUIChat.CHAT_ID, conversationInfo.getId());
|
||||
param.putString(TUIConstants.TUIChat.CHAT_NAME, conversationInfo.getTitle());
|
||||
param.putString(TUIConstants.TUIChat.ROOM_ID,conversationInfo.getRoom_id());
|
||||
if (conversationInfo.getDraft() != null) {
|
||||
param.putString(TUIConstants.TUIChat.DRAFT_TEXT, conversationInfo.getDraft().getDraftText());
|
||||
param.putLong(TUIConstants.TUIChat.DRAFT_TIME, conversationInfo.getDraft().getDraftTime());
|
||||
}
|
||||
param.putBoolean(TUIConstants.TUIChat.IS_TOP_CHAT, conversationInfo.isTop());
|
||||
param.putString(TUIConstants.TUIChat.FACE_URL, conversationInfo.getIconPath());
|
||||
if (conversationInfo.isGroup()) {
|
||||
param.putString(TUIConstants.TUIChat.GROUP_TYPE, conversationInfo.getGroupType());
|
||||
param.putSerializable(TUIConstants.TUIChat.AT_INFO_LIST, (Serializable) conversationInfo.getGroupAtInfoList());
|
||||
}
|
||||
if (conversationInfo.isGroup()) {
|
||||
TUICore.startActivity(TUIConstants.TUIChat.GROUP_CHAT_ACTIVITY_NAME, param);
|
||||
} else {
|
||||
TUICore.startActivity(TUIConstants.TUIChat.C2C_CHAT_ACTIVITY_NAME, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public abstract class ConversationBaseHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
protected View rootView;
|
||||
protected ConversationListAdapter mAdapter;
|
||||
|
||||
public ConversationBaseHolder(View itemView) {
|
||||
super(itemView);
|
||||
rootView = itemView;
|
||||
}
|
||||
|
||||
public void setAdapter(RecyclerView.Adapter adapter) {
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
|
||||
public abstract void layoutViews(ConversationInfo conversationInfo, int position);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.component.UnreadCountTextView;
|
||||
import com.tencent.qcloud.tuicore.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ConversationCommonHolder extends ConversationBaseHolder {
|
||||
|
||||
public ConversationIconView conversationIconView;
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected UnreadCountTextView unreadText;
|
||||
protected TextView atInfoText;
|
||||
protected ImageView disturbView;
|
||||
protected CheckBox multiSelectCheckBox;
|
||||
protected RelativeLayout messageStatusLayout;
|
||||
public ImageView messageSending;
|
||||
public ImageView messageFailed;
|
||||
private boolean isForwardMode = false;
|
||||
protected View userStatusView;
|
||||
private boolean showFoldedStyle = true;
|
||||
|
||||
public ConversationCommonHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
atInfoText = rootView.findViewById(R.id.conversation_at_msg);
|
||||
disturbView = rootView.findViewById(R.id.not_disturb);
|
||||
multiSelectCheckBox = rootView.findViewById(R.id.select_checkbox);
|
||||
messageStatusLayout = rootView.findViewById(R.id.message_status_layout);
|
||||
messageFailed = itemView.findViewById(R.id.message_status_failed);
|
||||
messageSending = itemView.findViewById(R.id.message_status_sending);
|
||||
userStatusView = itemView.findViewById(R.id.user_status);
|
||||
}
|
||||
|
||||
public void setForwardMode(boolean forwardMode) {
|
||||
isForwardMode = forwardMode;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
// if (conversation.isTop() && !isForwardMode) {
|
||||
// leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
// } else {
|
||||
// leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
// }
|
||||
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
titleText.setText(R.string.folded_group_chat);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
} else {
|
||||
titleText.setText(conversation.getTitle());
|
||||
}
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
DraftInfo draftInfo = conversation.getDraft();
|
||||
String draftText = "";
|
||||
if (draftInfo != null) {
|
||||
Gson gson = new Gson();
|
||||
HashMap draftJsonMap;
|
||||
draftText = draftInfo.getDraftText();
|
||||
try {
|
||||
draftJsonMap = gson.fromJson(draftInfo.getDraftText(), HashMap.class);
|
||||
if (draftJsonMap != null) {
|
||||
draftText = (String) draftJsonMap.get("content");
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
TUIConversationLog.e("ConversationCommonHolder", " getDraftJsonMap error ");
|
||||
}
|
||||
}
|
||||
if (draftInfo != null) {
|
||||
messageText.setText(draftText);
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(draftInfo.getDraftTime() * 1000)));
|
||||
} else {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIChat.V2TIMMESSAGE, conversation.getLastMessage());
|
||||
String lastMsgDisplayString = (String) TUICore.callService(TUIConstants.TUIChat.SERVICE_NAME, TUIConstants.TUIChat.METHOD_GET_DISPLAY_STRING, param);
|
||||
// 获取要显示的字符
|
||||
// Get the characters to display
|
||||
if (lastMsgDisplayString != null) {
|
||||
messageText.setText(Html.fromHtml(lastMsgDisplayString));
|
||||
messageText.setTextColor(rootView.getResources().getColor(R.color.list_bottom_text_bg));
|
||||
}
|
||||
if (conversation.getLastMessage() != null) {
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(conversation.getLastMessageTime() * 1000)));
|
||||
}
|
||||
}
|
||||
|
||||
if (conversation.isShowDisturbIcon()) {
|
||||
if ((showFoldedStyle && conversation.isMarkFold())) {
|
||||
if (conversation.isMarkLocalUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (conversation.getUnRead() == 0) {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
|
||||
if (messageText.getText() != null) {
|
||||
String text = messageText.getText().toString();
|
||||
messageText.setText("[" + conversation.getUnRead() + rootView.getContext().getString(R.string.message_num) + "] " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("1");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (draftInfo != null) {
|
||||
atInfoText.setVisibility(View.VISIBLE);
|
||||
atInfoText.setText(R.string.drafts);
|
||||
atInfoText.setTextColor(Color.RED);
|
||||
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (conversation.getAtInfoText().isEmpty()) {
|
||||
atInfoText.setVisibility(View.GONE);
|
||||
} else {
|
||||
atInfoText.setVisibility(View.VISIBLE);
|
||||
atInfoText.setText(conversation.getAtInfoText());
|
||||
atInfoText.setTextColor(Color.RED);
|
||||
}
|
||||
|
||||
V2TIMMessage lastMessage = conversation.getLastMessage();
|
||||
if (lastMessage != null) {
|
||||
int status = lastMessage.getStatus();
|
||||
if (status == V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.VISIBLE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else if (status == V2TIMMessage.V2TIM_MSG_STATUS_SENDING) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
conversationIconView.setRadius(mAdapter.getItemAvatarRadius());
|
||||
if (mAdapter.getItemDateTextSize() != 0) {
|
||||
timelineText.setTextSize(mAdapter.getItemDateTextSize());
|
||||
}
|
||||
if (mAdapter.getItemBottomTextSize() != 0) {
|
||||
messageText.setTextSize(mAdapter.getItemBottomTextSize());
|
||||
}
|
||||
if (mAdapter.getItemTopTextSize() != 0) {
|
||||
titleText.setTextSize(mAdapter.getItemTopTextSize());
|
||||
}
|
||||
if (!mAdapter.hasItemUnreadDot()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
conversationIconView.setShowFoldedStyle(showFoldedStyle);
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
if (conversation.isShowDisturbIcon() && !isForwardMode) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
} else {
|
||||
disturbView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (isForwardMode) {
|
||||
messageText.setVisibility(View.GONE);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.GONE);
|
||||
atInfoText.setVisibility(View.GONE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (!conversation.isGroup() && TUIConversationConfig.getInstance().isShowUserStatus()) {
|
||||
userStatusView.setVisibility(View.VISIBLE);
|
||||
if (conversation.getStatusType() == V2TIMUserStatus.V2TIM_USER_STATUS_ONLINE) {
|
||||
userStatusView.setBackgroundResource(TUIThemeManager.getAttrResId(rootView.getContext(), com.tencent.qcloud.tuicore.R.attr.user_status_online));
|
||||
} else {
|
||||
userStatusView.setBackgroundResource(TUIThemeManager.getAttrResId(rootView.getContext(), com.tencent.qcloud.tuicore.R.attr.user_status_offline));
|
||||
}
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
|
||||
public class ConversationCustomHolder extends ConversationBaseHolder {
|
||||
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected TextView unreadText;
|
||||
protected ConversationIconView conversationIconView;
|
||||
|
||||
|
||||
public ConversationCustomHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
if (conversation.isTop()) {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
titleText.setText(conversation.getTitle());
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
|
||||
if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (mAdapter.getItemDateTextSize() != 0) {
|
||||
timelineText.setTextSize(mAdapter.getItemDateTextSize());
|
||||
}
|
||||
if (mAdapter.getItemBottomTextSize() != 0) {
|
||||
messageText.setTextSize(mAdapter.getItemBottomTextSize());
|
||||
}
|
||||
if (mAdapter.getItemTopTextSize() != 0) {
|
||||
titleText.setTextSize(mAdapter.getItemTopTextSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.component.gatherimage.SynthesizedImageView;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuicore.util.BackgroundTasks;
|
||||
import com.tencent.qcloud.tuicore.util.ImageUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ThreadHelper;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationIconPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会话列表头像View
|
||||
*/
|
||||
public class ConversationIconView extends RelativeLayout {
|
||||
|
||||
private static final int icon_size = ScreenUtil.getPxByDp(50);
|
||||
private ImageView mIconView;
|
||||
private boolean showFoldedStyle = false;
|
||||
|
||||
private ConversationIconPresenter presenter;
|
||||
|
||||
public ConversationIconView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), com.tencent.qcloud.tuicore.R.layout.profile_icon_view, this);
|
||||
mIconView = findViewById(com.tencent.qcloud.tuicore.R.id.profile_icon);
|
||||
((SynthesizedImageView) mIconView).defaultImage(TUIConfig.getDefaultAvatarImage());
|
||||
presenter = new ConversationIconPresenter();
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置会话头像的url
|
||||
*
|
||||
* @param iconUrls 头像url,最多只取前9个
|
||||
*/
|
||||
public void setIconUrls(final List<Object> iconUrls, final String conversationId) {
|
||||
// 需要在主线程中执行,以免写缓存出现问题
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).displayImage(iconUrls).load(conversationId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversation(ConversationInfo conversationInfo) {
|
||||
if (showFoldedStyle && conversationInfo.isMarkFold()) {
|
||||
mIconView.setImageResource(R.drawable.ic_fold);
|
||||
} else if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setImageId(conversationInfo.getConversationId());
|
||||
if (conversationInfo.isGroup()) {
|
||||
fillConversationUrlForGroup(conversationInfo);
|
||||
} else {
|
||||
setIconUrls(conversationInfo.getIconUrlList(), conversationInfo.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillConversationUrlForGroup(final ConversationInfo info) {
|
||||
List<Object> iconUrlList = info.getIconUrlList();
|
||||
if (iconUrlList == null || iconUrlList.size() == 0) {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar()) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
return;
|
||||
}
|
||||
// 读取文件,在线程池中进行,避免主线程卡顿
|
||||
ThreadHelper.INST.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String savedIcon = ImageUtil.getGroupConversationAvatar(info.getConversationId());
|
||||
if (TextUtils.isEmpty(savedIcon)) {
|
||||
fillFaceUrlList(info.getId(), info);
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(savedIcon);
|
||||
info.setIconUrlList(list);
|
||||
setIconUrls(list, info.getConversationId());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar() && iconUrlList.size() > 1) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
} else {
|
||||
setIconUrls(iconUrlList, info.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFaceUrlList(final String groupID, final ConversationInfo info) {
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearImage();
|
||||
presenter.getGroupMemberIconList(groupID, new IUIKitCallback<List<Object>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Object> data) {
|
||||
info.setIconUrlList(data);
|
||||
setIconUrls(data, info.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setRadius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
mIconView.setImageBitmap(bd.getBitmap());
|
||||
}
|
||||
|
||||
public void setBitmapResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
Bitmap bitmap = ImageUtil.toRoundBitmap(bd.getBitmap());
|
||||
mIconView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
public void clearImage() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) mIconView).clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
|
||||
private ConversationListLayout mConversationList;
|
||||
private ConversationPresenter presenter;
|
||||
public ConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (mConversationList != null) {
|
||||
mConversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化相关UI元素
|
||||
*/
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.conversation_layout, this);
|
||||
mConversationList = findViewById(R.id.conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
if (presenter != null) {
|
||||
initSearchView(adapter);
|
||||
adapter.setShowFoldedStyle(true);
|
||||
}
|
||||
mConversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
mConversationList.loadConversation(0);
|
||||
}
|
||||
|
||||
public void initSearchView(ConversationListAdapter adapter) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONTEXT, getContext());
|
||||
Map<String, Object> searchExtension = TUICore.getExtensionInfo(TUIConstants.TUIConversation.EXTENSION_CLASSIC_SEARCH, param);
|
||||
if (searchExtension != null) {
|
||||
View searchView = (View) searchExtension.get(TUIConstants.TUIConversation.SEARCH_VIEW);
|
||||
if (searchView != null) {
|
||||
adapter.setSearchView(searchView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return mConversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
if (presenter != null) {
|
||||
presenter.setConversationTop(conversation, callBack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.clearConversationMessage(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
if (presenter != null) {
|
||||
presenter.hideFoldItem(needHide);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
if (presenter != null) {
|
||||
presenter.setUnreadStatusOfFoldItem(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,550 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationListAdapter extends RecyclerView.Adapter implements IConversationListAdapter {
|
||||
|
||||
public static final int ITEM_TYPE_HEADER_SEARCH = 101;
|
||||
public static final int ITEM_TYPE_FOOTER_LOADING = -99;
|
||||
public static final int HEADER_COUNT = 1;
|
||||
public static final int FOOTER_COUNT = 1;
|
||||
public static final int SELECT_COUNT = 1;
|
||||
public static final int SELECT_LABEL_COUNT = 1;
|
||||
|
||||
private boolean mHasShowUnreadDot = true;
|
||||
private int mItemAvatarRadius = ScreenUtil.getPxByDp(50);
|
||||
private int mTopTextSize;
|
||||
private int mBottomTextSize;
|
||||
private int mDateTextSize;
|
||||
protected List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private OnConversationAdapterListener mOnConversationAdapterListener;
|
||||
|
||||
//消息转发
|
||||
private final HashMap<String, Boolean> mSelectedPositions = new HashMap<>();
|
||||
private boolean isShowMultiSelectCheckBox = false;
|
||||
private boolean isForwardFragment = false;
|
||||
|
||||
private boolean mIsLoading = false;
|
||||
|
||||
// 长按高亮显示
|
||||
private boolean isClick = false;
|
||||
private int currentPosition = -1;
|
||||
|
||||
private View searchView;
|
||||
// 展示折叠样式
|
||||
private boolean showFoldedStyle = true;
|
||||
|
||||
public ConversationListAdapter() {
|
||||
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public boolean isClick() {
|
||||
return isClick;
|
||||
}
|
||||
|
||||
public void setClick(boolean click) {
|
||||
isClick = click;
|
||||
}
|
||||
|
||||
public void setCurrentPosition(int currentPosition, boolean isClick) {
|
||||
this.currentPosition = currentPosition;
|
||||
this.isClick = isClick;
|
||||
}
|
||||
|
||||
public void setShowMultiSelectCheckBox(boolean show) {
|
||||
isShowMultiSelectCheckBox = show;
|
||||
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
mSelectedPositions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForwardFragment(boolean forwardFragment) {
|
||||
isForwardFragment = forwardFragment;
|
||||
}
|
||||
|
||||
public void setSearchView(View searchView) {
|
||||
this.searchView = searchView;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
//设置给定位置条目的选择状态
|
||||
public void setItemChecked(String conversationId, boolean isChecked) {
|
||||
mSelectedPositions.put(conversationId, isChecked);
|
||||
}
|
||||
|
||||
//根据位置判断条目是否选中
|
||||
private boolean isItemChecked(String id) {
|
||||
if (mSelectedPositions.size() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSelectedPositions.containsKey(id)) {
|
||||
return mSelectedPositions.get(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获得选中条目的结果
|
||||
public List<ConversationInfo> getSelectedItem() {
|
||||
if (mSelectedPositions.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
List<ConversationInfo> selectList = new ArrayList<>();
|
||||
for (int i = 0; i < getItemCount() - 1; i++) {
|
||||
ConversationInfo conversationInfo = getItem(i);
|
||||
if (conversationInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if (isItemChecked(conversationInfo.getConversationId())) {
|
||||
selectList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
return selectList;
|
||||
}
|
||||
|
||||
public void setSelectConversations(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null || dataSource.size() == 0) {
|
||||
mSelectedPositions.clear();
|
||||
notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
mSelectedPositions.clear();
|
||||
for (int i = 0; i < dataSource.size(); i++) {
|
||||
for (int j = 0; j < mDataSource.size(); j++) {
|
||||
if (TextUtils.equals(dataSource.get(i).getConversationId(), mDataSource.get(j).getConversationId())) {
|
||||
setItemChecked(mDataSource.get(j).getConversationId(), true);
|
||||
notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
this.mOnConversationAdapterListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataSourceChanged(List<ConversationInfo> dataSource) {
|
||||
this.mDataSource = dataSource;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
ConversationBaseHolder holder = null;
|
||||
// 创建不同的 ViewHolder
|
||||
View view;
|
||||
// 根据ViewType来创建条目
|
||||
if (viewType == ITEM_TYPE_HEADER_SEARCH) {
|
||||
// 如果 searchView 不显示,添加一个隐藏的 view,防止 recyclerview 自动滑到最底部
|
||||
if (searchView == null) {
|
||||
searchView = new View(parent.getContext());
|
||||
}
|
||||
return new HeaderViewHolder(searchView);
|
||||
} else if (viewType == ConversationInfo.TYPE_CUSTOM) {
|
||||
view = inflater.inflate(R.layout.conversation_custom_adapter, parent, false);
|
||||
holder = new ConversationCustomHolder(view);
|
||||
} else if (viewType == ITEM_TYPE_FOOTER_LOADING) {
|
||||
view = inflater.inflate(R.layout.loading_progress_bar, parent, false);
|
||||
return new FooterViewHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_select_adapter, parent, false);
|
||||
return new ForwardSelectHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_RECENT_LABEL) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_label_adapter, parent, false);
|
||||
return new ForwardLabelHolder(view);
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.conversation_list_item_layout, parent, false);
|
||||
holder = new ConversationCommonHolder(view);
|
||||
((ConversationCommonHolder) holder).setForwardMode(isForwardFragment);
|
||||
((ConversationCommonHolder) holder).setShowFoldedStyle(showFoldedStyle);
|
||||
}
|
||||
holder.setAdapter(this);
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
final ConversationInfo conversationInfo = getItem(position);
|
||||
ConversationBaseHolder baseHolder = null;
|
||||
if (conversationInfo != null) {
|
||||
baseHolder = (ConversationBaseHolder) holder;
|
||||
}
|
||||
|
||||
switch (getItemViewType(position)) {
|
||||
case ConversationInfo.TYPE_CUSTOM:
|
||||
case ConversationInfo.TYPE_RECENT_LABEL:
|
||||
break;
|
||||
case ITEM_TYPE_FOOTER_LOADING: {
|
||||
if (holder instanceof FooterViewHolder) {
|
||||
((ConversationBaseHolder) holder).layoutViews(null, position);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConversationInfo.TYPE_FORWAR_SELECT: {
|
||||
ForwardSelectHolder selectHolder = (ForwardSelectHolder) holder;
|
||||
selectHolder.refreshTitle(!isShowMultiSelectCheckBox);
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
if (baseHolder != null) {
|
||||
baseHolder.layoutViews(conversationInfo, position);
|
||||
setCheckBoxStatus(conversationInfo, position, baseHolder);
|
||||
}
|
||||
|
||||
if (getCurrentPosition() == position && isClick()) {
|
||||
// baseHolder.itemView.setBackgroundResource(R.color.conversation_item_clicked_color);
|
||||
} else {
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
// if (conversationInfo.isTop() && !isForwardFragment) {
|
||||
// baseHolder.itemView.setBackgroundColor(baseHolder.rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
// } else {
|
||||
// baseHolder.itemView.setBackgroundColor(Color.WHITE);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setOnClickListener(RecyclerView.ViewHolder holder, int viewType, ConversationInfo conversationInfo) {
|
||||
if (holder instanceof HeaderViewHolder) {
|
||||
return;
|
||||
}
|
||||
//设置点击和长按事件
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mOnConversationAdapterListener.onItemClick(view, viewType, conversationInfo);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
mOnConversationAdapterListener.OnItemLongClick(view, conversationInfo);
|
||||
int position = getIndexInAdapter(conversationInfo);
|
||||
if (position != -1) {
|
||||
setCurrentPosition(position, true);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 设置多选框的选中状态和点击事件
|
||||
private void setCheckBoxStatus(final ConversationInfo conversationInfo, int position, ConversationBaseHolder baseHolder) {
|
||||
if (!(baseHolder instanceof ConversationCommonHolder) || ((ConversationCommonHolder) baseHolder).multiSelectCheckBox == null) {
|
||||
return;
|
||||
}
|
||||
int viewType = getItemViewType(position);
|
||||
String conversationId = conversationInfo.getConversationId();
|
||||
ConversationCommonHolder commonHolder = (ConversationCommonHolder) baseHolder;
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.GONE);
|
||||
} else {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.VISIBLE);
|
||||
|
||||
//设置条目状态
|
||||
commonHolder.multiSelectCheckBox.setChecked(isItemChecked(conversationId));
|
||||
//checkBox的监听
|
||||
commonHolder.multiSelectCheckBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//条目view的监听
|
||||
baseHolder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
int currentPosition = getIndexInAdapter(conversationInfo);
|
||||
if (currentPosition != -1) {
|
||||
notifyItemChanged(currentPosition);
|
||||
}
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
((ConversationCommonHolder) baseHolder).conversationIconView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onUserIconClick(conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndexInAdapter(ConversationInfo conversationInfo) {
|
||||
int position = -1;
|
||||
if (mDataSource != null) {
|
||||
int indexInData = mDataSource.indexOf(conversationInfo);
|
||||
if (indexInData != -1) {
|
||||
position = getItemIndexInAdapter(indexInData);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
|
||||
// ViewHolder 被回收时要清空头像 view 并且停止异步加载头像
|
||||
if (holder instanceof ConversationCommonHolder) {
|
||||
((ConversationCommonHolder) holder).conversationIconView.clearImage();
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationInfo getItem(int position) {
|
||||
if (mDataSource.isEmpty() || position == getItemCount() - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int dataPosition;
|
||||
if (isForwardFragment) {
|
||||
dataPosition = position - SELECT_COUNT - SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
dataPosition = position - HEADER_COUNT;
|
||||
}
|
||||
if (dataPosition < mDataSource.size() && dataPosition >= 0) {
|
||||
return mDataSource.get(dataPosition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int listSize = mDataSource.size();
|
||||
if (isForwardFragment) {
|
||||
return listSize + SELECT_COUNT + SELECT_LABEL_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
return listSize + HEADER_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (isForwardFragment) {
|
||||
if (position == 0) {
|
||||
return ConversationInfo.TYPE_FORWAR_SELECT;
|
||||
} else if (position == 1) {
|
||||
return ConversationInfo.TYPE_RECENT_LABEL;
|
||||
}
|
||||
} else {
|
||||
if (position == 0) {
|
||||
return ITEM_TYPE_HEADER_SEARCH;
|
||||
}
|
||||
}
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_TYPE_FOOTER_LOADING;
|
||||
} else if (mDataSource != null) {
|
||||
ConversationInfo conversationInfo = getItem(position);
|
||||
if (conversationInfo != null) {
|
||||
return conversationInfo.getType();
|
||||
}
|
||||
}
|
||||
return ConversationInfo.TYPE_COMMON;
|
||||
}
|
||||
|
||||
private int getItemIndexInAdapter(int index) {
|
||||
int itemIndex;
|
||||
if (isForwardFragment) {
|
||||
itemIndex = index + SELECT_LABEL_COUNT + SELECT_COUNT;
|
||||
} else {
|
||||
itemIndex = index + HEADER_COUNT;
|
||||
}
|
||||
return itemIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRemoved(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemRemoved(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemInserted(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemInserted(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemChanged(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemChanged(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int startPosition, int count) {
|
||||
int itemStartIndex = getItemIndexInAdapter(startPosition);
|
||||
notifyItemRangeChanged(itemStartIndex, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
public void setItemTopTextSize(int size) {
|
||||
mTopTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemTopTextSize() {
|
||||
return mTopTextSize;
|
||||
}
|
||||
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mBottomTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemBottomTextSize() {
|
||||
return mBottomTextSize;
|
||||
}
|
||||
|
||||
public void setItemDateTextSize(int size) {
|
||||
mDateTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemDateTextSize() {
|
||||
return mDateTextSize;
|
||||
}
|
||||
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mItemAvatarRadius = radius;
|
||||
}
|
||||
|
||||
public int getItemAvatarRadius() {
|
||||
return mItemAvatarRadius;
|
||||
}
|
||||
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mHasShowUnreadDot = !flag;
|
||||
}
|
||||
|
||||
public boolean hasItemUnreadDot() {
|
||||
return mHasShowUnreadDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChanged(boolean isLoading) {
|
||||
this.mIsLoading = isLoading;
|
||||
notifyItemChanged(getItemCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewNeedRefresh() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
//header
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
public HeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
//footer
|
||||
class FooterViewHolder extends ConversationBaseHolder {
|
||||
public FooterViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) rootView.getLayoutParams();
|
||||
if (mIsLoading) {
|
||||
param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
|
||||
param.width = LinearLayout.LayoutParams.MATCH_PARENT;
|
||||
rootView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
param.height = 0;
|
||||
param.width = 0;
|
||||
rootView.setVisibility(View.GONE);
|
||||
}
|
||||
rootView.setLayoutParams(param);
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardLabelHolder extends ConversationBaseHolder {
|
||||
public ForwardLabelHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardSelectHolder extends ConversationBaseHolder {
|
||||
private final TextView titleView;
|
||||
|
||||
public ForwardSelectHolder(View itemView) {
|
||||
super(itemView);
|
||||
titleView = itemView.findViewById(R.id.forward_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
|
||||
}
|
||||
|
||||
public void refreshTitle(boolean isCreateGroup) {
|
||||
if (titleView == null) return;
|
||||
|
||||
if (isCreateGroup) {
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_new_chat));
|
||||
} else {
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_from_contact));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public ConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mAdapter.setItemAvatarRadius(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemTopTextSize(int size) {
|
||||
mAdapter.setItemTopTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mAdapter.setItemBottomTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemDateTextSize(int size) {
|
||||
mAdapter.setItemDateTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener){
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(int state) {
|
||||
super.onScrollStateChanged(state);
|
||||
if (state == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (layoutManager == null) {
|
||||
return;
|
||||
}
|
||||
int lastPosition = layoutManager.findLastCompletelyVisibleItemPosition();
|
||||
|
||||
if (mAdapter != null) {
|
||||
if (lastPosition == mAdapter.getItemCount() - 1 && !isLoadCompleted()) {
|
||||
mAdapter.onLoadingStateChanged(true);
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadConversation(long nextSeq) {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation(nextSeq);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLoadCompleted(){
|
||||
if (presenter != null) {
|
||||
return presenter.isLoadFinished();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private FoldedConversationListLayout conversationListLayout;
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
public FoldedConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationListLayout != null) {
|
||||
conversationListLayout.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.folded_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationListLayout = findViewById(R.id.folded_conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
conversationListLayout.setAdapter((IConversationListAdapter) adapter);
|
||||
adapter.setShowFoldedStyle(false);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
conversationListLayout.loadConversation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getConversationList() {
|
||||
return conversationListLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationFoldPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public FoldedConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mAdapter.setItemAvatarRadius(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemTopTextSize(int size) {
|
||||
mAdapter.setItemTopTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mAdapter.setItemBottomTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemDateTextSize(int size) {
|
||||
mAdapter.setItemDateTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ForwardConversationSelectorAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
|
||||
private Context context;
|
||||
private List<ConversationInfo> list;
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
|
||||
public ForwardConversationSelectorAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
super.onAttachedToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConversationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ConversationViewHolder(LayoutInflater.from(context).inflate(R.layout.forward_conversation_selector_item, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
ConversationViewHolder viewHolder = (ConversationViewHolder) holder;
|
||||
viewHolder.conversationUserIconView.setVisibility(View.VISIBLE);
|
||||
viewHolder.conversationUserIconView.setConversation(list.get(position));
|
||||
|
||||
viewHolder.conversationUserIconView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mOnItemClickListener.onClick(v, position);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void setDataSource(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
if (list != null) {
|
||||
list.clear();
|
||||
}
|
||||
} else {
|
||||
list = dataSource;
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.mOnItemClickListener = listener;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(View view, int position);
|
||||
}
|
||||
|
||||
static class ConversationViewHolder extends RecyclerView.ViewHolder {
|
||||
public ConversationIconView conversationUserIconView;
|
||||
public ConversationViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
conversationUserIconView = itemView.findViewById(R.id.conversation_user_icon_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ForwardSelectLayout extends RelativeLayout implements IConversationLayout {
|
||||
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private ConversationListLayout conversationList;
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
public ForwardSelectLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationList != null) {
|
||||
conversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化相关UI元素
|
||||
*/
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.forward_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationList = findViewById(R.id.conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
adapter.setForwardFragment(true);
|
||||
conversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
presenter.setAdapter(adapter);
|
||||
presenter.loadConversation(0);
|
||||
}
|
||||
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return conversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markRead) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupAtInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuicore.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationUtils {
|
||||
private static final String TAG = ConversationUtils.class.getSimpleName();
|
||||
|
||||
public static List<ConversationInfo> convertV2TIMConversationList(List<V2TIMConversation> conversationList) {
|
||||
List<ConversationInfo> conversationInfoList = new ArrayList<>();
|
||||
if (conversationList != null) {
|
||||
for(V2TIMConversation conversation : conversationList) {
|
||||
conversationInfoList.add(convertV2TIMConversation(conversation));
|
||||
}
|
||||
}
|
||||
return conversationInfoList;
|
||||
}
|
||||
|
||||
public static ConversationInfo convertV2TIMConversation(final V2TIMConversation conversation) {
|
||||
if (conversation == null) {
|
||||
return null;
|
||||
}
|
||||
TUIConversationLog.i(TAG, "TIMConversation2ConversationInfo id:" + conversation.getConversationID()
|
||||
+ "|name:" + conversation.getShowName()
|
||||
+ "|unreadNum:" + conversation.getUnreadCount());
|
||||
final ConversationInfo info = new ConversationInfo();
|
||||
info.setConversation(conversation);
|
||||
int type = conversation.getType();
|
||||
if (type != V2TIMConversation.V2TIM_C2C && type != V2TIMConversation.V2TIM_GROUP) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isGroup = type == V2TIMConversation.V2TIM_GROUP;
|
||||
|
||||
String draftText = conversation.getDraftText();
|
||||
if (!TextUtils.isEmpty(draftText)) {
|
||||
DraftInfo draftInfo = new DraftInfo();
|
||||
draftInfo.setDraftText(draftText);
|
||||
draftInfo.setDraftTime(conversation.getDraftTimestamp());
|
||||
info.setDraft(draftInfo);
|
||||
}
|
||||
V2TIMMessage message = conversation.getLastMessage();
|
||||
if (message == null) {
|
||||
long time = DateTimeUtil.getStringToDate("0001-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
|
||||
info.setLastMessageTime(time);
|
||||
} else {
|
||||
info.setLastMessageTime(message.getTimestamp());
|
||||
info.setLastMessage(message);
|
||||
}
|
||||
|
||||
int atInfoType = getAtInfoType(conversation);
|
||||
switch (atInfoType){
|
||||
case V2TIMGroupAtInfo.TIM_AT_ME:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_me));
|
||||
break;
|
||||
case V2TIMGroupAtInfo.TIM_AT_ALL:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_all));
|
||||
break;
|
||||
case V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_all_me));
|
||||
break;
|
||||
default:
|
||||
info.setAtInfoText("");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
info.setTitle(conversation.getShowName());
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
if (isGroup) {
|
||||
if (!TextUtils.isEmpty(conversation.getFaceUrl())) {
|
||||
faceList.add(conversation.getFaceUrl());
|
||||
}
|
||||
} else {
|
||||
if (TextUtils.isEmpty(conversation.getFaceUrl())) {
|
||||
faceList.add(TUIConfig.getDefaultAvatarImage());
|
||||
} else {
|
||||
faceList.add(conversation.getFaceUrl());
|
||||
}
|
||||
}
|
||||
info.setIconPath(conversation.getFaceUrl());
|
||||
info.setIconUrlList(faceList);
|
||||
|
||||
if (isGroup) {
|
||||
info.setId(conversation.getGroupID());
|
||||
info.setGroupType(conversation.getGroupType());
|
||||
} else {
|
||||
info.setId(conversation.getUserID());
|
||||
}
|
||||
|
||||
if (V2TIMManager.GROUP_TYPE_MEETING.equals(conversation.getGroupType())) {
|
||||
info.setShowDisturbIcon(false);
|
||||
} else {
|
||||
info.setShowDisturbIcon(conversation.getRecvOpt() == V2TIMMessage.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE);
|
||||
}
|
||||
info.setConversationId(conversation.getConversationID());
|
||||
info.setGroup(isGroup);
|
||||
|
||||
if (!V2TIMManager.GROUP_TYPE_AVCHATROOM.equals(conversation.getGroupType())) {
|
||||
info.setUnRead(conversation.getUnreadCount());
|
||||
}
|
||||
info.setTop(conversation.isPinned());
|
||||
info.setOrderKey(conversation.getOrderKey());
|
||||
if (conversation.getMarkList() != null) {
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD)) {
|
||||
info.setMarkFold(true);
|
||||
} else {
|
||||
info.setMarkFold(false);
|
||||
}
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD)) {
|
||||
info.setMarkUnread(true);
|
||||
} else {
|
||||
info.setMarkUnread(false);
|
||||
}
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
|
||||
info.setMarkHidden(true);
|
||||
} else {
|
||||
info.setMarkHidden(false);
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private static int getAtInfoType(V2TIMConversation conversation){
|
||||
int atInfoType = 0;
|
||||
boolean atMe = false;
|
||||
boolean atAll = false;
|
||||
|
||||
List<V2TIMGroupAtInfo> atInfoList = conversation.getGroupAtInfoList();
|
||||
|
||||
if (atInfoList == null || atInfoList.isEmpty()){
|
||||
return V2TIMGroupAtInfo.TIM_AT_UNKNOWN;
|
||||
}
|
||||
|
||||
for(V2TIMGroupAtInfo atInfo : atInfoList){
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ME){
|
||||
atMe = true;
|
||||
continue;
|
||||
}
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ALL){
|
||||
atAll = true;
|
||||
continue;
|
||||
}
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME){
|
||||
atMe = true;
|
||||
atAll = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (atAll && atMe){
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME;
|
||||
} else if (atAll){
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ALL;
|
||||
} else if (atMe){
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ME;
|
||||
} else {
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_UNKNOWN;
|
||||
}
|
||||
|
||||
return atInfoType;
|
||||
}
|
||||
|
||||
public static boolean isIgnored(ConversationInfo conversationInfo) {
|
||||
if (V2TIMManager.GROUP_TYPE_AVCHATROOM.equals(conversationInfo.getGroupType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getListUnspecifiedWidth(PopDialogAdapter adapter, ListView listView) {
|
||||
if (adapter == null || listView == null) {
|
||||
return 0;
|
||||
}
|
||||
int maxWidth = 0;
|
||||
View convertView = null;
|
||||
int childCount = adapter.getCount();
|
||||
if (childCount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = adapter.getView(i, convertView, listView);
|
||||
child.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
maxWidth = Math.max(maxWidth, child.getMeasuredWidth() + child.getPaddingLeft() + child.getPaddingRight());
|
||||
convertView = child;
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import com.tencent.imsdk.common.IMLog;
|
||||
|
||||
public class TUIConversationLog extends IMLog {
|
||||
|
||||
private static final String PRE = "TUIKit-";
|
||||
|
||||
private static String mixTag(String tag) {
|
||||
return PRE + tag;
|
||||
}
|
||||
|
||||
public static void v(String strTag, String strInfo) {
|
||||
IMLog.v(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void d(String strTag, String strInfo) {
|
||||
IMLog.d(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void i(String strTag, String strInfo) {
|
||||
IMLog.i(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void w(String strTag, String strInfo) {
|
||||
IMLog.w(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void w(String strTag, String strInfo, Throwable e) {
|
||||
IMLog.w(mixTag(strTag), strInfo + e.getMessage());
|
||||
}
|
||||
|
||||
public static void e(String strTag, String strInfo) {
|
||||
IMLog.e(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
|
||||
public static <T> void callbackOnError(IUIKitCallback<T> callBack, String module, int errCode, String desc) {
|
||||
if (callBack != null) {
|
||||
callBack.onError(module, errCode, ErrorMessageConverter.convertIMError(errCode, desc));
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void callbackOnError(IUIKitCallback<T> callBack, int errCode, String desc) {
|
||||
if (callBack != null) {
|
||||
callBack.onError(null, errCode, ErrorMessageConverter.convertIMError(errCode, desc));
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void callbackOnSuccess(IUIKitCallback<T> callBack, T data) {
|
||||
if (callBack != null) {
|
||||
callBack.onSuccess(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.config;
|
||||
|
||||
public class TUIConversationConfig {
|
||||
public static final String TAG = TUIConversationConfig.class.getSimpleName();
|
||||
private static TUIConversationConfig instance;
|
||||
private boolean isShowUserStatus;
|
||||
|
||||
public static TUIConversationConfig getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new TUIConversationConfig();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean isShowUserStatus() {
|
||||
return isShowUserStatus;
|
||||
}
|
||||
|
||||
public void setShowUserStatus(boolean showUserStatus) {
|
||||
isShowUserStatus = showUserStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.interfaces;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ConversationEventListener {
|
||||
void deleteConversation(String chatId, boolean isGroup);
|
||||
void clearConversationMessage(String chatId, boolean isGroup);
|
||||
void clearFoldMarkAndDeleteConversation(String conversationId);
|
||||
void setConversationTop(String chatId, boolean isChecked, IUIKitCallback<Void> iuiKitCallBack);
|
||||
boolean isTopConversation(String chatId);
|
||||
long getUnreadTotal();
|
||||
void onSyncServerFinish();
|
||||
void updateTotalUnreadMessageCount(long count);
|
||||
void onNewConversation(List<ConversationInfo> conversationList);
|
||||
void onConversationChanged(List<ConversationInfo> conversationList);
|
||||
void onFriendRemarkChanged(String id, String remark);
|
||||
void onUserStatusChanged(List<V2TIMUserStatus> userStatusList);
|
||||
void refreshUserStatusFragmentUI();
|
||||
void onReceiveMessage(String conversationID, boolean isTypingMessage);
|
||||
void onMessageSendForHideConversation(String conversationID);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IConversationListAdapter {
|
||||
/**
|
||||
* 获取适配器的条目数据,返回的是ConversationInfo对象或其子对象
|
||||
*
|
||||
* Get the entry data of the adapter, which returns the ConversationInfo object or its sub-objects
|
||||
*
|
||||
* @param position
|
||||
* @return ConversationInfo
|
||||
*/
|
||||
ConversationInfo getItem(int position);
|
||||
|
||||
void onLoadingStateChanged(boolean isLoading);
|
||||
|
||||
void onDataSourceChanged(List<ConversationInfo> conversationInfoList);
|
||||
|
||||
void onViewNeedRefresh();
|
||||
|
||||
void onItemRemoved(int position);
|
||||
|
||||
void onItemInserted(int position);
|
||||
|
||||
void onItemChanged(int position);
|
||||
|
||||
void onItemRangeChanged(int startPosition, int count);
|
||||
|
||||
void onConversationChanged(List<ConversationInfo> conversationInfoList);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ILayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public interface IConversationLayout extends ILayout {
|
||||
View getConversationList();
|
||||
void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack);
|
||||
void deleteConversation(ConversationInfo conversation);
|
||||
void clearConversationMessage(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* 隐藏普通会话
|
||||
* Hide normal conversation
|
||||
*/
|
||||
void markConversationHidden(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* 标记会话已读/未读
|
||||
* Mark conversation read or unread
|
||||
*/
|
||||
void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread);
|
||||
|
||||
/**
|
||||
* 隐藏整个折叠的会话 item
|
||||
* Hide folded conversation item
|
||||
*/
|
||||
void hideFoldedItem(boolean needHide);
|
||||
|
||||
/**
|
||||
* 清除折叠 item 本地未读状态
|
||||
* Clear unread status of fold item
|
||||
*/
|
||||
void clearUnreadStatusOfFoldItem();
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListAdapter;
|
||||
|
||||
public interface IConversationListLayout {
|
||||
void setBackground(int resId);
|
||||
void setOnConversationAdapterListener(OnConversationAdapterListener listener);
|
||||
|
||||
/**
|
||||
* 不显示小红点未读消息条数开关
|
||||
*
|
||||
* Do not display the switch for the number of unread messages with the small red dot
|
||||
*
|
||||
* @param flag 默认false,表示显示
|
||||
*/
|
||||
void disableItemUnreadDot(boolean flag);
|
||||
|
||||
/**
|
||||
* 设置会话Item头像圆角
|
||||
*
|
||||
* Set session item avatar rounded corners
|
||||
*
|
||||
* @param radius
|
||||
*/
|
||||
void setItemAvatarRadius(int radius);
|
||||
|
||||
/**
|
||||
* 设置会话Item顶部字体大小
|
||||
*
|
||||
* Set the font size at the top of the session item
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemTopTextSize(int size);
|
||||
|
||||
/**
|
||||
* 设置会话Item底部字体大小
|
||||
*
|
||||
* Set the font size at the bottom of the session item
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemBottomTextSize(int size);
|
||||
|
||||
/**
|
||||
* 设置会话Item日期字体大小
|
||||
*
|
||||
* Set the session item date font size
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
void setItemDateTextSize(int size);
|
||||
|
||||
|
||||
View getListLayout();
|
||||
ConversationListAdapter getAdapter();
|
||||
void setAdapter(IConversationListAdapter adapter);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface IConversationProvider {
|
||||
|
||||
/**
|
||||
* 获取具体的会话数据集合,ConversationContainer依据该数据集合展示会话列表
|
||||
*
|
||||
* Get a specific session data set, and ConversationContainer displays the session list based on the data set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ConversationInfo> getDataSource();
|
||||
|
||||
/**
|
||||
* 批量添加会话条目
|
||||
*
|
||||
* Bulk add session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean addConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* 删除会话条目
|
||||
*
|
||||
* Delete session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean deleteConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* 更新会话条目
|
||||
*
|
||||
* Update session entries
|
||||
*
|
||||
* @param conversations 会话数据集合
|
||||
* @return
|
||||
*/
|
||||
boolean updateConversations(List<ConversationInfo> conversations);
|
||||
|
||||
|
||||
/**
|
||||
* 绑定会话适配器时触发的调用,在调用{@link com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider}时自动调用
|
||||
*
|
||||
* Called when a session adapter is bound, automatically called when {@link com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider} is called
|
||||
*
|
||||
* @param adapter 会话UI显示适配器
|
||||
* @return
|
||||
*/
|
||||
|
||||
void attachAdapter(IConversationListAdapter adapter);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OnConversationAdapterListener {
|
||||
void onItemClick(View view, int viewType, ConversationInfo conversationInfo);
|
||||
void OnItemLongClick(View view, ConversationInfo conversationInfo);
|
||||
void onConversationChanged(List<ConversationInfo> dataSource);
|
||||
void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread);
|
||||
void onMarkConversationHidden(View view, ConversationInfo conversationInfo);
|
||||
void onClickMoreView(View view, ConversationInfo conversationInfo);
|
||||
void onSwipeConversationChanged(ConversationInfo conversationInfo);
|
||||
}
|
||||
@@ -0,0 +1,642 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.Menu;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationMinimalistFragment extends BaseFragment {
|
||||
private View mBaseView;
|
||||
private ConversationLayout mConversationLayout;
|
||||
private ListView mConversationPopList;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
private AlertDialog mBottomDialog;
|
||||
private boolean isShowReadButton, isShowReadAllButton;
|
||||
private BroadcastReceiver unreadCountReceiver;
|
||||
private Menu menu;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
private ConversationListAdapter mAdapter;
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalistui_conversation_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
// 从布局文件中获取会话列表面板
|
||||
mConversationLayout = mBaseView.findViewById(R.id.conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
presenter.setConversationListener();
|
||||
presenter.setShowType(ConversationPresenter.SHOW_TYPE_CONVERSATION_LIST_WITH_FOLD);
|
||||
mConversationLayout.setPresenter(presenter);
|
||||
|
||||
// 会话列表面板的默认UI和交互初始化
|
||||
mConversationLayout.initDefault();
|
||||
// 通过API设置ConversataonLayout各种属性的样例,开发者可以打开注释,体验效果
|
||||
// ConversationLayoutSetting.customizeConversation(mConversationLayout);
|
||||
isShowReadButton = false;
|
||||
isShowReadAllButton = false;
|
||||
mAdapter = mConversationLayout.getConversationList().getAdapter();
|
||||
mConversationLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
if (mConversationLayout.isMultiSelected()) {
|
||||
if (mAdapter == null) {
|
||||
refreshEditConversationDialog(0);
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
if (mSelectConversations == null) {
|
||||
refreshEditConversationDialog(0);
|
||||
return;
|
||||
}
|
||||
isShowReadButton = false;
|
||||
for(ConversationInfo conversation : mSelectConversations) {
|
||||
if (conversation.isMarkUnread() || conversation.getUnRead() > 0) {
|
||||
isShowReadButton = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
refreshEditConversationDialog(mSelectConversations.size());
|
||||
} else if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.clearUnreadStatusOfFoldItem();
|
||||
startFoldedConversationActivity();
|
||||
} else {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null)return;
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null)return;
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
if (mAdapter != null) {
|
||||
mAdapter.closeAllSwipeItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {
|
||||
showConversationMoreActionDialog(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {
|
||||
if (conversationInfo == null) {
|
||||
popWindowConversationId = "";
|
||||
return;
|
||||
}
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
}
|
||||
});
|
||||
|
||||
mConversationLayout.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onEditConversationStartClick() {
|
||||
showEditConversationDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditConversationEndClick() {
|
||||
closeEditConversationDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartChatClick() {
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
if (menu.isShowing()) {
|
||||
menu.hide();
|
||||
} else {
|
||||
menu.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
initUnreadCountReceiver();
|
||||
restoreConversationItemBackground();
|
||||
setConversationMenu();
|
||||
}
|
||||
|
||||
public void restoreConversationItemBackground() {
|
||||
if (mConversationLayout.getConversationList().getAdapter() != null &&
|
||||
mConversationLayout.getConversationList().getAdapter().isClick()) {
|
||||
mConversationLayout.getConversationList().getAdapter().setClick(false);
|
||||
mConversationLayout.getConversationList().getAdapter().notifyItemChanged(mConversationLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void initUnreadCountReceiver() {
|
||||
unreadCountReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
long unreadCount = intent.getLongExtra(TUIConstants.UNREAD_COUNT_EXTRA, 0);
|
||||
if (unreadCount > 0) {
|
||||
isShowReadAllButton = true;
|
||||
} else {
|
||||
isShowReadAllButton = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
IntentFilter unreadCountFilter = new IntentFilter();
|
||||
unreadCountFilter.addAction(TUIConstants.CONVERSATION_UNREAD_COUNT_ACTION);
|
||||
LocalBroadcastManager.getInstance(getContext()).registerReceiver(unreadCountReceiver, unreadCountFilter);
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
// 设置长按conversation显示PopAction
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.hideFoldedItem(true);
|
||||
} else {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mConversationLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void addDeletePopMenuAction() {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mConversationLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
mConversationPopActions.add(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 长按会话item弹框
|
||||
* @param view 长按 view
|
||||
* @param conversationInfo 会话数据对象
|
||||
*/
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (!conversationInfo.isMarkFold()) {
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
addDeletePopMenuAction();
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = - view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mConversationLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
|
||||
private void startFoldedConversationActivity() {
|
||||
Intent intent = new Intent(getActivity(), TUIFoldedConversationMinimalistActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public interface OnClickListener {
|
||||
void onEditConversationStartClick();
|
||||
void onEditConversationEndClick();
|
||||
void onStartChatClick();
|
||||
}
|
||||
|
||||
private void showEditConversationDialog(){
|
||||
if (mBottomDialog != null && mBottomDialog.isShowing()) {
|
||||
return;
|
||||
}
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.minimalist_bottom_bar,null,false);
|
||||
mBottomDialog = new AlertDialog.Builder(getContext()).setView(view).create();
|
||||
|
||||
TextView markReadView = view.findViewById(R.id.mark_read);
|
||||
TextView notDisplayView = view.findViewById(R.id.not_display);
|
||||
TextView deleteChatView = view.findViewById(R.id.delete_chat);
|
||||
|
||||
if (isShowReadAllButton) {
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
markReadView.setText(getString(R.string.has_all_read));
|
||||
} else {
|
||||
markReadView.setAlpha(0.5f);
|
||||
markReadView.setEnabled(false);
|
||||
markReadView.setText(getString(R.string.mark_read));
|
||||
}
|
||||
notDisplayView.setAlpha(0.5f);
|
||||
notDisplayView.setEnabled(false);
|
||||
deleteChatView.setAlpha(0.5f);
|
||||
deleteChatView.setEnabled(false);
|
||||
|
||||
markReadView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (markReadView.getText().equals(getString(R.string.has_all_read))) {
|
||||
presenter.clearAllUnreadMessage();
|
||||
} else {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for (ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
notDisplayView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for(ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
deleteChatView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for(ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.deleteConversation(conversationInfo);
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
mBottomDialog.setCanceledOnTouchOutside(false);
|
||||
mBottomDialog.show();
|
||||
Window win = mBottomDialog.getWindow();
|
||||
win.setGravity(Gravity.BOTTOM); // 这里控制弹出的位置
|
||||
win.getDecorView().setPadding(0, 0, 0, 0);
|
||||
WindowManager.LayoutParams lp = win.getAttributes();
|
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mBottomDialog.getWindow().setBackgroundDrawableResource(R.color.conversation_bottom_bg);
|
||||
win.setAttributes(lp);
|
||||
|
||||
win.setDimAmount(0f);
|
||||
win.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
|
||||
win.setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
|
||||
|
||||
mBottomDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshEditConversationDialog(int selectSize) {
|
||||
if (mBottomDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TextView markReadView = mBottomDialog.findViewById(R.id.mark_read);
|
||||
TextView notDisplayView = mBottomDialog.findViewById(R.id.not_display);
|
||||
TextView deleteChatView = mBottomDialog.findViewById(R.id.delete_chat);
|
||||
|
||||
if (selectSize <= 0) {
|
||||
deleteChatView.setAlpha(0.5f);
|
||||
deleteChatView.setEnabled(false);
|
||||
|
||||
notDisplayView.setAlpha(0.5f);
|
||||
notDisplayView.setEnabled(false);
|
||||
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
markReadView.setText(getString(R.string.has_all_read));
|
||||
} else {
|
||||
deleteChatView.setAlpha(1f);
|
||||
deleteChatView.setEnabled(true);
|
||||
|
||||
notDisplayView.setAlpha(1f);
|
||||
notDisplayView.setEnabled(true);
|
||||
|
||||
markReadView.setText(getString(R.string.mark_read));
|
||||
if (isShowReadButton) {
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
} else {
|
||||
markReadView.setAlpha(0.5f);
|
||||
markReadView.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetEditConversationStatus() {
|
||||
isShowReadAllButton = false;
|
||||
isShowReadButton = false;
|
||||
if (mBottomDialog != null) {
|
||||
mBottomDialog.dismiss();
|
||||
}
|
||||
mConversationLayout.resetTitileBar();
|
||||
}
|
||||
|
||||
private void closeEditConversationDialog() {
|
||||
if (mBottomDialog != null) {
|
||||
mBottomDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private void setConversationMenu() {
|
||||
menu = new Menu(getActivity(), mConversationLayout.getCreateChatView());
|
||||
PopActionClickListener popActionClickListener = new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int position, Object data) {
|
||||
PopMenuAction action = (PopMenuAction) data;
|
||||
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.start_conversation))) {
|
||||
TUICore.startActivity("StartC2CChatMinimalistActivity", null);
|
||||
}
|
||||
|
||||
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_group_chat))) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
TUICore.startActivity("StartGroupChatMinimalistActivity", bundle);
|
||||
}
|
||||
|
||||
menu.hide();
|
||||
}
|
||||
};
|
||||
|
||||
List<PopMenuAction> menuActions = new ArrayList<>();
|
||||
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
|
||||
action.setActionName(getResources().getString(R.string.start_conversation));
|
||||
action.setActionClickListener(popActionClickListener);
|
||||
action.setIconResId(R.drawable.create_c2c);
|
||||
menuActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.create_group_chat));
|
||||
action.setIconResId(R.drawable.group_icon);
|
||||
action.setActionClickListener(popActionClickListener);
|
||||
menuActions.add(action);
|
||||
|
||||
menu.setMenuAction(menuActions);
|
||||
}
|
||||
|
||||
private void showConversationMoreActionDialog(ConversationInfo conversationInfo){
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.minimalist_more_dialog,null,false);
|
||||
AlertDialog moreDialog = new AlertDialog.Builder(getContext()).setView(view).create();
|
||||
|
||||
TextView setTopView = view.findViewById(R.id.top_set);
|
||||
TextView notDisplayView = view.findViewById(R.id.not_display);
|
||||
TextView clearChatView = view.findViewById(R.id.clear_chat);
|
||||
TextView deleteChatView = view.findViewById(R.id.delete_chat);
|
||||
TextView cancelView = view.findViewById(R.id.cancel_button);
|
||||
|
||||
|
||||
if (conversationInfo.isTop()) {
|
||||
setTopView.setText(getString(R.string.quit_chat_top));
|
||||
} else {
|
||||
setTopView.setText(getString(R.string.chat_top));
|
||||
}
|
||||
setTopView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.setConversationTop(conversationInfo, new IUIKitCallback() {
|
||||
@Override
|
||||
public void onSuccess(Object data) {
|
||||
super.onSuccess(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
super.onError(module, errCode, errMsg);
|
||||
}
|
||||
});
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
notDisplayView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
clearChatView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.clearConversationMessage(conversationInfo);
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
deleteChatView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.deleteConversation(conversationInfo);
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
cancelView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
moreDialog.setCanceledOnTouchOutside(false);
|
||||
Window win = moreDialog.getWindow();
|
||||
WindowManager.LayoutParams lp = win.getAttributes();
|
||||
lp.width = lp.width - ScreenUtil.getPxByDp(16f);
|
||||
lp.y = ScreenUtil.getPxByDp(34f);
|
||||
moreDialog.getWindow().setBackgroundDrawableResource(com.tencent.qcloud.tuicore.R.color.status_bar_color);
|
||||
win.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
|
||||
win.setAttributes(lp);
|
||||
moreDialog.show();
|
||||
|
||||
moreDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (unreadCountReceiver != null) {
|
||||
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(unreadCountReceiver);
|
||||
unreadCountReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
|
||||
public class TUIFoldedConversationMinimalistActivity extends BaseLightActivity {
|
||||
private TUIFoldedConversationMinimalistFragment mTUIFoldedConversationMinimalistFragment;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.folded_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIFoldedConversationMinimalistFragment = new TUIFoldedConversationMinimalistFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIFoldedConversationMinimalistFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIFoldedConversationMinimalistFragment extends BaseFragment {
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private FoldedConversationLayout mFoldedLayout;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private ListView mConversationPopList;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalist_folded_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mFoldedLayout = mBaseView.findViewById(R.id.folded_conversation_layout);
|
||||
mTitleBarLayout = mFoldedLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle(getResources().getString(R.string.folded_group_chat), ITitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
presenter = new ConversationFoldPresenter();
|
||||
presenter.initListener();
|
||||
|
||||
mFoldedLayout.setPresenter(presenter);
|
||||
mFoldedLayout.initDefault();
|
||||
|
||||
mFoldedLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null)return;
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null)return;
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {
|
||||
if (conversationInfo == null) {
|
||||
popWindowConversationId = "";
|
||||
return;
|
||||
}
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
// 设置长按conversation显示PopAction
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
mFoldedLayout.markConversationHidden((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
conversationPopActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void restoreConversationItemBackground() {
|
||||
if (mFoldedLayout.getConversationList().getAdapter() != null &&
|
||||
mFoldedLayout.getConversationList().getAdapter().isClick()) {
|
||||
mFoldedLayout.getConversationList().getAdapter().setClick(false);
|
||||
mFoldedLayout.getConversationList().getAdapter().notifyItemChanged(mFoldedLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = - view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mFoldedLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
|
||||
public class TUIForwardSelectMinimalistActivity extends BaseLightActivity {
|
||||
private static final String TAG = TUIForwardSelectMinimalistActivity.class.getSimpleName();
|
||||
|
||||
private TUIForwardSelectMinimalistFragment mTUIForwardSelectMinimalistFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.forward_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
TUIConversationLog.i(TAG, "onNewIntent");
|
||||
super.onNewIntent(intent);;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
TUIConversationLog.i(TAG, "onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIForwardSelectMinimalistFragment = new TUIForwardSelectMinimalistFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIForwardSelectMinimalistFragment).commitAllowingStateLoss();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.fragments.BaseFragment;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ForwardConversationSelectorAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ForwardSelectLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIForwardSelectMinimalistFragment extends BaseFragment {
|
||||
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private ForwardSelectLayout mForwardLayout;
|
||||
|
||||
private RecyclerView mForwardSelectlistView;
|
||||
private ForwardConversationSelectorAdapter mAdapter;
|
||||
private List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mContactDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mAllSelectedConversations = new ArrayList<>();
|
||||
private RelativeLayout mForwardSelectlistViewLayout;
|
||||
private TextView mSureView;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
private static final String TAG = TUIForwardSelectMinimalistFragment.class.getSimpleName();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalist_forward_fragment, container, false);
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
mForwardLayout = view.findViewById(R.id.forward_conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
mForwardLayout.setPresenter(presenter);
|
||||
|
||||
mForwardLayout.initDefault();
|
||||
|
||||
customizeConversation();
|
||||
mForwardLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
if (viewType == ConversationInfo.TYPE_RECENT_LABEL){
|
||||
return;
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT){
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))){
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, false);
|
||||
TUICore.startActivity(TUIForwardSelectMinimalistFragment.this, "ForwardSelectGroupMinimalistActivity", param, TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE);
|
||||
}else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, true);
|
||||
TUICore.startActivity(TUIForwardSelectMinimalistFragment.this, "ForwardSelectGroupMinimalistActivity", param, TUIConversationConstants.FORWARD_CREATE_GROUP_CODE);
|
||||
}else{
|
||||
TUIConversationLog.d(TAG,"Titlebar exception");
|
||||
}
|
||||
} else {
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))) {
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
checkRepeat();
|
||||
refreshSelectConversations();
|
||||
} else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
forwardMessages(conversationInfo);
|
||||
} else {
|
||||
forwardMessages(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mForwardSelectlistViewLayout = view.findViewById(R.id.forward_select_list_layout);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mForwardSelectlistView = view.findViewById(R.id.forward_select_list);
|
||||
mForwardSelectlistView.setLayoutManager(new CustomLinearLayoutManager(getContext(), CustomLinearLayoutManager.HORIZONTAL, false));
|
||||
mAdapter = new ForwardConversationSelectorAdapter(this.getContext());
|
||||
mForwardSelectlistView.setAdapter(mAdapter);
|
||||
|
||||
mAdapter.setOnItemClickListener(new ForwardConversationSelectorAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position) {
|
||||
boolean needFresh = false;
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
if(position < mDataSource.size()) {
|
||||
mDataSource.remove(position);
|
||||
mForwardLayout.getConversationList().getAdapter().setSelectConversations(mDataSource);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!needFresh) {
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0) {
|
||||
int dataSourcePosition = mDataSource == null ? 0 : mDataSource.size();
|
||||
if (position - dataSourcePosition < mContactDataSource.size()) {
|
||||
mContactDataSource.remove(position - dataSourcePosition);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needFresh) {
|
||||
refreshSelectConversations();
|
||||
}
|
||||
}
|
||||
});
|
||||
mSureView = view.findViewById(R.id.btn_msg_ok);
|
||||
mSureView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> conversationMap = new HashMap<>();
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
for (int i=0;i<mDataSource.size();i++){
|
||||
conversationMap.put(mDataSource.get(i).getId(), mDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0){
|
||||
for (int i=0;i<mContactDataSource.size();i++){
|
||||
conversationMap.put(mContactDataSource.get(i).getId(), mContactDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, conversationMap);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelectConversations();
|
||||
initTitleAction();
|
||||
}
|
||||
|
||||
private void refreshSelectConversations(){
|
||||
mAllSelectedConversations.clear();
|
||||
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
|
||||
if (mDataSource != null && mDataSource.size() != 0){
|
||||
mAllSelectedConversations.addAll(mDataSource);
|
||||
}
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0){
|
||||
mAllSelectedConversations.addAll(mContactDataSource);
|
||||
}
|
||||
|
||||
mAdapter.setDataSource(mAllSelectedConversations);
|
||||
|
||||
if (mAllSelectedConversations == null || mAllSelectedConversations.size() == 0){
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure));
|
||||
mSureView.setVisibility(View.GONE);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mSureView.setVisibility(View.VISIBLE);
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure) + "(" + mAllSelectedConversations.size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void forwardMessages(final ConversationInfo conversationInfo){
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle("");
|
||||
builder.setMessage(getString(R.string.forward_alert_title));
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(getString(com.tencent.qcloud.tuicore.R.string.sure), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> chatInfo = new HashMap<>();
|
||||
chatInfo.put(conversationInfo.getId(), conversationInfo.isGroup());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, chatInfo);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(com.tencent.qcloud.tuicore.R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void customizeConversation(){
|
||||
mTitleBarLayout = mForwardLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle("", TitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.getLeftGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), ITitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
mTitleBarLayout.getLeftIcon().setVisibility(View.GONE);
|
||||
mTitleBarLayout.getRightIcon().setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
private void initTitleAction() {
|
||||
mForwardLayout.getTitleBar().setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))){
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), TitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(false);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
mAdapter.setDataSource(null);
|
||||
mAllSelectedConversations.clear();
|
||||
}else if(mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))){
|
||||
getActivity().finish();
|
||||
}else{
|
||||
TUIConversationLog.d(TAG,"Titlebar exception");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mForwardLayout.getTitleBar().setOnRightClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.GONE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_cancle), TitleBarLayout.Position.LEFT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(true);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == TUIConversationConstants.FORWARD_CREATE_GROUP_CODE && resultCode == TUIConversationConstants.FORWARD_CREATE_GROUP_CODE) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, data);
|
||||
getActivity().finish();
|
||||
}
|
||||
} else if (requestCode == TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE && resultCode == TUIConversationConstants.FORWARD_SELECT_MEMBERS_CODE){
|
||||
HashMap<String, String> conversationMap = (HashMap<String, String>) data.getSerializableExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY);
|
||||
if (conversationMap == null || conversationMap.isEmpty()){
|
||||
mContactDataSource.clear();
|
||||
refreshSelectConversations();
|
||||
return;
|
||||
}
|
||||
|
||||
mContactDataSource.clear();
|
||||
for (Map.Entry<String, String> entry: conversationMap.entrySet()){
|
||||
ConversationInfo conversationInfo = new ConversationInfo();
|
||||
List<Object> iconList = new ArrayList<>();
|
||||
iconList.add(entry.getValue());
|
||||
conversationInfo.setIconUrlList(iconList);
|
||||
conversationInfo.setId(entry.getKey());
|
||||
conversationInfo.setGroup(false);
|
||||
mContactDataSource.add(conversationInfo);
|
||||
}
|
||||
checkRepeat();
|
||||
|
||||
refreshSelectConversations();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRepeat() {
|
||||
Iterator<ConversationInfo> iterator = mContactDataSource.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConversationInfo conversationInfo = iterator.next();
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
for (int i = 0; i < mDataSource.size(); i++) {
|
||||
if (conversationInfo.getId().equals(mDataSource.get(i).getId())) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.setting;
|
||||
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout;
|
||||
|
||||
public class ConversationLayoutSetting {
|
||||
|
||||
public static void customizeConversation(final ConversationLayout layout) {
|
||||
|
||||
ConversationListLayout listLayout = (ConversationListLayout) layout.getConversationList();
|
||||
|
||||
listLayout.setItemAvatarRadius((int) ScreenUtil.dp2px(49f, listLayout.getResources().getDisplayMetrics()));
|
||||
|
||||
// 动态插入,删除Item,包括自定义会话
|
||||
// final ConversationInfo customInfo = new ConversationInfo();
|
||||
// customInfo.setType(ConversationInfo.TYPE_CUSTOM);
|
||||
// customInfo.setId("自定义会话");
|
||||
// customInfo.setGroup(false);
|
||||
// customInfo.setTitle("乔丹风行8代跑鞋 风随我动!");
|
||||
// customInfo.setIconUrl("https://img1.gtimg.com/ninja/2/2019/03/ninja155375585738456.jpg");
|
||||
//
|
||||
//
|
||||
// new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// layout.addConversationInfo(0, customInfo);
|
||||
// }
|
||||
// }, 3000);
|
||||
|
||||
// new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// layout.removeConversationInfo(0);
|
||||
// }
|
||||
// }, 5000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
public static void startChatActivity(ConversationInfo conversationInfo) {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConstants.TUIChat.CHAT_TYPE, conversationInfo.isGroup() ? V2TIMConversation.V2TIM_GROUP : V2TIMConversation.V2TIM_C2C);
|
||||
param.putString(TUIConstants.TUIChat.CHAT_ID, conversationInfo.getId());
|
||||
param.putString(TUIConstants.TUIChat.CHAT_NAME, conversationInfo.getTitle());
|
||||
if (conversationInfo.getDraft() != null) {
|
||||
param.putString(TUIConstants.TUIChat.DRAFT_TEXT, conversationInfo.getDraft().getDraftText());
|
||||
param.putLong(TUIConstants.TUIChat.DRAFT_TIME, conversationInfo.getDraft().getDraftTime());
|
||||
}
|
||||
param.putBoolean(TUIConstants.TUIChat.IS_TOP_CHAT, conversationInfo.isTop());
|
||||
param.putString(TUIConstants.TUIChat.FACE_URL, conversationInfo.getIconPath());
|
||||
if (conversationInfo.isGroup()) {
|
||||
param.putString(TUIConstants.TUIChat.GROUP_TYPE, conversationInfo.getGroupType());
|
||||
param.putSerializable(TUIConstants.TUIChat.FACE_URL_LIST, (Serializable) conversationInfo.getIconUrlList());
|
||||
param.putSerializable(TUIConstants.TUIChat.AT_INFO_LIST, (Serializable) conversationInfo.getGroupAtInfoList());
|
||||
}
|
||||
if (conversationInfo.isGroup()) {
|
||||
TUICore.startActivity("TUIGroupChatMinimalistActivity", param);
|
||||
} else {
|
||||
TUICore.startActivity("TUIC2CChatMinimalistActivity", param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public abstract class ConversationBaseHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
protected View rootView;
|
||||
protected ConversationListAdapter mAdapter;
|
||||
|
||||
public ConversationBaseHolder(View itemView) {
|
||||
super(itemView);
|
||||
rootView = itemView;
|
||||
}
|
||||
|
||||
public void setAdapter(RecyclerView.Adapter adapter) {
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
|
||||
public abstract void layoutViews(ConversationInfo conversationInfo, int position);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.component.UnreadCountTextView;
|
||||
import com.tencent.qcloud.tuicore.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeLayout;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ConversationCommonHolder extends ConversationBaseHolder {
|
||||
|
||||
public ConversationIconView conversationIconView;
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected UnreadCountTextView unreadText;
|
||||
protected TextView atInfoText;
|
||||
protected ImageView disturbView;
|
||||
protected CheckBox multiSelectCheckBox;
|
||||
protected RelativeLayout messageStatusLayout;
|
||||
public ImageView messageSending;
|
||||
public ImageView messageFailed;
|
||||
private boolean isForwardMode = false;
|
||||
protected View userStatusView;
|
||||
private boolean showFoldedStyle = true;
|
||||
protected SwipeLayout swipeLayout;
|
||||
protected RelativeLayout markReadView, moreView;
|
||||
protected TextView markReadTextView, notDisplayView;
|
||||
protected ImageView markReadIconView;
|
||||
|
||||
public ConversationCommonHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
atInfoText = rootView.findViewById(R.id.conversation_at_msg);
|
||||
disturbView = rootView.findViewById(R.id.not_disturb);
|
||||
multiSelectCheckBox = rootView.findViewById(R.id.select_checkbox);
|
||||
messageStatusLayout = rootView.findViewById(R.id.message_status_layout);
|
||||
messageFailed = itemView.findViewById(R.id.message_status_failed);
|
||||
messageSending = itemView.findViewById(R.id.message_status_sending);
|
||||
userStatusView = itemView.findViewById(R.id.user_status);
|
||||
swipeLayout = itemView.findViewById(R.id.swipe);
|
||||
markReadView = itemView.findViewById(R.id.mark_read);
|
||||
moreView = itemView.findViewById(R.id.more_view);
|
||||
markReadTextView = itemView.findViewById(R.id.mark_read_text);
|
||||
notDisplayView = itemView.findViewById(R.id.not_display);
|
||||
markReadIconView = itemView.findViewById(R.id.mark_read_image);
|
||||
}
|
||||
|
||||
public void setForwardMode(boolean forwardMode) {
|
||||
isForwardMode = forwardMode;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
if (conversation.isTop() && !isForwardMode) {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
titleText.setText(R.string.folded_group_chat);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
} else {
|
||||
titleText.setText(conversation.getTitle());
|
||||
}
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
DraftInfo draftInfo = conversation.getDraft();
|
||||
String draftText = "";
|
||||
if (draftInfo != null) {
|
||||
Gson gson = new Gson();
|
||||
HashMap draftJsonMap;
|
||||
draftText = draftInfo.getDraftText();
|
||||
try {
|
||||
draftJsonMap = gson.fromJson(draftInfo.getDraftText(), HashMap.class);
|
||||
if (draftJsonMap != null) {
|
||||
draftText = (String) draftJsonMap.get("content");
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
TUIConversationLog.e("ConversationCommonHolder", " getDraftJsonMap error ");
|
||||
}
|
||||
}
|
||||
if (draftInfo != null) {
|
||||
messageText.setText(draftText);
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(draftInfo.getDraftTime() * 1000)));
|
||||
} else {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIChat.V2TIMMESSAGE, conversation.getLastMessage());
|
||||
String lastMsgDisplayString = (String) TUICore.callService(TUIConstants.TUIChat.SERVICE_NAME, TUIConstants.TUIChat.METHOD_GET_DISPLAY_STRING, param);
|
||||
// 获取要显示的字符
|
||||
// Get the characters to display
|
||||
if (lastMsgDisplayString != null) {
|
||||
messageText.setText(Html.fromHtml(lastMsgDisplayString));
|
||||
messageText.setTextColor(rootView.getResources().getColor(R.color.list_bottom_text_bg));
|
||||
}
|
||||
if (conversation.getLastMessage() != null) {
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(conversation.getLastMessageTime() * 1000)));
|
||||
}
|
||||
}
|
||||
|
||||
if (conversation.isShowDisturbIcon()) {
|
||||
if ((showFoldedStyle && conversation.isMarkFold())) {
|
||||
if (conversation.isMarkLocalUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (conversation.getUnRead() == 0) {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
|
||||
if (messageText.getText() != null) {
|
||||
String text = messageText.getText().toString();
|
||||
messageText.setText("[" + conversation.getUnRead() + rootView.getContext().getString(R.string.message_num) + "] " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("1");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (draftInfo != null) {
|
||||
atInfoText.setVisibility(View.VISIBLE);
|
||||
atInfoText.setText(R.string.drafts);
|
||||
atInfoText.setTextColor(Color.RED);
|
||||
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (conversation.getAtInfoText().isEmpty()) {
|
||||
atInfoText.setVisibility(View.GONE);
|
||||
} else {
|
||||
atInfoText.setVisibility(View.VISIBLE);
|
||||
atInfoText.setText(conversation.getAtInfoText());
|
||||
atInfoText.setTextColor(Color.RED);
|
||||
}
|
||||
|
||||
V2TIMMessage lastMessage = conversation.getLastMessage();
|
||||
if (lastMessage != null) {
|
||||
int status = lastMessage.getStatus();
|
||||
if (status == V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.VISIBLE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else if (status == V2TIMMessage.V2TIM_MSG_STATUS_SENDING) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
conversationIconView.setRadius(mAdapter.getItemAvatarRadius());
|
||||
if (mAdapter.getItemDateTextSize() != 0) {
|
||||
timelineText.setTextSize(mAdapter.getItemDateTextSize());
|
||||
}
|
||||
if (mAdapter.getItemBottomTextSize() != 0) {
|
||||
messageText.setTextSize(mAdapter.getItemBottomTextSize());
|
||||
}
|
||||
if (mAdapter.getItemTopTextSize() != 0) {
|
||||
titleText.setTextSize(mAdapter.getItemTopTextSize());
|
||||
}
|
||||
if (!mAdapter.hasItemUnreadDot()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
conversationIconView.setShowFoldedStyle(showFoldedStyle);
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
if (conversation.isShowDisturbIcon() && !isForwardMode) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
} else {
|
||||
disturbView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (isForwardMode) {
|
||||
messageText.setVisibility(View.GONE);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.GONE);
|
||||
atInfoText.setVisibility(View.GONE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (!conversation.isGroup() && TUIConversationConfig.getInstance().isShowUserStatus()) {
|
||||
if (conversation.getStatusType() == V2TIMUserStatus.V2TIM_USER_STATUS_ONLINE) {
|
||||
userStatusView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
|
||||
public class ConversationCustomHolder extends ConversationBaseHolder {
|
||||
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected TextView unreadText;
|
||||
protected ConversationIconView conversationIconView;
|
||||
|
||||
|
||||
public ConversationCustomHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
if (conversation.isTop()) {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
titleText.setText(conversation.getTitle());
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
|
||||
if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (mAdapter.getItemDateTextSize() != 0) {
|
||||
timelineText.setTextSize(mAdapter.getItemDateTextSize());
|
||||
}
|
||||
if (mAdapter.getItemBottomTextSize() != 0) {
|
||||
messageText.setTextSize(mAdapter.getItemBottomTextSize());
|
||||
}
|
||||
if (mAdapter.getItemTopTextSize() != 0) {
|
||||
titleText.setTextSize(mAdapter.getItemTopTextSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.component.gatherimage.SynthesizedImageView;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuicore.util.BackgroundTasks;
|
||||
import com.tencent.qcloud.tuicore.util.ImageUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ThreadHelper;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationIconPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会话列表头像View
|
||||
*/
|
||||
public class ConversationIconView extends RelativeLayout {
|
||||
|
||||
private ImageView mIconView;
|
||||
private boolean showFoldedStyle = false;
|
||||
|
||||
private ConversationIconPresenter presenter;
|
||||
|
||||
public ConversationIconView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), com.tencent.qcloud.tuicore.R.layout.profile_icon_view, this);
|
||||
mIconView = findViewById(com.tencent.qcloud.tuicore.R.id.profile_icon);
|
||||
((SynthesizedImageView) mIconView).defaultImage(TUIConfig.getDefaultAvatarImage());
|
||||
presenter = new ConversationIconPresenter();
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置会话头像的url
|
||||
*
|
||||
* @param iconUrls 头像url,最多只取前9个
|
||||
*/
|
||||
public void setIconUrls(final List<Object> iconUrls, final String conversationId) {
|
||||
// 需要在主线程中执行,以免写缓存出现问题
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).displayImage(iconUrls).load(conversationId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversation(ConversationInfo conversationInfo) {
|
||||
if (showFoldedStyle && conversationInfo.isMarkFold()) {
|
||||
mIconView.setImageResource(R.drawable.ic_fold);
|
||||
} else if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setImageId(conversationInfo.getConversationId());
|
||||
if (conversationInfo.isGroup()) {
|
||||
fillConversationUrlForGroup(conversationInfo);
|
||||
} else {
|
||||
setIconUrls(conversationInfo.getIconUrlList(), conversationInfo.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillConversationUrlForGroup(final ConversationInfo info) {
|
||||
List<Object> iconUrlList = info.getIconUrlList();
|
||||
if (iconUrlList == null || iconUrlList.size() == 0) {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar()) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
return;
|
||||
}
|
||||
// 读取文件,在线程池中进行,避免主线程卡顿
|
||||
ThreadHelper.INST.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String savedIcon = ImageUtil.getGroupConversationAvatar(info.getConversationId());
|
||||
if (TextUtils.isEmpty(savedIcon)) {
|
||||
fillFaceUrlList(info.getId(), info);
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(savedIcon);
|
||||
info.setIconUrlList(list);
|
||||
setIconUrls(list, info.getConversationId());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar() && iconUrlList.size() > 1) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
} else {
|
||||
setIconUrls(iconUrlList, info.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFaceUrlList(final String groupID, final ConversationInfo info) {
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearImage();
|
||||
presenter.getGroupMemberIconList(groupID, new IUIKitCallback<List<Object>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Object> data) {
|
||||
info.setIconUrlList(data);
|
||||
setIconUrls(data, info.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setRadius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
mIconView.setImageBitmap(bd.getBitmap());
|
||||
}
|
||||
|
||||
public void setBitmapResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
Bitmap bitmap = ImageUtil.toRoundBitmap(bd.getBitmap());
|
||||
mIconView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
public void clearImage() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) mIconView).clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page.ConversationMinimalistFragment;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.setting.ConversationLayoutSetting;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.Attributes;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
|
||||
private ConversationListLayout mConversationList;
|
||||
private ViewGroup searchLayout;
|
||||
private ConversationPresenter presenter;
|
||||
private ImageView conversationEditView, createChatView;
|
||||
private TextView conversationEditDoneView;
|
||||
private ConversationMinimalistFragment.OnClickListener mClickListener = null;
|
||||
private boolean isMultiSelected = false;
|
||||
private List<ConversationInfo> mSelectConversations = new ArrayList<>();
|
||||
|
||||
public ConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (mConversationList != null) {
|
||||
mConversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化相关UI元素
|
||||
*/
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalistui_conversation_layout, this);
|
||||
mConversationList = findViewById(R.id.conversation_list);
|
||||
searchLayout = findViewById(R.id.search_layout);
|
||||
conversationEditView = findViewById(R.id.edit_button);
|
||||
createChatView = findViewById(R.id.create_new_button);
|
||||
conversationEditDoneView = findViewById(R.id.edit_done);
|
||||
mSelectConversations.clear();
|
||||
conversationEditView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onEditConversationStartClick();
|
||||
}
|
||||
conversationEditView.setVisibility(GONE);
|
||||
conversationEditDoneView.setVisibility(VISIBLE);
|
||||
createChatView.setVisibility(GONE);
|
||||
|
||||
conversationMutiSelectStart();
|
||||
}
|
||||
});
|
||||
createChatView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onStartChatClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
conversationEditDoneView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onEditConversationEndClick();
|
||||
}
|
||||
conversationEditView.setVisibility(VISIBLE);
|
||||
conversationEditDoneView.setVisibility(GONE);
|
||||
createChatView.setVisibility(VISIBLE);
|
||||
|
||||
conversationMutiSelectEnd();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ImageView getCreateChatView() {
|
||||
return createChatView;
|
||||
}
|
||||
|
||||
public void resetTitileBar() {
|
||||
conversationEditView.setVisibility(VISIBLE);
|
||||
conversationEditDoneView.setVisibility(GONE);
|
||||
createChatView.setVisibility(VISIBLE);
|
||||
conversationMutiSelectEnd();
|
||||
}
|
||||
|
||||
public void setOnClickListener(ConversationMinimalistFragment.OnClickListener listener) {
|
||||
mClickListener = listener;
|
||||
}
|
||||
public boolean isMultiSelected() {
|
||||
return isMultiSelected;
|
||||
}
|
||||
|
||||
private void conversationMutiSelectStart() {
|
||||
ConversationListAdapter adapter = mConversationList.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.setShowMultiSelectCheckBox(true);
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.closeAllSwipeItems();
|
||||
adapter.switchAllSwipeEnable(false);
|
||||
}
|
||||
isMultiSelected = true;
|
||||
mSelectConversations.clear();
|
||||
}
|
||||
|
||||
private void conversationMutiSelectEnd() {
|
||||
ConversationListAdapter adapter = mConversationList.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.setShowMultiSelectCheckBox(false);
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.closeAllSwipeItems();
|
||||
adapter.switchAllSwipeEnable(true);
|
||||
}
|
||||
isMultiSelected = false;
|
||||
mSelectConversations.clear();
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
if (presenter != null) {
|
||||
initSearchView(adapter);
|
||||
adapter.setShowFoldedStyle(true);
|
||||
}
|
||||
|
||||
mConversationList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
adapter.setMode(Attributes.Mode.Single);
|
||||
mConversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
ConversationLayoutSetting.customizeConversation(this);
|
||||
mConversationList.loadConversation(0);
|
||||
}
|
||||
|
||||
public void initSearchView(ConversationListAdapter adapter) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONTEXT, getContext());
|
||||
Map<String, Object> searchExtension = TUICore.getExtensionInfo(TUIConstants.TUIConversation.EXTENSION_MINIMALIST_SEARCH, param);
|
||||
if (searchExtension != null) {
|
||||
searchLayout.setVisibility(VISIBLE);
|
||||
if (searchLayout.getChildCount() == 0) {
|
||||
View searchView = (View) searchExtension.get(TUIConstants.TUIConversation.SEARCH_VIEW);
|
||||
searchLayout.addView(searchView);
|
||||
}
|
||||
} else {
|
||||
searchLayout.removeAllViews();
|
||||
searchLayout.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return mConversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
if (presenter != null) {
|
||||
presenter.setConversationTop(conversation, callBack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.clearConversationMessage(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
if (presenter != null) {
|
||||
presenter.hideFoldItem(needHide);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
if (presenter != null) {
|
||||
presenter.setUnreadStatusOfFoldItem(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,654 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.RecyclerSwipeAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SimpleSwipeListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationListAdapter extends RecyclerSwipeAdapter<RecyclerView.ViewHolder> implements IConversationListAdapter {
|
||||
|
||||
public static final int ITEM_TYPE_HEADER_HIDE = 101;
|
||||
public static final int ITEM_TYPE_FOOTER_LOADING = -99;
|
||||
public static final int HEADER_COUNT = 1;
|
||||
public static final int FOOTER_COUNT = 1;
|
||||
public static final int SELECT_COUNT = 1;
|
||||
public static final int SELECT_LABEL_COUNT = 1;
|
||||
|
||||
private boolean mHasShowUnreadDot = true;
|
||||
private int mItemAvatarRadius = ScreenUtil.getPxByDp(5);
|
||||
private int mTopTextSize;
|
||||
private int mBottomTextSize;
|
||||
private int mDateTextSize;
|
||||
protected List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private OnConversationAdapterListener mOnConversationAdapterListener;
|
||||
|
||||
//消息转发
|
||||
private final HashMap<String, Boolean> mSelectedPositions = new HashMap<>();
|
||||
private boolean isShowMultiSelectCheckBox = false;
|
||||
private boolean isForwardFragment = false;
|
||||
|
||||
private boolean mIsLoading = false;
|
||||
|
||||
// 长按高亮显示
|
||||
private boolean isClick = false;
|
||||
private int currentPosition = -1;
|
||||
|
||||
private View hideView;
|
||||
// 展示折叠样式
|
||||
private boolean showFoldedStyle = true;
|
||||
public ConversationListAdapter() {
|
||||
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public boolean isClick() {
|
||||
return isClick;
|
||||
}
|
||||
|
||||
public void setClick(boolean click) {
|
||||
isClick = click;
|
||||
}
|
||||
|
||||
public void setCurrentPosition(int currentPosition , boolean isClick) {
|
||||
this.currentPosition = currentPosition;
|
||||
this.isClick = isClick;
|
||||
}
|
||||
|
||||
public void setShowMultiSelectCheckBox(boolean show) {
|
||||
isShowMultiSelectCheckBox = show;
|
||||
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
mSelectedPositions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForwardFragment(boolean forwardFragment) {
|
||||
isForwardFragment = forwardFragment;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
//设置给定位置条目的选择状态
|
||||
public void setItemChecked(String conversationId, boolean isChecked) {
|
||||
mSelectedPositions.put(conversationId, isChecked);
|
||||
}
|
||||
|
||||
//根据位置判断条目是否选中
|
||||
private boolean isItemChecked(String id) {
|
||||
if (mSelectedPositions.size() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSelectedPositions.containsKey(id)) {
|
||||
return mSelectedPositions.get(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获得选中条目的结果
|
||||
public List<ConversationInfo> getSelectedItem() {
|
||||
if (mSelectedPositions.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
List<ConversationInfo> selectList = new ArrayList<>();
|
||||
for (int i = 0; i < getItemCount() - 1; i++) {
|
||||
ConversationInfo conversationInfo = getItem(i);
|
||||
if (conversationInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if (isItemChecked(conversationInfo.getConversationId())) {
|
||||
selectList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
return selectList;
|
||||
}
|
||||
|
||||
public void setSelectConversations(List<ConversationInfo> dataSource){
|
||||
if(dataSource == null || dataSource.size() == 0){
|
||||
mSelectedPositions.clear();
|
||||
notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
mSelectedPositions.clear();
|
||||
for (int i = 0; i < dataSource.size(); i++) {
|
||||
for (int j =0; j<mDataSource.size(); j++){
|
||||
if (TextUtils.equals(dataSource.get(i).getConversationId(), mDataSource.get(j).getConversationId())){
|
||||
setItemChecked(mDataSource.get(j).getConversationId(), true);
|
||||
notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
this.mOnConversationAdapterListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataSourceChanged(List<ConversationInfo> dataSource) {
|
||||
this.mDataSource = dataSource;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
ConversationBaseHolder holder = null;
|
||||
// 创建不同的 ViewHolder
|
||||
View view;
|
||||
// 根据ViewType来创建条目
|
||||
if (viewType == ITEM_TYPE_HEADER_HIDE) {
|
||||
// 如果 searchView 不显示,添加一个隐藏的 view,防止 recyclerview 自动滑到最底部
|
||||
return new HeaderViewHolder(new View(parent.getContext()));
|
||||
} else if (viewType == ConversationInfo.TYPE_CUSTOM) {
|
||||
view = inflater.inflate(R.layout.conversation_custom_adapter, parent, false);
|
||||
holder = new ConversationCustomHolder(view);
|
||||
} else if (viewType == ITEM_TYPE_FOOTER_LOADING) {
|
||||
view = inflater.inflate(R.layout.loading_progress_bar, parent, false);
|
||||
return new FooterViewHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_select_adapter, parent, false);
|
||||
return new ForwardSelectHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_RECENT_LABEL) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_label_adapter, parent, false);
|
||||
return new ForwardLabelHolder(view);
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.minimalistui_conversation_list_item_layout, parent, false);
|
||||
holder = new ConversationCommonHolder(view);
|
||||
((ConversationCommonHolder) holder).setForwardMode(isForwardFragment);
|
||||
((ConversationCommonHolder) holder).setShowFoldedStyle(showFoldedStyle);
|
||||
}
|
||||
holder.setAdapter(this);
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
final ConversationInfo conversationInfo = getItem(position);
|
||||
ConversationBaseHolder baseHolder = null;
|
||||
if (conversationInfo != null) {
|
||||
baseHolder = (ConversationBaseHolder) holder;
|
||||
}
|
||||
|
||||
switch (getItemViewType(position)) {
|
||||
case ConversationInfo.TYPE_CUSTOM:
|
||||
case ConversationInfo.TYPE_RECENT_LABEL:
|
||||
break;
|
||||
case ITEM_TYPE_FOOTER_LOADING: {
|
||||
if (holder instanceof FooterViewHolder) {
|
||||
((ConversationBaseHolder) holder).layoutViews(null, position);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConversationInfo.TYPE_FORWAR_SELECT : {
|
||||
ForwardSelectHolder selectHolder = (ForwardSelectHolder) holder;
|
||||
selectHolder.refreshTitle(!isShowMultiSelectCheckBox);
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (baseHolder instanceof ConversationCommonHolder) {
|
||||
ConversationCommonHolder viewHolder = (ConversationCommonHolder) baseHolder;
|
||||
viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
viewHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
|
||||
@Override
|
||||
public void onDoubleClick(SwipeLayout layout, boolean surface) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(viewHolder.itemView, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.markReadView.setVisibility(View.GONE);
|
||||
viewHolder.moreView.setVisibility(View.GONE);
|
||||
viewHolder.notDisplayView.setVisibility(View.VISIBLE);
|
||||
viewHolder.notDisplayView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mItemManger.removeShownLayouts(viewHolder.swipeLayout);
|
||||
mOnConversationAdapterListener.onMarkConversationHidden(view, conversationInfo);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
mItemManger.bind(viewHolder.itemView, position);
|
||||
} else {
|
||||
viewHolder.notDisplayView.setVisibility(View.GONE);
|
||||
viewHolder.markReadView.setVisibility(View.VISIBLE);
|
||||
viewHolder.moreView.setVisibility(View.VISIBLE);
|
||||
viewHolder.swipeLayout.addSwipeListener(new SimpleSwipeListener() {
|
||||
@Override
|
||||
public void onOpen(SwipeLayout layout) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onSwipeConversationChanged(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(SwipeLayout layout) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onSwipeConversationChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartOpen(SwipeLayout layout) {
|
||||
int unReadNum = conversationInfo.getUnRead();
|
||||
boolean isMarkUnread = conversationInfo.isMarkUnread();
|
||||
if (unReadNum > 0) {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_read);
|
||||
viewHolder.markReadView.setBackgroundColor(viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_all_read);
|
||||
} else {
|
||||
if (isMarkUnread) {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_read);
|
||||
viewHolder.markReadView.setBackgroundColor(viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_all_read);
|
||||
} else {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_unread);
|
||||
viewHolder.markReadView.setBackgroundColor(viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_dark_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_no_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
viewHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
|
||||
@Override
|
||||
public void onDoubleClick(SwipeLayout layout, boolean surface) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(viewHolder.itemView, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.markReadView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
boolean markRead = TUIConversationService.getAppContext().getString(R.string.mark_read).equals(viewHolder.markReadTextView.getText());
|
||||
mOnConversationAdapterListener.onMarkConversationUnread(view, conversationInfo, !markRead);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.moreView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onClickMoreView(view, conversationInfo);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
|
||||
mItemManger.bind(viewHolder.itemView, position);
|
||||
}
|
||||
} else {
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (baseHolder != null) {
|
||||
baseHolder.layoutViews(conversationInfo, position);
|
||||
setCheckBoxStatus(conversationInfo, position, baseHolder);
|
||||
}
|
||||
|
||||
if (getCurrentPosition() == position && isClick()){
|
||||
baseHolder.itemView.setBackgroundResource(R.color.conversation_item_clicked_color);
|
||||
} else {
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (conversationInfo.isTop() && !isForwardFragment) {
|
||||
baseHolder.itemView.setBackgroundColor(baseHolder.rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
baseHolder.itemView.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setOnClickListener(RecyclerView.ViewHolder holder, int viewType, ConversationInfo conversationInfo) {
|
||||
if (holder instanceof HeaderViewHolder) {
|
||||
return;
|
||||
}
|
||||
//设置点击和长按事件
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mOnConversationAdapterListener.onItemClick(view, viewType, conversationInfo);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
mOnConversationAdapterListener.OnItemLongClick(view, conversationInfo);
|
||||
int position = getIndexInAdapter(conversationInfo);
|
||||
if (position != -1) {
|
||||
setCurrentPosition(position, true);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 设置多选框的选中状态和点击事件
|
||||
private void setCheckBoxStatus(final ConversationInfo conversationInfo, int position, ConversationBaseHolder baseHolder) {
|
||||
if (!(baseHolder instanceof ConversationCommonHolder) || ((ConversationCommonHolder) baseHolder).multiSelectCheckBox == null) {
|
||||
return;
|
||||
}
|
||||
int viewType = getItemViewType(position);
|
||||
String conversationId = conversationInfo.getConversationId();
|
||||
ConversationCommonHolder commonHolder = (ConversationCommonHolder) baseHolder;
|
||||
if (!isShowMultiSelectCheckBox || conversationInfo.isMarkFold()) {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.GONE);
|
||||
baseHolder.itemView.setOnClickListener(null);
|
||||
} else {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.VISIBLE);
|
||||
|
||||
//设置条目状态
|
||||
commonHolder.multiSelectCheckBox.setChecked(isItemChecked(conversationId));
|
||||
//checkBox的监听
|
||||
commonHolder.multiSelectCheckBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//条目view的监听
|
||||
baseHolder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
int currentPosition = getIndexInAdapter(conversationInfo);
|
||||
if (currentPosition != -1) {
|
||||
notifyItemChanged(currentPosition);
|
||||
}
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndexInAdapter(ConversationInfo conversationInfo) {
|
||||
int position = -1;
|
||||
if (mDataSource != null) {
|
||||
int indexInData = mDataSource.indexOf(conversationInfo);
|
||||
if (indexInData != -1) {
|
||||
position = getItemIndexInAdapter(indexInData);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
|
||||
// ViewHolder 被回收时要清空头像 view 并且停止异步加载头像
|
||||
if (holder instanceof ConversationCommonHolder) {
|
||||
((ConversationCommonHolder) holder).conversationIconView.clearImage();
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationInfo getItem(int position) {
|
||||
if (mDataSource.isEmpty() || position == getItemCount() - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int dataPosition;
|
||||
if (isForwardFragment) {
|
||||
dataPosition = position - SELECT_COUNT - SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
dataPosition = position - HEADER_COUNT;
|
||||
}
|
||||
if (dataPosition < mDataSource.size() && dataPosition >= 0) {
|
||||
return mDataSource.get(dataPosition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int listSize = mDataSource.size();
|
||||
if (isForwardFragment) {
|
||||
return listSize + SELECT_COUNT + SELECT_LABEL_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
return listSize + HEADER_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (isForwardFragment) {
|
||||
if (position == 0) {
|
||||
return ConversationInfo.TYPE_FORWAR_SELECT;
|
||||
} else if (position == 1) {
|
||||
return ConversationInfo.TYPE_RECENT_LABEL;
|
||||
}
|
||||
} else {
|
||||
if (position == 0) {
|
||||
return ITEM_TYPE_HEADER_HIDE;
|
||||
}
|
||||
}
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_TYPE_FOOTER_LOADING;
|
||||
} else if (mDataSource != null) {
|
||||
ConversationInfo conversationInfo = getItem(position);
|
||||
if (conversationInfo != null) {
|
||||
return conversationInfo.getType();
|
||||
}
|
||||
}
|
||||
return ConversationInfo.TYPE_COMMON;
|
||||
}
|
||||
|
||||
private int getItemIndexInAdapter(int index) {
|
||||
int itemIndex;
|
||||
if (isForwardFragment) {
|
||||
itemIndex = index + SELECT_LABEL_COUNT + SELECT_COUNT;
|
||||
} else {
|
||||
itemIndex = index + HEADER_COUNT;
|
||||
}
|
||||
return itemIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRemoved(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemRemoved(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemInserted(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemInserted(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemChanged(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemChanged(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int startPosition, int count) {
|
||||
int itemStartIndex = getItemIndexInAdapter(startPosition);
|
||||
notifyItemRangeChanged(itemStartIndex, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
public void setItemTopTextSize(int size) {
|
||||
mTopTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemTopTextSize() {
|
||||
return mTopTextSize;
|
||||
}
|
||||
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mBottomTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemBottomTextSize() {
|
||||
return mBottomTextSize;
|
||||
}
|
||||
|
||||
public void setItemDateTextSize(int size) {
|
||||
mDateTextSize = size;
|
||||
}
|
||||
|
||||
public int getItemDateTextSize() {
|
||||
return mDateTextSize;
|
||||
}
|
||||
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mItemAvatarRadius = radius;
|
||||
}
|
||||
|
||||
public int getItemAvatarRadius() {
|
||||
return mItemAvatarRadius;
|
||||
}
|
||||
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mHasShowUnreadDot = !flag;
|
||||
}
|
||||
|
||||
public boolean hasItemUnreadDot() {
|
||||
return mHasShowUnreadDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChanged(boolean isLoading) {
|
||||
this.mIsLoading = isLoading;
|
||||
notifyItemChanged(getItemCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewNeedRefresh() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwipeLayoutResourceId(int position) {
|
||||
return R.id.swipe;
|
||||
}
|
||||
|
||||
//header
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
public HeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
//footer
|
||||
class FooterViewHolder extends ConversationBaseHolder {
|
||||
public FooterViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) rootView.getLayoutParams();
|
||||
if (mIsLoading) {
|
||||
param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
|
||||
param.width = LinearLayout.LayoutParams.MATCH_PARENT;
|
||||
rootView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
param.height = 0;
|
||||
param.width = 0;
|
||||
rootView.setVisibility(View.GONE);
|
||||
}
|
||||
rootView.setLayoutParams(param);
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardLabelHolder extends ConversationBaseHolder {
|
||||
public ForwardLabelHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardSelectHolder extends ConversationBaseHolder {
|
||||
private final TextView titleView;
|
||||
public ForwardSelectHolder(View itemView) {
|
||||
super(itemView);
|
||||
titleView = itemView.findViewById(R.id.forward_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
|
||||
}
|
||||
|
||||
public void refreshTitle(boolean isCreateGroup){
|
||||
if (titleView == null)return;
|
||||
|
||||
if (isCreateGroup){
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_new_chat));
|
||||
} else {
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_from_contact));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public ConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mAdapter.setItemAvatarRadius(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemTopTextSize(int size) {
|
||||
mAdapter.setItemTopTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mAdapter.setItemBottomTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemDateTextSize(int size) {
|
||||
mAdapter.setItemDateTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener){
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(int state) {
|
||||
super.onScrollStateChanged(state);
|
||||
if (state == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (layoutManager == null) {
|
||||
return;
|
||||
}
|
||||
int lastPosition = layoutManager.findLastCompletelyVisibleItemPosition();
|
||||
|
||||
if (mAdapter != null) {
|
||||
if (lastPosition == mAdapter.getItemCount() - 1 && !isLoadCompleted()) {
|
||||
mAdapter.onLoadingStateChanged(true);
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadConversation(long nextSeq) {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation(nextSeq);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLoadCompleted(){
|
||||
if (presenter != null) {
|
||||
return presenter.isLoadFinished();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private FoldedConversationListLayout conversationListLayout;
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
public FoldedConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationListLayout != null) {
|
||||
conversationListLayout.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalist_folded_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationListLayout = findViewById(R.id.folded_conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
conversationListLayout.setAdapter((IConversationListAdapter) adapter);
|
||||
adapter.setShowFoldedStyle(false);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
conversationListLayout.loadConversation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getConversationList() {
|
||||
return conversationListLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationFoldPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public FoldedConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemAvatarRadius(int radius) {
|
||||
mAdapter.setItemAvatarRadius(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemTopTextSize(int size) {
|
||||
mAdapter.setItemTopTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemBottomTextSize(int size) {
|
||||
mAdapter.setItemBottomTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemDateTextSize(int size) {
|
||||
mAdapter.setItemDateTextSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ForwardConversationSelectorAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
|
||||
private Context context;
|
||||
private List<ConversationInfo> list;
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
|
||||
public ForwardConversationSelectorAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
super.onAttachedToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConversationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ConversationViewHolder(LayoutInflater.from(context).inflate(R.layout.minimalist_forward_conversation_selector_item, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
ConversationViewHolder viewHolder = (ConversationViewHolder) holder;
|
||||
viewHolder.conversationUserIconView.setVisibility(View.VISIBLE);
|
||||
viewHolder.conversationUserIconView.setConversation(list.get(position));
|
||||
|
||||
viewHolder.conversationUserIconView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mOnItemClickListener.onClick(v, position);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void setDataSource(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
if (list != null) {
|
||||
list.clear();
|
||||
}
|
||||
} else {
|
||||
list = dataSource;
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.mOnItemClickListener = listener;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(View view, int position);
|
||||
}
|
||||
|
||||
static class ConversationViewHolder extends RecyclerView.ViewHolder {
|
||||
public ConversationIconView conversationUserIconView;
|
||||
public ConversationViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
conversationUserIconView = itemView.findViewById(R.id.conversation_user_icon_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ForwardSelectLayout extends RelativeLayout implements IConversationLayout {
|
||||
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private ConversationListLayout conversationList;
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
public ForwardSelectLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationList != null) {
|
||||
conversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化相关UI元素
|
||||
*/
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalist_forward_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationList = findViewById(R.id.conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
adapter.setForwardFragment(true);
|
||||
conversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
presenter.setAdapter(adapter);
|
||||
presenter.loadConversation(0);
|
||||
}
|
||||
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return conversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markRead) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuicore.component.action.PopMenuAdapter;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Menu {
|
||||
|
||||
private static final int SHADOW_WIDTH = 10;
|
||||
private static final int Y_OFFSET = 4;
|
||||
|
||||
private ListView mMenuList;
|
||||
private PopMenuAdapter mMenuAdapter;
|
||||
private PopupWindow mMenuWindow;
|
||||
private List<PopMenuAction> mActions = new ArrayList<>();
|
||||
private Activity mActivity;
|
||||
private View mAttachView;
|
||||
|
||||
public Menu(Activity activity, View attach) {
|
||||
mActivity = activity;
|
||||
mAttachView = attach;
|
||||
}
|
||||
|
||||
public void setMenuAction(List<PopMenuAction> menuActions) {
|
||||
mActions.clear();
|
||||
mActions.addAll(menuActions);
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
if (mMenuWindow == null) {
|
||||
return false;
|
||||
}
|
||||
return mMenuWindow.isShowing();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
mMenuWindow.dismiss();
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (mActions == null || mActions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
mMenuWindow = new PopupWindow(mActivity);
|
||||
mMenuWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mMenuWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mMenuWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
|
||||
mMenuAdapter = new PopMenuAdapter();
|
||||
mMenuAdapter.setDataSource(mActions);
|
||||
View menuView = LayoutInflater.from(mActivity).inflate(R.layout.core_pop_menu, null);
|
||||
menuView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
mMenuWindow.setContentView(menuView);
|
||||
mMenuList = menuView.findViewById(R.id.menu_pop_list);
|
||||
mMenuList.setAdapter(mMenuAdapter);
|
||||
mMenuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = (PopMenuAction) mMenuAdapter.getItem(position);
|
||||
if (action != null && action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, mActions.get(position));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
int paddingLeftRight = ScreenUtil.dip2px(15.0f);
|
||||
int paddingTopBottom = ScreenUtil.dip2px(12.0f);
|
||||
|
||||
int itemWidth = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_width);
|
||||
int itemHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_height);
|
||||
float anchorWidth = mAttachView.getWidth();
|
||||
float anchorHeight = mAttachView.getHeight();
|
||||
|
||||
mMenuWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
int[] location = new int[2];
|
||||
mAttachView.getLocationOnScreen(location);
|
||||
int rowCount = mActions.size();
|
||||
int indicatorHeight = mActivity.getResources().getDimensionPixelOffset(R.dimen.core_pop_menu_indicator_height);
|
||||
|
||||
int popWidth = itemWidth + paddingLeftRight * 2 - SHADOW_WIDTH;
|
||||
int popHeight = itemHeight * rowCount + paddingTopBottom * 2 - SHADOW_WIDTH;
|
||||
|
||||
float indicatorX = anchorWidth / 2;
|
||||
int screenWidth = ScreenUtil.getScreenWidth(mActivity);
|
||||
int x = location[0];
|
||||
int y;
|
||||
float xOffset = anchorWidth / 2;
|
||||
// If it is on the right, the x-coordinate of the small arrow and the x-position of the pop-up window will change
|
||||
if (location[0] * 2 + anchorWidth > screenWidth) {
|
||||
indicatorX = popWidth - anchorWidth / 2 - xOffset;
|
||||
x = (int) (location[0] + anchorWidth - popWidth + xOffset);
|
||||
}
|
||||
|
||||
y = (int) (location[1] + anchorHeight) + Y_OFFSET;
|
||||
popHeight = popHeight - indicatorHeight;
|
||||
|
||||
Drawable backgroundDrawable = getBackgroundDrawable(popWidth, popHeight, indicatorX, indicatorHeight, 16);
|
||||
menuView.setBackground(backgroundDrawable);
|
||||
|
||||
mMenuWindow.setFocusable(true);
|
||||
mMenuWindow.setTouchable(true);
|
||||
mMenuWindow.setOutsideTouchable(true);
|
||||
mMenuWindow.showAtLocation(mAttachView, Gravity.NO_GRAVITY, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a popup background with small triangles
|
||||
*/
|
||||
public Drawable getBackgroundDrawable(final float widthPixel, final float heightPixel, float indicatorX, float indicatorHeight, float radius) {
|
||||
int borderWidth = SHADOW_WIDTH;
|
||||
|
||||
Path path = new Path();
|
||||
Drawable drawable = new Drawable() {
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setShadowLayer(borderWidth, 0,0,0xFFAAAAAA);
|
||||
path.addRoundRect(new RectF(borderWidth, indicatorHeight + borderWidth, widthPixel - borderWidth, heightPixel + indicatorHeight - borderWidth), radius, radius, Path.Direction.CW);
|
||||
path.moveTo(indicatorX - indicatorHeight, indicatorHeight + borderWidth);
|
||||
path.lineTo(indicatorX, borderWidth);
|
||||
path.lineTo(indicatorX + indicatorHeight, indicatorHeight + borderWidth);
|
||||
path.close();
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
};
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
|
||||
public class Attributes {
|
||||
|
||||
public enum Mode {
|
||||
Single, Multiple
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.Attributes;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeAdapterInterface;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeItemMangerImpl;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeItemMangerInterface;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeLayout;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class RecyclerSwipeAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements SwipeItemMangerInterface, SwipeAdapterInterface {
|
||||
|
||||
public SwipeItemMangerImpl mItemManger = new SwipeItemMangerImpl(this);
|
||||
|
||||
@Override
|
||||
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
|
||||
|
||||
@Override
|
||||
public abstract void onBindViewHolder(VH viewHolder, final int position);
|
||||
|
||||
@Override
|
||||
public void notifyDatasetChanged() {
|
||||
super.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openItem(int position) {
|
||||
mItemManger.openItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeItem(int position) {
|
||||
mItemManger.closeItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeAllExcept(SwipeLayout layout) {
|
||||
mItemManger.closeAllExcept(layout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeAllSwipeItems() {
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getOpenItems() {
|
||||
return mItemManger.getOpenItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwipeLayout> getOpenLayouts() {
|
||||
return mItemManger.getOpenLayouts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeShownLayouts(SwipeLayout layout) {
|
||||
mItemManger.removeShownLayouts(layout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen(int position) {
|
||||
return mItemManger.isOpen(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attributes.Mode getMode() {
|
||||
return mItemManger.getMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMode(Attributes.Mode mode) {
|
||||
mItemManger.setMode(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchAllSwipeEnable(boolean enable) {
|
||||
mItemManger.switchAllSwipeEnable(enable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
public class SimpleSwipeListener implements SwipeLayout.SwipeListener {
|
||||
|
||||
@Override
|
||||
public void onStartOpen(SwipeLayout layout) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(SwipeLayout layout) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartClose(SwipeLayout layout) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(SwipeLayout layout) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
public interface SwipeAdapterInterface {
|
||||
|
||||
int getSwipeLayoutResourceId(int position);
|
||||
|
||||
void notifyDatasetChanged();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SwipeItemMangerImpl implements SwipeItemMangerInterface {
|
||||
|
||||
private Attributes.Mode mode = Attributes.Mode.Single;
|
||||
public final int INVALID_POSITION = -1;
|
||||
|
||||
protected int mOpenPosition = INVALID_POSITION;
|
||||
|
||||
protected Set<Integer> mOpenPositions = new HashSet<Integer>();
|
||||
protected Set<SwipeLayout> mShownLayouts = new HashSet<SwipeLayout>();
|
||||
|
||||
protected SwipeAdapterInterface swipeAdapterInterface;
|
||||
|
||||
public SwipeItemMangerImpl(SwipeAdapterInterface swipeAdapterInterface) {
|
||||
if (swipeAdapterInterface == null)
|
||||
throw new IllegalArgumentException("SwipeAdapterInterface can not be null");
|
||||
|
||||
this.swipeAdapterInterface = swipeAdapterInterface;
|
||||
}
|
||||
|
||||
public Attributes.Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void setMode(Attributes.Mode mode) {
|
||||
this.mode = mode;
|
||||
mOpenPositions.clear();
|
||||
mShownLayouts.clear();
|
||||
mOpenPosition = INVALID_POSITION;
|
||||
}
|
||||
|
||||
public void bind(View view, int position) {
|
||||
int resId = swipeAdapterInterface.getSwipeLayoutResourceId(position);
|
||||
SwipeLayout swipeLayout = (SwipeLayout) view.findViewById(resId);
|
||||
if (swipeLayout == null)
|
||||
throw new IllegalStateException("can not find SwipeLayout in target view");
|
||||
|
||||
if (swipeLayout.getTag(resId) == null) {
|
||||
OnLayoutListener onLayoutListener = new OnLayoutListener(position);
|
||||
SwipeMemory swipeMemory = new SwipeMemory(position);
|
||||
swipeLayout.addSwipeListener(swipeMemory);
|
||||
swipeLayout.addOnLayoutListener(onLayoutListener);
|
||||
swipeLayout.setTag(resId, new ValueBox(position, swipeMemory, onLayoutListener));
|
||||
mShownLayouts.add(swipeLayout);
|
||||
} else {
|
||||
ValueBox valueBox = (ValueBox) swipeLayout.getTag(resId);
|
||||
valueBox.swipeMemory.setPosition(position);
|
||||
valueBox.onLayoutListener.setPosition(position);
|
||||
valueBox.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openItem(int position) {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
if (!mOpenPositions.contains(position))
|
||||
mOpenPositions.add(position);
|
||||
} else {
|
||||
mOpenPosition = position;
|
||||
}
|
||||
swipeAdapterInterface.notifyDatasetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeItem(int position) {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
mOpenPositions.remove(position);
|
||||
} else {
|
||||
if (mOpenPosition == position)
|
||||
mOpenPosition = INVALID_POSITION;
|
||||
}
|
||||
swipeAdapterInterface.notifyDatasetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeAllExcept(SwipeLayout layout) {
|
||||
for (SwipeLayout s : mShownLayouts) {
|
||||
if (s != layout)
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeAllSwipeItems() {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
mOpenPositions.clear();
|
||||
} else {
|
||||
mOpenPosition = INVALID_POSITION;
|
||||
}
|
||||
for (SwipeLayout s : mShownLayouts) {
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchAllSwipeEnable(boolean enable) {
|
||||
for (SwipeLayout s : mShownLayouts) {
|
||||
s.setSwipeEnabled(enable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeShownLayouts(SwipeLayout layout) {
|
||||
mShownLayouts.remove(layout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getOpenItems() {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
return new ArrayList<Integer>(mOpenPositions);
|
||||
} else {
|
||||
return Collections.singletonList(mOpenPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwipeLayout> getOpenLayouts() {
|
||||
return new ArrayList<SwipeLayout>(mShownLayouts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen(int position) {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
return mOpenPositions.contains(position);
|
||||
} else {
|
||||
return mOpenPosition == position;
|
||||
}
|
||||
}
|
||||
|
||||
class ValueBox {
|
||||
OnLayoutListener onLayoutListener;
|
||||
SwipeMemory swipeMemory;
|
||||
int position;
|
||||
|
||||
ValueBox(int position, SwipeMemory swipeMemory, OnLayoutListener onLayoutListener) {
|
||||
this.swipeMemory = swipeMemory;
|
||||
this.onLayoutListener = onLayoutListener;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
class OnLayoutListener implements SwipeLayout.OnLayout {
|
||||
|
||||
private int position;
|
||||
|
||||
OnLayoutListener(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayout(SwipeLayout v) {
|
||||
if (isOpen(position)) {
|
||||
v.open(false, false);
|
||||
} else {
|
||||
v.close(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SwipeMemory extends SimpleSwipeListener {
|
||||
|
||||
private int position;
|
||||
|
||||
SwipeMemory(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(SwipeLayout layout) {
|
||||
if (mode == Attributes.Mode.Multiple) {
|
||||
mOpenPositions.remove(position);
|
||||
} else {
|
||||
mOpenPosition = INVALID_POSITION;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartOpen(SwipeLayout layout) {
|
||||
if (mode == Attributes.Mode.Single) {
|
||||
closeAllExcept(layout);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(SwipeLayout layout) {
|
||||
if (mode == Attributes.Mode.Multiple)
|
||||
mOpenPositions.add(position);
|
||||
else {
|
||||
closeAllExcept(layout);
|
||||
mOpenPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SwipeItemMangerInterface {
|
||||
|
||||
void openItem(int position);
|
||||
|
||||
void closeItem(int position);
|
||||
|
||||
void closeAllExcept(SwipeLayout layout);
|
||||
|
||||
void closeAllSwipeItems();
|
||||
|
||||
List<Integer> getOpenItems();
|
||||
|
||||
List<SwipeLayout> getOpenLayouts();
|
||||
|
||||
void removeShownLayouts(SwipeLayout layout);
|
||||
|
||||
boolean isOpen(int position);
|
||||
|
||||
Attributes.Mode getMode();
|
||||
|
||||
void setMode(Attributes.Mode mode);
|
||||
|
||||
void switchAllSwipeEnable(boolean enable);
|
||||
}
|
||||
@@ -0,0 +1,489 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.imsdk.BaseConstants;
|
||||
import com.tencent.imsdk.v2.V2TIMCallback;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationOperationResult;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationResult;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupMemberInfoResult;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback;
|
||||
import com.tencent.qcloud.tuicore.BuildConfig;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
|
||||
import com.tencent.qcloud.tuicore.util.ToastUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversationProvider {
|
||||
private static final String TAG = ConversationProvider.class.getSimpleName();
|
||||
|
||||
private boolean isFinished = false;
|
||||
private long nextLoadSeq = 0L;
|
||||
|
||||
private List<ConversationInfo> markConversationInfoList = new ArrayList<>();
|
||||
private HashMap<String, V2TIMConversation> markUnreadMap = new HashMap<>();
|
||||
|
||||
public void loadConversation(long startSeq, int loadCount, final IUIKitCallback<List<ConversationInfo>> callBack) {
|
||||
isFinished = false;
|
||||
nextLoadSeq = 0;
|
||||
V2TIMManager.getConversationManager().getConversationList(startSeq, loadCount, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.v(TAG, "loadConversation getConversationList error, code = " + code + ", desc = " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> v2TIMConversationList = v2TIMConversationResult.getConversationList();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(v2TIMConversationList);
|
||||
isFinished = v2TIMConversationResult.isFinished();
|
||||
nextLoadSeq = v2TIMConversationResult.getNextSeq();
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, conversationInfoList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadMoreConversation(int loadCount, IUIKitCallback<List<ConversationInfo>> callBack) {
|
||||
if (isFinished) {
|
||||
return;
|
||||
}
|
||||
loadConversation(nextLoadSeq, loadCount, callBack);
|
||||
}
|
||||
|
||||
public boolean isLoadFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public void getConversation(String conversationID, IUIKitCallback<ConversationInfo> callback) {
|
||||
V2TIMManager.getConversationManager().getConversation(conversationID, new V2TIMValueCallback<V2TIMConversation>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversation v2TIMConversation) {
|
||||
ConversationInfo conversationInfo = ConversationUtils.convertV2TIMConversation(v2TIMConversation);
|
||||
TUIConversationUtils.callbackOnSuccess(callback, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.v(TAG, "getConversation error, code = " + code + ", desc = " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getTotalUnreadMessageCount(IUIKitCallback<Long> callBack) {
|
||||
// 更新消息未读总数
|
||||
V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback<Long>() {
|
||||
@Override
|
||||
public void onSuccess(Long count) {
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversationTop(String conversationId, boolean isTop, IUIKitCallback<Void> callBack) {
|
||||
V2TIMManager.getConversationManager().pinConversation(conversationId, isTop, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationFold(String conversationID, boolean isFold, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
conversationIDList.add(conversationID);
|
||||
V2TIMManager.getConversationManager().markConversation(conversationIDList,
|
||||
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD, isFold,
|
||||
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationFold error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationHidden(String conversationID, boolean isHidden, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(conversationID)) {
|
||||
conversationIDList.add(conversationID);
|
||||
}
|
||||
V2TIMManager.getConversationManager().markConversation(conversationIDList,
|
||||
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE, isHidden, new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationHidden error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
conversationIDList.add(conversationInfo.getConversationId());
|
||||
}
|
||||
if (!markUnread && conversationInfo.getUnRead() > 0) {
|
||||
if (conversationInfo.isGroup()) {
|
||||
V2TIMManager.getMessageManager().markGroupMessageAsRead(conversationInfo.getId(), new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "markConversationUnread->markGroupMessageAsRead success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
V2TIMManager.getMessageManager().markC2CMessageAsRead(conversationInfo.getId(), new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "markConversationUnread->markC2CMessageAsRead success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (markUnread != conversationInfo.isMarkUnread()) {
|
||||
V2TIMManager.getConversationManager().markConversation(conversationIDList, V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD, markUnread, new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteConversation(String conversationId, IUIKitCallback<Void> callBack) {
|
||||
V2TIMManager.getConversationManager().deleteConversation(conversationId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "deleteConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "deleteConversation success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearHistoryMessage(String userId, boolean isGroup, IUIKitCallback<Void> callBack) {
|
||||
if (isGroup) {
|
||||
V2TIMManager.getMessageManager().clearGroupHistoryMessage(userId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "clearConversationMessage error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "clearConversationMessage success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
V2TIMManager.getMessageManager().clearC2CHistoryMessage(userId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "clearConversationMessage error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "clearConversationMessage success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void getGroupMemberIconList(String groupId, int iconCount, IUIKitCallback<List<Object>> callback) {
|
||||
V2TIMManager.getGroupManager().getGroupMemberList(groupId, V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_FILTER_ALL, 0, new V2TIMValueCallback<V2TIMGroupMemberInfoResult>() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
TUIConversationLog.e("ConversationIconView", "getGroupMemberList failed! groupID:" + groupId + "|code:" + code + "|desc: " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(V2TIMGroupMemberInfoResult v2TIMGroupMemberInfoResult) {
|
||||
List<V2TIMGroupMemberFullInfo> v2TIMGroupMemberFullInfoList = v2TIMGroupMemberInfoResult.getMemberInfoList();
|
||||
int faceSize = Math.min(v2TIMGroupMemberFullInfoList.size(), iconCount);
|
||||
final List<Object> urlList = new ArrayList<>();
|
||||
for (int i = 0; i < faceSize; i++) {
|
||||
V2TIMGroupMemberFullInfo v2TIMGroupMemberFullInfo = v2TIMGroupMemberFullInfoList.get(i);
|
||||
urlList.add(v2TIMGroupMemberFullInfo.getFaceUrl());
|
||||
}
|
||||
TUIConversationUtils.callbackOnSuccess(callback, urlList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadConversationUserStatus(List<ConversationInfo> dataSource, IUIKitCallback<Void> callback) {
|
||||
if (dataSource == null || dataSource.size() == 0) {
|
||||
TUIConversationLog.d(TAG, "loadConversationUserStatus datasource is null");
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap<String, ConversationInfo> dataSourceMap = new HashMap<>();
|
||||
List<String> userList = new ArrayList<>();
|
||||
for(ConversationInfo itemBean : dataSource) {
|
||||
if (itemBean.isGroup()) {
|
||||
continue;
|
||||
}
|
||||
userList.add(itemBean.getId());
|
||||
dataSourceMap.put(itemBean.getId(), itemBean);
|
||||
}
|
||||
if (userList.isEmpty()) {
|
||||
TUIConversationLog.d(TAG, "loadConversationUserStatus userList is empty");
|
||||
return;
|
||||
}
|
||||
V2TIMManager.getInstance().getUserStatus(userList, new V2TIMValueCallback<List<V2TIMUserStatus>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMUserStatus> v2TIMUserStatuses) {
|
||||
TUIConversationLog.i(TAG, "getUserStatus success");
|
||||
for (V2TIMUserStatus item : v2TIMUserStatuses) {
|
||||
ConversationInfo bean = dataSourceMap.get(item.getUserID());
|
||||
if (bean != null) {
|
||||
bean.setStatusType(item.getStatusType());
|
||||
}
|
||||
}
|
||||
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getUserStatus error code = " + code + ",des = " + desc);
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
if (code == TUIConstants.BuyingFeature.ERR_SDK_INTERFACE_NOT_SUPPORT &&
|
||||
TUIConversationConfig.getInstance().isShowUserStatus() && BuildConfig.DEBUG) {
|
||||
ToastUtil.toastLongMessage(desc);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void subscribeConversationUserStatus(List<String> userIdList, IUIKitCallback<Void> callback) {
|
||||
if (userIdList == null || userIdList.size() == 0) {
|
||||
TUIConversationLog.e(TAG, "subscribeConversationUserStatus userId is null");
|
||||
TUIConversationUtils.callbackOnError(callback, BaseConstants.ERR_INVALID_PARAMETERS, "userid list is null");
|
||||
return;
|
||||
}
|
||||
|
||||
V2TIMManager.getInstance().subscribeUserStatus(userIdList, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "subscribeConversationUserStatus error code = " + code + ",des = " + desc);
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getMarkConversationList(final V2TIMConversationListFilter filter, boolean fromStart, IUIKitCallback<List<ConversationInfo>> callback) {
|
||||
if (fromStart) {
|
||||
markConversationInfoList.clear();
|
||||
}
|
||||
V2TIMManager.getConversationManager().getConversationListByFilter(filter, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
markConversationInfoList.addAll(conversationInfoList);
|
||||
|
||||
if (!v2TIMConversationResult.isFinished()) {
|
||||
getMarkConversationList(filter, false, callback);
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(markConversationInfoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getMarkConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearAllUnreadMessage(IUIKitCallback<Void> callback) {
|
||||
V2TIMManager.getMessageManager().markAllMessageAsRead(new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "markAllMessageAsRead success");
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.i(TAG, "markAllMessageAsRead error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
|
||||
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
|
||||
filter.setCount(100);
|
||||
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD);
|
||||
filter.setNextSeq(0);
|
||||
getMarkUnreadConversationList(filter, true, new V2TIMValueCallback<HashMap<String, V2TIMConversation>>() {
|
||||
@Override
|
||||
public void onSuccess(HashMap<String, V2TIMConversation> stringV2TIMConversationHashMap) {
|
||||
if (stringV2TIMConversationHashMap.size() == 0) {
|
||||
return;
|
||||
}
|
||||
List<String> unreadConversationIDList = new ArrayList<>();
|
||||
Iterator<Map.Entry<String, V2TIMConversation>> iterator = markUnreadMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, V2TIMConversation> entry = iterator.next();
|
||||
unreadConversationIDList.add(entry.getKey());
|
||||
}
|
||||
|
||||
V2TIMManager.getConversationManager().markConversation(unreadConversationIDList,
|
||||
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD,
|
||||
false,
|
||||
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
for (V2TIMConversationOperationResult result : v2TIMConversationOperationResults) {
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
V2TIMConversation v2TIMConversation = markUnreadMap.get(result.getConversationID());
|
||||
if (!v2TIMConversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
|
||||
markUnreadMap.remove(result.getConversationID());
|
||||
}
|
||||
}
|
||||
}
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "triggerClearAllUnreadMessage->markConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "triggerClearAllUnreadMessage->getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getMarkUnreadConversationList(V2TIMConversationListFilter filter, boolean fromStart, V2TIMValueCallback<HashMap<String, V2TIMConversation>> callback) {
|
||||
if (fromStart) {
|
||||
markUnreadMap.clear();
|
||||
}
|
||||
V2TIMManager.getConversationManager().getConversationListByFilter(filter, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
|
||||
for (V2TIMConversation conversation : conversationList) {
|
||||
markUnreadMap.put(conversation.getConversationID(), conversation);
|
||||
}
|
||||
|
||||
if (!v2TIMConversationResult.isFinished()) {
|
||||
getMarkUnreadConversationList(filter, false, callback);
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(markUnreadMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.presenter;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationEventListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.model.ConversationProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationFoldPresenter {
|
||||
private static final String TAG = ConversationFoldPresenter.class.getSimpleName();
|
||||
|
||||
private final static int GET_CONVERSATION_COUNT = 100;
|
||||
|
||||
ConversationEventListener conversationEventForMarkObserver;
|
||||
|
||||
private final ConversationProvider provider;
|
||||
|
||||
private IConversationListAdapter adapter;
|
||||
|
||||
private final List<ConversationInfo> loadedConversationInfoList = new ArrayList<>();
|
||||
|
||||
public ConversationFoldPresenter() {
|
||||
provider = new ConversationProvider();
|
||||
}
|
||||
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
public void initListener() {
|
||||
conversationEventForMarkObserver = new ConversationEventListener() {
|
||||
@Override
|
||||
public void deleteConversation(String chatId, boolean isGroup) {
|
||||
ConversationFoldPresenter.this.deleteConversationFromUI(chatId, isGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(String chatId, boolean isGroup) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFoldMarkAndDeleteConversation(String conversationId) {
|
||||
ConversationFoldPresenter.this.deleteConversationFromUI(conversationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(String chatId, boolean isChecked, IUIKitCallback<Void> iuiKitCallBack) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTopConversation(String chatId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUnreadTotal() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFinish() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTotalUnreadMessageCount(long count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewConversation(List<ConversationInfo> conversationList) {
|
||||
ConversationFoldPresenter.this.onNewConversation(conversationList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationList) {
|
||||
ConversationFoldPresenter.this.onConversationChanged(conversationList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFriendRemarkChanged(String id, String remark) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshUserStatusFragmentUI() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveMessage(String conversationID, boolean isTypingMessage) {
|
||||
processNewMessage(conversationID, isTypingMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSendForHideConversation(String conversationID) {
|
||||
|
||||
}
|
||||
};
|
||||
TUIConversationService.getInstance().addConversationEventListener(conversationEventForMarkObserver);
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
TUIConversationLog.i(TAG, "loadConversation");
|
||||
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
|
||||
filter.setCount(GET_CONVERSATION_COUNT);
|
||||
long markType = V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD;
|
||||
filter.setMarkType(markType);
|
||||
filter.setNextSeq(0);
|
||||
provider.getMarkConversationList(filter, true, new IUIKitCallback<List<ConversationInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(List<ConversationInfo> conversationInfoList) {
|
||||
if (conversationInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collections.sort(conversationInfoList);
|
||||
List<ConversationInfo> loadList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : conversationInfoList) {
|
||||
if (!conversationInfo.isMarkHidden()) {
|
||||
loadList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
onLoadConversationCompleted(loadList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(TAG, "loadConversation error:" + errCode + ", " + errMsg);
|
||||
if (adapter != null) {
|
||||
adapter.onLoadingStateChanged(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onLoadConversationCompleted(List<ConversationInfo> conversationInfoList) {
|
||||
onNewConversation(conversationInfoList);
|
||||
if (adapter != null) {
|
||||
adapter.onLoadingStateChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 有新的会话
|
||||
* @param conversationInfoList 新的会话列表
|
||||
*/
|
||||
public void onNewConversation(List<ConversationInfo> conversationInfoList) {
|
||||
TUIConversationLog.i(TAG, "onNewConversation conversations:" + conversationInfoList);
|
||||
|
||||
if (conversationInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<ConversationInfo> processedInfoList = processFoldedAndHiddenConversation(conversationInfoList);
|
||||
|
||||
List<ConversationInfo> exists = new ArrayList<>();
|
||||
Iterator<ConversationInfo> iterator = processedInfoList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConversationInfo update = iterator.next();
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo cacheInfo = loadedConversationInfoList.get(i);
|
||||
// 去重
|
||||
if (cacheInfo.getConversationId().equals(update.getConversationId())) {
|
||||
loadedConversationInfoList.set(i, update);
|
||||
iterator.remove();
|
||||
exists.add(update);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 对新增会话排序,避免插入 recyclerview 时错乱
|
||||
Collections.sort(processedInfoList);
|
||||
loadedConversationInfoList.addAll(processedInfoList);
|
||||
if (adapter != null) {
|
||||
Collections.sort(loadedConversationInfoList);
|
||||
adapter.onDataSourceChanged(loadedConversationInfoList);
|
||||
for (ConversationInfo info : processedInfoList) {
|
||||
int index = loadedConversationInfoList.indexOf(info);
|
||||
if (index != -1) {
|
||||
adapter.onItemInserted(index);
|
||||
}
|
||||
}
|
||||
|
||||
for (ConversationInfo info : exists) {
|
||||
int index = loadedConversationInfoList.indexOf(info);
|
||||
if (index != -1) {
|
||||
adapter.onItemChanged(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
TUIConversationLog.i(TAG, "onConversationChanged conversations:" + conversationInfoList);
|
||||
|
||||
ArrayList<ConversationInfo> addInfoList = new ArrayList<>();
|
||||
ArrayList<ConversationInfo> infoList = processFoldedAndHiddenConversation(conversationInfoList);
|
||||
|
||||
ArrayList<ConversationInfo> changedInfoList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : infoList) {
|
||||
if (!ConversationUtils.isIgnored(conversationInfo)) {
|
||||
boolean exists = false;
|
||||
for (ConversationInfo loadedInfo : loadedConversationInfoList) {
|
||||
if (TextUtils.equals(conversationInfo.getConversationId(), loadedInfo.getConversationId())) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exists) {
|
||||
TUIConversationLog.i(TAG, "onConversationChanged conversationInfo " + conversationInfo);
|
||||
changedInfoList.add(conversationInfo);
|
||||
} else {
|
||||
addInfoList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!addInfoList.isEmpty()) {
|
||||
onNewConversation(addInfoList);
|
||||
}
|
||||
|
||||
if (changedInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
refreshChangedInfo(loadedConversationInfoList, changedInfoList);
|
||||
}
|
||||
|
||||
private void refreshChangedInfo(List<ConversationInfo> uiSourceInfoList,
|
||||
ArrayList<ConversationInfo> changedInfoList) {
|
||||
Collections.sort(changedInfoList);
|
||||
|
||||
HashMap<ConversationInfo, Integer> indexMap = new HashMap<>();
|
||||
for (int j = 0; j < changedInfoList.size(); j++) {
|
||||
ConversationInfo update = changedInfoList.get(j);
|
||||
for (int i = 0; i < uiSourceInfoList.size(); i++) {
|
||||
ConversationInfo cacheInfo = uiSourceInfoList.get(i);
|
||||
//单个会话刷新时找到老的会话数据,替换
|
||||
if (cacheInfo.getConversationId().equals(update.getConversationId())) {
|
||||
if (update.getStatusType() == V2TIMUserStatus.V2TIM_USER_STATUS_UNKNOWN) {
|
||||
update.setStatusType(cacheInfo.getStatusType());
|
||||
}
|
||||
uiSourceInfoList.set(i, update);
|
||||
indexMap.put(update, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adapter != null) {
|
||||
Collections.sort(uiSourceInfoList);
|
||||
adapter.onDataSourceChanged(uiSourceInfoList);
|
||||
int minRefreshIndex = Integer.MAX_VALUE;
|
||||
int maxRefreshIndex = Integer.MIN_VALUE;
|
||||
for (ConversationInfo info : changedInfoList) {
|
||||
Integer oldIndexObj = indexMap.get(info);
|
||||
if (oldIndexObj == null) {
|
||||
continue;
|
||||
}
|
||||
int oldIndex = oldIndexObj;
|
||||
int newIndex = uiSourceInfoList.indexOf(info);
|
||||
if (newIndex != -1) {
|
||||
minRefreshIndex = Math.min(minRefreshIndex, Math.min(oldIndex, newIndex));
|
||||
maxRefreshIndex = Math.max(maxRefreshIndex, Math.max(oldIndex, newIndex));
|
||||
}
|
||||
}
|
||||
int count;
|
||||
if (minRefreshIndex == maxRefreshIndex) {
|
||||
count = 1;
|
||||
} else {
|
||||
count = maxRefreshIndex - minRefreshIndex + 1;
|
||||
}
|
||||
if (count > 0 && maxRefreshIndex >= minRefreshIndex) {
|
||||
adapter.onItemRangeChanged(minRefreshIndex, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<ConversationInfo> processFoldedAndHiddenConversation(List<ConversationInfo> infoList) {
|
||||
ArrayList<ConversationInfo> changedInfoList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : infoList) {
|
||||
int uiIndex = -1;
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo loadedInfo = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(conversationInfo.getConversationId(), loadedInfo.getConversationId())) {
|
||||
uiIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uiIndex >= 0) {
|
||||
if (!conversationInfo.isMarkFold() || conversationInfo.isMarkHidden()) {
|
||||
loadedConversationInfoList.remove(uiIndex);
|
||||
if (adapter != null) {
|
||||
adapter.onItemRemoved(uiIndex);
|
||||
}
|
||||
} else if (conversationInfo.isMarkFold()) {
|
||||
changedInfoList.add(conversationInfo);
|
||||
}
|
||||
} else {
|
||||
if (conversationInfo.isMarkFold() && !conversationInfo.isMarkHidden()) {
|
||||
changedInfoList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changedInfoList;
|
||||
}
|
||||
|
||||
private void processNewMessage(String conversationID, boolean isTypingMessage) {
|
||||
if (TextUtils.isEmpty(conversationID)) {
|
||||
return;
|
||||
}
|
||||
if (isTypingMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConversationInfo cacheInfo = null;
|
||||
for (ConversationInfo conversationInfo : loadedConversationInfoList) {
|
||||
if (TextUtils.equals(conversationID, conversationInfo.getConversationId())) {
|
||||
cacheInfo = conversationInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheInfo != null) {
|
||||
if (cacheInfo.isMarkUnread()) {
|
||||
markConversationUnread(cacheInfo, false);
|
||||
}
|
||||
} else {
|
||||
provider.getConversation(conversationID, new IUIKitCallback<ConversationInfo>() {
|
||||
@Override
|
||||
public void onSuccess(ConversationInfo conversationInfo) {
|
||||
if (conversationInfo.isMarkHidden()) {
|
||||
markConversationHidden(conversationInfo, false);
|
||||
}
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会话,会将本地会话数据从imsdk中删除
|
||||
*
|
||||
* @param conversation 会话信息
|
||||
*/
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONVERSATION_ID, conversation.getConversationId());
|
||||
TUICore.callService(TUIConstants.TUIConversation.SERVICE_NAME, TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏会话
|
||||
* hide conversation
|
||||
* @param conversationInfo 会话信息 conversation info
|
||||
*/
|
||||
public void markConversationHidden(ConversationInfo conversationInfo, boolean isHidden) {
|
||||
if (conversationInfo == null || TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
TUIConversationLog.e(TAG, "markConversationHidden error: invalid conversationInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
provider.markConversationHidden(conversationInfo.getConversationId(), isHidden, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {
|
||||
conversationInfo.setMarkHidden(isHidden);
|
||||
TUIConversationLog.i(TAG, "markConversationHidden success, conversationID:" +
|
||||
conversationInfo.getConversationId() + ", isHidden:" + isHidden);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(TAG, "markConversationHidden error, conversationID:" +
|
||||
conversationInfo.getConversationId() + ", code:" + errCode + "|msg:" + errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (conversationInfo == null || TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error: invalid conversationInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
provider.markConversationUnread(conversationInfo, markUnread, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {
|
||||
conversationInfo.setMarkUnread(markUnread);
|
||||
TUIConversationLog.i(TAG, "markConversationRead success, conversationID:" +
|
||||
conversationInfo.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(TAG, "markConversationRead error, conversationID:" +
|
||||
conversationInfo.getConversationId() + ", code:" + errCode + "|msg:" + errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteConversationFromUI(String id, boolean isGroup) {
|
||||
if (!isGroup) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo info = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(info.getId(), id)) {
|
||||
boolean isRemove = loadedConversationInfoList.remove(info);
|
||||
if (adapter != null && isRemove) {
|
||||
adapter.onItemRemoved(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteConversationFromUI(String conversationId) {
|
||||
if (TextUtils.isEmpty(conversationId)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo info = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(info.getConversationId(), conversationId)) {
|
||||
boolean isRemove = loadedConversationInfoList.remove(info);
|
||||
if (adapter != null && isRemove) {
|
||||
adapter.onItemRemoved(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.presenter;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.model.ConversationProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationIconPresenter {
|
||||
private final ConversationProvider provider;
|
||||
|
||||
public ConversationIconPresenter() {
|
||||
provider = new ConversationProvider();
|
||||
}
|
||||
|
||||
public void getGroupMemberIconList(String groupId, IUIKitCallback<List<Object>> callback) {
|
||||
provider.getGroupMemberIconList(groupId, 9, callback);
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 419 B |
|
After Width: | Height: | Size: 314 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 682 B |
|
After Width: | Height: | Size: 547 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="#1F767680"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,64 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/bottom_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/conversation_bottom_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/divide_line"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/dialog_line_bg" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/conversation_bottom_bg"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingLeft="38.4dp"
|
||||
android:paddingRight="38.4dp"
|
||||
android:layout_marginTop="1.36dp"
|
||||
android:layout_marginBottom="46.08dp"
|
||||
android:orientation="horizontal" >
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:text="@string/not_display"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mark_read"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/mark_read"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/delete_chat"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:text="@string/chat_delete"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:gravity="center_vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationIconView
|
||||
android:id="@+id/conversation_icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
tools:background="@android:drawable/ic_menu_gallery"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/user_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_alignBottom="@id/conversation_icon"
|
||||
android:layout_alignEnd="@id/conversation_icon"
|
||||
android:layout_alignRight="@id/conversation_icon"
|
||||
android:visibility="visible"
|
||||
android:background="@drawable/conversation_minimalist_online_icon" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="180dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="top|start"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/black_font_color"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
tools:text="Daniel"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_at_msg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FF666666"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
tools:visibility="visible"
|
||||
tools:text="\@You" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_last_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:layout_gravity="start"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/conversation_at_msg"
|
||||
android:layout_toStartOf="@id/message_status_layout"
|
||||
android:layout_marginEnd="29dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FF666666"
|
||||
android:textSize="12sp"
|
||||
tools:text="Hello"
|
||||
android:layout_toRightOf="@id/conversation_at_msg"
|
||||
android:layout_toLeftOf="@id/message_status_layout"
|
||||
android:layout_marginRight="29dp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/message_status_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/view_line"
|
||||
android:layout_toStartOf="@id/conversation_time"
|
||||
android:layout_alignBottom="@id/conversation_time"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:layout_marginRight="2dp"
|
||||
tools:visibility="visible"
|
||||
android:layout_toLeftOf="@id/conversation_time">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/message_status_sending"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@drawable/ic_sending_status"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/message_status_failed"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_send_failed"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:textColor="#FF666666"
|
||||
android:textSize="12sp"
|
||||
android:lineHeight="14.32sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
tools:text="12:00"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/not_disturb"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:includeFontPadding="false"
|
||||
android:background="@drawable/conversation_minimalist_not_disturb_icon"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<com.tencent.qcloud.tuicore.component.UnreadCountTextView
|
||||
android:id="@+id/conversation_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/conversation_time"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="11sp"
|
||||
app:paint_color="#FF584C"
|
||||
android:layout_alignParentEnd="true"
|
||||
tools:text="2"
|
||||
tools:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?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:background="@color/conversation_page_bg">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationLayout
|
||||
android:id="@+id/folded_conversation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,16 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.tencent.qcloud.tuicore.component.TitleBarLayout
|
||||
android:id="@+id/conversation_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationListLayout
|
||||
android:id="@+id/folded_conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/btn_margin_bottom"
|
||||
android:clickable="true">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationIconView
|
||||
android:id="@+id/conversation_user_icon_view"
|
||||
android:layout_width="41dp"
|
||||
android:layout_height="41dp"
|
||||
app:default_image="?attr/core_default_user_icon"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ForwardSelectLayout
|
||||
android:id="@+id/forward_conversation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/btn_height"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/forward_select_list_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingLeft="14.85dp"
|
||||
android:paddingRight="14.85dp"
|
||||
android:orientation="horizontal">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/forward_select_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/forward_margin"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btn_msg_ok"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/btn_margin_right"
|
||||
android:text="@string/sure"
|
||||
android:textColor="@color/bg_positive_btn"
|
||||
android:textSize="14sp"
|
||||
android:visibility="visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,16 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.tencent.qcloud.tuicore.component.TitleBarLayout
|
||||
android:id="@+id/conversation_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout
|
||||
android:id="@+id/conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textSize="34sp"
|
||||
android:lineHeight="41dp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black_font_color"
|
||||
android:text="@string/conversation_minimalist_chat"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:background="@drawable/conversation_minimalist_edit_icon"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/create_new_button"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginLeft="25dp"
|
||||
android:layout_marginStart="25dp"
|
||||
android:background="@drawable/conversation_minimalist_create_icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/edit_done"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/font_blue"
|
||||
android:text="@string/conversation_minimalist_done"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,88 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/more_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="34dp"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/alert_bg"
|
||||
android:alpha="0.95">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:text="@string/not_display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/top_set"
|
||||
android:text="@string/chat_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/clear_chat"
|
||||
android:text="@string/clear_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/delete_chat"
|
||||
android:text="@string/chat_delete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#FF584C"
|
||||
android:textSize="17sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel_button"
|
||||
android:layout_below="@+id/layout_actions"
|
||||
android:background="@drawable/alert_bg"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/cancel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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:background="@color/conversation_page_bg">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationLayout
|
||||
android:id="@+id/conversation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<include layout="@layout/minimalist_bottom_bar"
|
||||
android:layout_marginBottom="@dimen/page_margin"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,29 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/minimalist_header_view_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/search_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout
|
||||
android:id="@+id/conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/swipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="#FFFFFF"
|
||||
app:clickToClose="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_wrapper_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:tag="Bottom4">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/more_view"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/more_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/conversation_minimalist_more_icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/more_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/more_image"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/more_text"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mark_read"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mark_read_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mark_read_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/mark_read_image"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/mark_read"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/not_display"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/item_left"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="#FFFFFF"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/select_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="6.23dp"
|
||||
android:button="@drawable/checkbox_selector"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/minimalist_conversation_list_item_sub_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:tag="Hover" />
|
||||
|
||||
</LinearLayout>
|
||||
</com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.swipe.SwipeLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="conversation_minimalist_chat">聊天</string>
|
||||
<string name="conversation_minimalist_search">搜索</string>
|
||||
<string name="conversation_minimalist_done">完成</string>
|
||||
<string name="has_all_read">全部已读</string>
|
||||
<string name="start_conversation">发起会话</string>
|
||||
<string name="create_group_chat">创建群聊</string>
|
||||
<string name="more_text">更多</string>
|
||||
<string name="clear_message">清除聊天记录</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="MinimalistHeaderView">
|
||||
<attr name="header_title" format="string" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SwipeLayout">
|
||||
<attr name="drag_edge">
|
||||
<flag name="left" value="1" />
|
||||
<flag name="right" value="2" />
|
||||
<flag name="top" value="4" />
|
||||
<flag name="bottom" value="8" />
|
||||
</attr>
|
||||
<attr name="leftEdgeSwipeOffset" format="dimension" />
|
||||
<attr name="rightEdgeSwipeOffset" format="dimension" />
|
||||
<attr name="topEdgeSwipeOffset" format="dimension" />
|
||||
<attr name="bottomEdgeSwipeOffset" format="dimension" />
|
||||
<attr name="show_mode" format="enum">
|
||||
<enum name="lay_down" value="0" />
|
||||
<enum name="pull_out" value="1" />
|
||||
</attr>
|
||||
<attr name="clickToClose" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="conversation_delete_swipe_bg">#F24D4C</color>
|
||||
<color name="conversation_mark_swipe_bg">#147AFF</color>
|
||||
<color name="conversation_mark_swipe_dark_bg">#666666</color>
|
||||
<color name="conversation_hide_swipe_bg">#F29340</color>
|
||||
<color name="conversation_bottom_bg">#F9F9F9</color>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="conversation_minimalist_chat">Chat</string>
|
||||
<string name="conversation_minimalist_search">Search</string>
|
||||
<string name="conversation_minimalist_done">Done</string>
|
||||
<string name="has_all_read">Read All</string>
|
||||
<string name="start_conversation">New Chat</string>
|
||||
<string name="create_group_chat">Create Group Chat</string>
|
||||
<string name="more_text">More</string>
|
||||
<string name="clear_message">Clear Chat History</string>
|
||||
</resources>
|
||||
17
tuiconversation/src/main/res/color/bg_positive_btn.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" android:color="@color/btn_positive_hover" >
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="@color/btn_positive_hover" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:color="@color/btn_positive" >
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="@color/btn_positive" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
tuiconversation/src/main/res/drawable-xxhdpi/create_c2c.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
tuiconversation/src/main/res/drawable-xxhdpi/group_icon.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |