私聊改造:长按弹窗UI修改

This commit is contained in:
huangjian
2023-01-31 17:41:37 +08:00
parent 0ba0aed40f
commit b37b1fc115
6 changed files with 519 additions and 478 deletions

View File

@@ -11,6 +11,7 @@ import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@@ -35,7 +36,7 @@ import com.netease.nim.uikit.business.session.module.Container;
import com.netease.nim.uikit.business.session.module.list.IncomingMsgPrompt; import com.netease.nim.uikit.business.session.module.list.IncomingMsgPrompt;
import com.netease.nim.uikit.business.session.module.list.MsgAdapter; import com.netease.nim.uikit.business.session.module.list.MsgAdapter;
import com.netease.nim.uikit.business.session.viewholder.robot.RobotLinkView; import com.netease.nim.uikit.business.session.viewholder.robot.RobotLinkView;
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog; import com.netease.nim.uikit.common.ui.dialog.CustomPopupWindow;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog; import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper; import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseFetchLoadAdapter; import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseFetchLoadAdapter;
@@ -955,7 +956,7 @@ public class MessageListPanelEx {
@Override @Override
public boolean onViewHolderLongClick(View clickView, View viewHolderView, IMMessage item) { public boolean onViewHolderLongClick(View clickView, View viewHolderView, IMMessage item) {
if (container.proxy.isLongClickEnabled()) { if (container.proxy.isLongClickEnabled()) {
showLongClickAction(item); onNormalLongClick(clickView, item);
} }
return true; return true;
} }
@@ -1011,28 +1012,21 @@ public class MessageListPanelEx {
* ****************************** 长按菜单 ******************************** * ****************************** 长按菜单 ********************************
*/ */
// 长按消息Item后弹出菜单控制
private void showLongClickAction(IMMessage selectedItem) {
onNormalLongClick(selectedItem);
}
/** /**
* 长按菜单操作 * 长按菜单操作
* *
* @param item * @param item
*/ */
private void onNormalLongClick(IMMessage item) { private void onNormalLongClick(View clickView, IMMessage item) {
CustomAlertDialog alertDialog = new CustomAlertDialog(container.activity); CustomPopupWindow alertDialog = new CustomPopupWindow(container.activity, LinearLayout.HORIZONTAL);
alertDialog.setCancelable(true);
alertDialog.setCanceledOnTouchOutside(true);
prepareDialogItems(item, alertDialog); prepareDialogItems(item, alertDialog);
alertDialog.show(); alertDialog.show(clickView, 0, ScreenUtil.dip2px(5));
} }
// 长按消息item的菜单项准备。如果消息item的MsgViewHolder处理长按事件(MsgViewHolderBase#onItemLongClick),且返回为true // 长按消息item的菜单项准备。如果消息item的MsgViewHolder处理长按事件(MsgViewHolderBase#onItemLongClick),且返回为true
// 则对应项的长按事件不会调用到此处 // 则对应项的长按事件不会调用到此处
private void prepareDialogItems(final IMMessage selectedItem, CustomAlertDialog alertDialog) { private void prepareDialogItems(final IMMessage selectedItem, CustomPopupWindow alertDialog) {
MsgTypeEnum msgType = selectedItem.getMsgType(); MsgTypeEnum msgType = selectedItem.getMsgType();
MessageAudioControl.getInstance(container.activity).stopAudio(); MessageAudioControl.getInstance(container.activity).stopAudio();
@@ -1050,7 +1044,7 @@ public class MessageListPanelEx {
// 4 delete // 4 delete
longClickItemDelete(selectedItem, alertDialog); longClickItemDelete(selectedItem, alertDialog);
// 5 trans // 5 trans
longClickItemVoidToText(selectedItem, alertDialog, msgType); //longClickItemVoidToText(selectedItem, alertDialog, msgType);
if (NimUIKitImpl.getMsgForwardFilter() != null && !NimUIKitImpl.getMsgForwardFilter().shouldIgnore(selectedItem) && !recordOnly) { if (NimUIKitImpl.getMsgForwardFilter() != null && !NimUIKitImpl.getMsgForwardFilter().shouldIgnore(selectedItem) && !recordOnly) {
// 6 forward to person // 6 forward to person
@@ -1069,14 +1063,14 @@ public class MessageListPanelEx {
} }
// 长按菜单项--重发 // 长按菜单项--重发
private void longClickItemResend(final IMMessage item, CustomAlertDialog alertDialog) { private void longClickItemResend(final IMMessage item, CustomPopupWindow alertDialog) {
if (item.getStatus() != MsgStatusEnum.fail) { if (item.getStatus() != MsgStatusEnum.fail) {
return; return;
} }
alertDialog.addItem(container.activity.getString(R.string.repeat_send_has_blank), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.repeat_send_has_blank), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
onResendMessageItem(item); onResendMessageItem(item);
} }
}); });
@@ -1107,13 +1101,13 @@ public class MessageListPanelEx {
} }
// 长按菜单项--复制 // 长按菜单项--复制
private void longClickItemCopy(final IMMessage item, CustomAlertDialog alertDialog, MsgTypeEnum msgType) { private void longClickItemCopy(final IMMessage item, CustomPopupWindow alertDialog, MsgTypeEnum msgType) {
if (msgType == MsgTypeEnum.text || if (msgType == MsgTypeEnum.text ||
(msgType == MsgTypeEnum.robot && item.getAttachment() != null && !((RobotAttachment) item.getAttachment()).isRobotSend())) { (msgType == MsgTypeEnum.robot && item.getAttachment() != null && !((RobotAttachment) item.getAttachment()).isRobotSend())) {
alertDialog.addItem(container.activity.getString(R.string.copy_has_blank), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.copy_has_blank), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
onCopyMessageItem(item); onCopyMessageItem(item);
} }
}); });
@@ -1125,21 +1119,21 @@ public class MessageListPanelEx {
} }
// 长按菜单项--删除 // 长按菜单项--删除
private void longClickItemDelete(final IMMessage selectedItem, CustomAlertDialog alertDialog) { private void longClickItemDelete(final IMMessage selectedItem, CustomPopupWindow alertDialog) {
if (recordOnly) { if (recordOnly) {
return; return;
} }
alertDialog.addItem(container.activity.getString(R.string.delete_has_blank), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.delete_has_blank), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
deleteItem(selectedItem, true); deleteItem(selectedItem, true);
} }
}); });
} }
// 长按菜单项 -- 音频转文字 // 长按菜单项 -- 音频转文字
private void longClickItemVoidToText(final IMMessage item, CustomAlertDialog alertDialog, MsgTypeEnum msgType) { private void longClickItemVoidToText(final IMMessage item, CustomPopupWindow alertDialog, MsgTypeEnum msgType) {
if (msgType != MsgTypeEnum.audio) return; if (msgType != MsgTypeEnum.audio) return;
if (item.getDirect() == MsgDirectionEnum.In if (item.getDirect() == MsgDirectionEnum.In
@@ -1149,10 +1143,10 @@ public class MessageListPanelEx {
&& item.getAttachStatus() != AttachStatusEnum.transferred) && item.getAttachStatus() != AttachStatusEnum.transferred)
return; return;
alertDialog.addItem(container.activity.getString(R.string.voice_to_text), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.voice_to_text), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
onVoiceToText(item); onVoiceToText(item);
} }
}); });
@@ -1171,15 +1165,15 @@ public class MessageListPanelEx {
} }
// 长按菜单项 -- 听筒扬声器切换 // 长按菜单项 -- 听筒扬声器切换
private void longClickItemEarPhoneMode(CustomAlertDialog alertDialog, MsgTypeEnum msgType) { private void longClickItemEarPhoneMode(CustomPopupWindow alertDialog, MsgTypeEnum msgType) {
if (msgType != MsgTypeEnum.audio) return; if (msgType != MsgTypeEnum.audio) return;
String content = UserPreferences.isEarPhoneModeEnable() ? "切换成扬声器播放" : "切换成听筒播放"; String content = UserPreferences.isEarPhoneModeEnable() ? "切换成扬声器播放" : "切换成听筒播放";
final String finalContent = content; final String finalContent = content;
alertDialog.addItem(content, new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(content, new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
SingleToastUtil.showToast(finalContent); SingleToastUtil.showToast(finalContent);
setEarPhoneMode(!UserPreferences.isEarPhoneModeEnable(), true); setEarPhoneMode(!UserPreferences.isEarPhoneModeEnable(), true);
} }
@@ -1187,11 +1181,11 @@ public class MessageListPanelEx {
} }
// 长按菜单项 -- 转发到个人 // 长按菜单项 -- 转发到个人
private void longClickItemForwardToPerson(final IMMessage item, CustomAlertDialog alertDialog) { private void longClickItemForwardToPerson(final IMMessage item, CustomPopupWindow alertDialog) {
alertDialog.addItem(container.activity.getString(R.string.forward_to_person), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.forward_to_person), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
forwardMessage = item; forwardMessage = item;
ContactSelectActivity.Option option = new ContactSelectActivity.Option(); ContactSelectActivity.Option option = new ContactSelectActivity.Option();
option.title = "选择转发的人"; option.title = "选择转发的人";
@@ -1204,11 +1198,11 @@ public class MessageListPanelEx {
} }
// 长按菜单项 -- 转发到群组 // 长按菜单项 -- 转发到群组
private void longClickItemForwardToTeam(final IMMessage item, CustomAlertDialog alertDialog) { private void longClickItemForwardToTeam(final IMMessage item, CustomPopupWindow alertDialog) {
alertDialog.addItem(container.activity.getString(R.string.forward_to_team), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.forward_to_team), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
forwardMessage = item; forwardMessage = item;
ContactSelectActivity.Option option = new ContactSelectActivity.Option(); ContactSelectActivity.Option option = new ContactSelectActivity.Option();
option.title = "选择转发的群"; option.title = "选择转发的群";
@@ -1221,11 +1215,11 @@ public class MessageListPanelEx {
} }
// 长按菜单项 -- 撤回消息 // 长按菜单项 -- 撤回消息
private void longClickRevokeMsg(final IMMessage item, CustomAlertDialog alertDialog) { private void longClickRevokeMsg(final IMMessage item, CustomPopupWindow alertDialog) {
alertDialog.addItem(container.activity.getString(R.string.withdrawn_msg), new CustomAlertDialog.onSeparateItemClickListener() { alertDialog.addItem(container.activity.getString(R.string.withdrawn_msg), new View.OnClickListener() {
@Override @Override
public void onClick() { public void onClick(View v) {
if (!NetworkUtil.isNetAvailable(container.activity)) { if (!NetworkUtil.isNetAvailable(container.activity)) {
SingleToastUtil.showToast(R.string.network_is_not_available); SingleToastUtil.showToast(R.string.network_is_not_available);
return; return;

View File

@@ -6,6 +6,7 @@ import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -27,6 +28,7 @@ import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.netease.nim.uikit.common.badger.Badger; import com.netease.nim.uikit.common.badger.Badger;
import com.netease.nim.uikit.common.fragment.TFragment; import com.netease.nim.uikit.common.fragment.TFragment;
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog; import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.CustomPopupWindow;
import com.netease.nim.uikit.common.ui.drop.DropCover; import com.netease.nim.uikit.common.ui.drop.DropCover;
import com.netease.nim.uikit.common.ui.drop.DropManager; import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.recyclerview.listener.SimpleClickListener; import com.netease.nim.uikit.common.ui.recyclerview.listener.SimpleClickListener;
@@ -194,7 +196,7 @@ public class RecentContactsFragment extends TFragment {
@Override @Override
public void onItemLongClick(RecentContactAdapter adapter, View view, int position) { public void onItemLongClick(RecentContactAdapter adapter, View view, int position) {
showLongClickMenu(adapter.getItem(position), position); showLongClickMenu(view, adapter.getItem(position), position);
} }
@Override @Override
@@ -400,34 +402,27 @@ public class RecentContactsFragment extends TFragment {
NimUIKitImpl.getOnlineStateChangeObservable().registerOnlineStateChangeListeners(onlineStateChangeObserver, register); NimUIKitImpl.getOnlineStateChangeObservable().registerOnlineStateChangeListeners(onlineStateChangeObserver, register);
} }
private void showLongClickMenu(final RecentContact recent, final int position) { private void showLongClickMenu(View view, final RecentContact recent, final int position) {
CustomAlertDialog alertDialog = new CustomAlertDialog(getActivity()); CustomPopupWindow alertDialog = new CustomPopupWindow(getActivity(), LinearLayout.VERTICAL);
alertDialog.setTitle(UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType()));
String title = getString(R.string.main_msg_list_delete_chatting); String title = getString(R.string.main_msg_list_delete_chatting);
alertDialog.addItem(title, new onSeparateItemClickListener() { alertDialog.addItem(title, v -> {
@Override // 删除会话,删除后,消息历史被一起删除
public void onClick() { NIMClient.getService(MsgService.class).deleteRecentContact2(recent.getContactId(), recent.getSessionType());
// 删除会话,删除后,消息历史被一起删除 NIMClient.getService(MsgService.class).clearChattingHistory(recent.getContactId(), recent.getSessionType());
NIMClient.getService(MsgService.class).deleteRecentContact2(recent.getContactId(), recent.getSessionType());
NIMClient.getService(MsgService.class).clearChattingHistory(recent.getContactId(), recent.getSessionType());
}
}); });
title = (isTagSet(recent, RECENT_TAG_STICKY) ? getString(R.string.main_msg_list_clear_sticky_on_top) : getString(R.string.main_msg_list_sticky_on_top)); title = (isTagSet(recent, RECENT_TAG_STICKY) ? getString(R.string.main_msg_list_clear_sticky_on_top) : getString(R.string.main_msg_list_sticky_on_top));
alertDialog.addItem(title, new onSeparateItemClickListener() { alertDialog.addItem(title, v -> {
@Override if (isTagSet(recent, RECENT_TAG_STICKY)) {
public void onClick() { removeTag(recent, RECENT_TAG_STICKY);
if (isTagSet(recent, RECENT_TAG_STICKY)) { } else {
removeTag(recent, RECENT_TAG_STICKY); addTag(recent, RECENT_TAG_STICKY);
} else {
addTag(recent, RECENT_TAG_STICKY);
}
NIMClient.getService(MsgService.class).updateRecent(recent);
refreshMessages(false);
} }
NIMClient.getService(MsgService.class).updateRecent(recent);
refreshMessages(false);
}); });
alertDialog.show(); alertDialog.show(view, view.getMeasuredWidth() / 2, 0);
} }
private void addTag(RecentContact recent, long tag) { private void addTag(RecentContact recent, long tag) {

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#767676" />
<corners android:radius="8dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/nim_shape_767676_8dp"
android:orientation="vertical" >
</LinearLayout>

View File

@@ -0,0 +1,75 @@
package com.netease.nim.uikit.common.ui.dialog;
import static android.widget.LinearLayout.SHOW_DIVIDER_BEGINNING;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import java.util.LinkedList;
import java.util.List;
public class CustomPopupWindow extends PopupWindow {
private final Context context;
private final LinearLayout llRoot;
private final List<Pair<String, View.OnClickListener>> itemTextList = new LinkedList<>();
private int orientation;
public CustomPopupWindow(Context context, int orientation) {
this.context = context;
this.orientation = orientation;
llRoot = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.nim_custom_popup_window, null);
setContentView(llRoot);
llRoot.setShowDividers(SHOW_DIVIDER_BEGINNING);
llRoot.setOrientation(orientation);
setBackgroundDrawable(new ColorDrawable());
setOutsideTouchable(true);
setFocusable(true);
}
public void addItem(String itemText, View.OnClickListener listener) {
itemTextList.add(new Pair<>(itemText, listener));
}
public void show(View anchor, int xoff, int yoff) {
for (Pair<String, View.OnClickListener> pair : itemTextList) {
llRoot.addView(
createTextView(pair.first, pair.second),
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, ScreenUtil.dip2px(30))
);
}
setHeight(ScreenUtil.dip2px(30 * (orientation == LinearLayout.HORIZONTAL ? 1 : itemTextList.size())));
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
showAsDropDown(anchor, xoff, yoff);
}
private TextView createTextView(CharSequence text, View.OnClickListener listener) {
TextView textView = new TextView(context);
textView.setPadding(ScreenUtil.dip2px(8), 0, ScreenUtil.dip2px(8), 0);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.WHITE);
textView.setTextSize(10);
textView.setSingleLine(true);
textView.setOnClickListener(v -> {
listener.onClick(v);
dismiss();
});
textView.setText(text);
return textView;
}
}