530 lines
17 KiB
Plaintext
530 lines
17 KiB
Plaintext
# 设置中添加黑名单功能实现文档
|
||
|
||
## 功能背景
|
||
|
||
根据用户需求,在"我的-设置"页面中增加黑名单功能,让用户可以查看和管理黑名单用户,提供完整的黑名单管理体验。
|
||
|
||
## 问题描述
|
||
|
||
**测试步骤**:我的-设置页面
|
||
**问题**:缺少黑名单管理功能,用户无法查看和管理已加入黑名单的用户。
|
||
|
||
## 功能实现
|
||
|
||
### 1. 设置页面添加黑名单条目
|
||
|
||
#### 1.1 修改setting_activity.xml
|
||
**文件路径**:`app/src/main/res/layout/setting_activity.xml`
|
||
|
||
```xml
|
||
<!-- 在青少年模式下方添加黑名单条目 -->
|
||
<cn.wildfire.chat.kit.widget.OptionItemView
|
||
android:id="@+id/blacklist_option"
|
||
style="@style/OptionItem"
|
||
app:show_arrow_indicator="true"
|
||
app:show_divider="true"
|
||
app:title="黑名单" />
|
||
```
|
||
|
||
#### 1.2 修改SettingActivity.java
|
||
**文件路径**:`app/src/main/java/com/xunpaisoft/social/im/setting/SettingActivity.java`
|
||
|
||
```java
|
||
// 添加点击事件绑定
|
||
findViewById(R.id.blacklist_option).setOnClickListener(v -> blacklist());
|
||
|
||
// 添加跳转方法
|
||
void blacklist() {
|
||
Intent intent = new Intent(this, BlacklistActivity.class);
|
||
startActivity(intent);
|
||
}
|
||
```
|
||
|
||
### 2. 创建黑名单页面
|
||
|
||
#### 2.1 创建BlacklistActivity.java
|
||
**文件路径**:`app/src/main/java/com/xunpaisoft/social/im/setting/BlacklistActivity.java`
|
||
|
||
```java
|
||
public class BlacklistActivity extends WfcBaseActivity {
|
||
|
||
private RecyclerView recyclerView;
|
||
private BlacklistAdapter adapter;
|
||
private List<UserInfo> blacklistUsers = new ArrayList<>();
|
||
private UserViewModel userViewModel;
|
||
|
||
@Override
|
||
protected int contentLayout() {
|
||
return R.layout.activity_blacklist;
|
||
}
|
||
|
||
@Override
|
||
protected void afterViews() {
|
||
super.afterViews();
|
||
initViews();
|
||
loadBlacklist();
|
||
}
|
||
|
||
private void initViews() {
|
||
setToolBarTitle("黑名单");
|
||
|
||
recyclerView = findViewById(R.id.recyclerView);
|
||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||
|
||
adapter = new BlacklistAdapter(blacklistUsers, new BlacklistAdapter.OnUserClickListener() {
|
||
@Override
|
||
public void onRemoveUser(UserInfo userInfo) {
|
||
showRemoveConfirmDialog(userInfo);
|
||
}
|
||
});
|
||
|
||
recyclerView.setAdapter(adapter);
|
||
userViewModel = new UserViewModel();
|
||
}
|
||
|
||
private void loadBlacklist() {
|
||
// 获取黑名单用户ID列表
|
||
List<String> blacklistUserIds = ChatManagerHolder.gChatManager.getBlackList(true);
|
||
|
||
if (blacklistUserIds == null || blacklistUserIds.isEmpty()) {
|
||
showEmptyView();
|
||
return;
|
||
}
|
||
|
||
// 获取用户详细信息
|
||
List<UserInfo> userInfos = userViewModel.getUserInfos(blacklistUserIds);
|
||
if (userInfos != null && !userInfos.isEmpty()) {
|
||
blacklistUsers.clear();
|
||
blacklistUsers.addAll(userInfos);
|
||
adapter.notifyDataSetChanged();
|
||
} else {
|
||
showEmptyView();
|
||
}
|
||
}
|
||
|
||
private void showEmptyView() {
|
||
findViewById(R.id.emptyView).setVisibility(View.VISIBLE);
|
||
recyclerView.setVisibility(View.GONE);
|
||
}
|
||
|
||
private void showRemoveConfirmDialog(UserInfo userInfo) {
|
||
String userName = TextUtils.isEmpty(userInfo.displayName) ? userInfo.name : userInfo.displayName;
|
||
|
||
new AlertDialog.Builder(this)
|
||
.setTitle("移除黑名单")
|
||
.setMessage("确定要将 " + userName + " 从黑名单中移除吗?")
|
||
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||
@Override
|
||
public void onClick(DialogInterface dialog, int which) {
|
||
removeFromBlacklist(userInfo);
|
||
}
|
||
})
|
||
.setNegativeButton("取消", null)
|
||
.show();
|
||
}
|
||
|
||
private void removeFromBlacklist(UserInfo userInfo) {
|
||
// 将用户从黑名单中移除
|
||
ChatManagerHolder.gChatManager.setBlackList(userInfo.uid, false, new GeneralCallback() {
|
||
@Override
|
||
public void onSuccess() {
|
||
runOnUiThread(() -> {
|
||
// 从本地列表中移除
|
||
blacklistUsers.remove(userInfo);
|
||
adapter.notifyDataSetChanged();
|
||
|
||
// 如果列表为空,显示空状态
|
||
if (blacklistUsers.isEmpty()) {
|
||
showEmptyView();
|
||
}
|
||
|
||
Toast.makeText(BlacklistActivity.this, "已从黑名单中移除", Toast.LENGTH_SHORT).show();
|
||
});
|
||
}
|
||
|
||
@Override
|
||
public void onFail(int errorCode) {
|
||
runOnUiThread(() -> {
|
||
Toast.makeText(BlacklistActivity.this, "移除失败,请重试", Toast.LENGTH_SHORT).show();
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2.2 创建activity_blacklist.xml
|
||
**文件路径**:`app/src/main/res/layout/activity_blacklist.xml`
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||
android:layout_width="match_parent"
|
||
android:layout_height="match_parent"
|
||
android:background="@color/gray5"
|
||
android:orientation="vertical">
|
||
|
||
<include layout="@layout/toolbar" />
|
||
|
||
<!-- 黑名单用户列表 -->
|
||
<androidx.recyclerview.widget.RecyclerView
|
||
android:id="@+id/recyclerView"
|
||
android:layout_width="match_parent"
|
||
android:layout_height="match_parent"
|
||
android:paddingTop="8dp" />
|
||
|
||
<!-- 空状态视图 -->
|
||
<LinearLayout
|
||
android:id="@+id/emptyView"
|
||
android:layout_width="match_parent"
|
||
android:layout_height="match_parent"
|
||
android:gravity="center"
|
||
android:orientation="vertical"
|
||
android:visibility="gone">
|
||
|
||
<ImageView
|
||
android:layout_width="80dp"
|
||
android:layout_height="80dp"
|
||
android:layout_marginBottom="16dp"
|
||
android:src="@drawable/ic_empty_blacklist"
|
||
android:alpha="0.6" />
|
||
|
||
<TextView
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:text="暂无黑名单用户"
|
||
android:textColor="@color/color_9999"
|
||
android:textSize="16sp" />
|
||
|
||
<TextView
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:layout_marginTop="8dp"
|
||
android:text="您可以将不想联系的用户加入黑名单"
|
||
android:textColor="@color/color_9999"
|
||
android:textSize="14sp" />
|
||
|
||
</LinearLayout>
|
||
|
||
</LinearLayout>
|
||
```
|
||
|
||
### 3. 创建黑名单用户列表适配器
|
||
|
||
#### 3.1 创建BlacklistAdapter.java
|
||
**文件路径**:`app/src/main/java/com/xunpaisoft/social/im/setting/BlacklistAdapter.java`
|
||
|
||
```java
|
||
public class BlacklistAdapter extends RecyclerView.Adapter<BlacklistAdapter.ViewHolder> {
|
||
|
||
private List<UserInfo> userList;
|
||
private OnUserClickListener listener;
|
||
|
||
public interface OnUserClickListener {
|
||
void onRemoveUser(UserInfo userInfo);
|
||
}
|
||
|
||
public BlacklistAdapter(List<UserInfo> userList, OnUserClickListener listener) {
|
||
this.userList = userList;
|
||
this.listener = listener;
|
||
}
|
||
|
||
@NonNull
|
||
@Override
|
||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||
View view = LayoutInflater.from(parent.getContext())
|
||
.inflate(R.layout.item_blacklist_user, parent, false);
|
||
return new ViewHolder(view);
|
||
}
|
||
|
||
@Override
|
||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||
UserInfo userInfo = userList.get(position);
|
||
|
||
// 设置头像
|
||
if (!TextUtils.isEmpty(userInfo.portrait)) {
|
||
GlideUtils.loadImage(holder.avatarImageView.getContext(), userInfo.portrait, holder.avatarImageView, R.mipmap.icon_default_man, R.mipmap.icon_default_man);
|
||
} else {
|
||
holder.avatarImageView.setImageResource(R.mipmap.icon_default_man);
|
||
}
|
||
|
||
// 设置用户名
|
||
String displayName = TextUtils.isEmpty(userInfo.displayName) ? userInfo.name : userInfo.displayName;
|
||
holder.nameTextView.setText(displayName);
|
||
|
||
// 设置移除按钮点击事件
|
||
holder.removeButton.setOnClickListener(v -> {
|
||
if (listener != null) {
|
||
listener.onRemoveUser(userInfo);
|
||
}
|
||
});
|
||
}
|
||
|
||
@Override
|
||
public int getItemCount() {
|
||
return userList.size();
|
||
}
|
||
|
||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||
ImageView avatarImageView;
|
||
TextView nameTextView;
|
||
TextView removeButton;
|
||
|
||
public ViewHolder(@NonNull View itemView) {
|
||
super(itemView);
|
||
avatarImageView = itemView.findViewById(R.id.avatarImageView);
|
||
nameTextView = itemView.findViewById(R.id.nameTextView);
|
||
removeButton = itemView.findViewById(R.id.removeButton);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 3.2 创建item_blacklist_user.xml
|
||
**文件路径**:`app/src/main/res/layout/item_blacklist_user.xml`
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||
android:layout_width="match_parent"
|
||
android:layout_height="wrap_content"
|
||
android:background="@color/white"
|
||
android:orientation="horizontal"
|
||
android:padding="16dp">
|
||
|
||
<!-- 用户头像 -->
|
||
<ImageView
|
||
android:id="@+id/avatarImageView"
|
||
android:layout_width="48dp"
|
||
android:layout_height="48dp"
|
||
android:layout_marginEnd="12dp"
|
||
android:scaleType="centerCrop"
|
||
android:src="@mipmap/icon_default_man" />
|
||
|
||
<!-- 用户信息区域 -->
|
||
<LinearLayout
|
||
android:layout_width="0dp"
|
||
android:layout_height="wrap_content"
|
||
android:layout_weight="1"
|
||
android:orientation="vertical"
|
||
android:gravity="center_vertical">
|
||
|
||
<TextView
|
||
android:id="@+id/nameTextView"
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:text="用户名"
|
||
android:textColor="@color/color_3333"
|
||
android:textSize="16sp"
|
||
android:textStyle="bold" />
|
||
|
||
</LinearLayout>
|
||
|
||
<!-- 移除按钮 -->
|
||
<TextView
|
||
android:id="@+id/removeButton"
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:background="@drawable/btn_remove_blacklist"
|
||
android:clickable="true"
|
||
android:focusable="true"
|
||
android:gravity="center"
|
||
android:minWidth="60dp"
|
||
android:paddingHorizontal="12dp"
|
||
android:paddingVertical="6dp"
|
||
android:text="移除"
|
||
android:textColor="@color/white"
|
||
android:textSize="14sp" />
|
||
|
||
</LinearLayout>
|
||
```
|
||
|
||
### 4. 创建样式和资源文件
|
||
|
||
#### 4.1 创建btn_remove_blacklist.xml
|
||
**文件路径**:`app/src/main/res/drawable/btn_remove_blacklist.xml`
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||
android:shape="rectangle">
|
||
<solid android:color="#FF6B6B" />
|
||
<corners android:radius="16dp" />
|
||
</shape>
|
||
```
|
||
|
||
#### 4.2 创建ic_empty_blacklist.xml
|
||
**文件路径**:`app/src/main/res/drawable/ic_empty_blacklist.xml`
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||
android:width="80dp"
|
||
android:height="80dp"
|
||
android:viewportWidth="24"
|
||
android:viewportHeight="24">
|
||
|
||
<path
|
||
android:fillColor="#CCCCCC"
|
||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4,12c0,-4.42 3.58,-8 8,-8 1.85,0 3.55,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4,13.85 4,12zM12,20c-1.85,0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20,10.15 20,12c0,4.42 -3.58,8 -8,8z"/>
|
||
|
||
<path
|
||
android:fillColor="#CCCCCC"
|
||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||
</vector>
|
||
```
|
||
|
||
### 5. 注册Activity
|
||
|
||
#### 5.1 修改AndroidManifest.xml
|
||
**文件路径**:`app/src/main/AndroidManifest.xml`
|
||
|
||
```xml
|
||
<activity
|
||
android:name=".im.setting.BlacklistActivity"
|
||
android:label="黑名单"
|
||
android:screenOrientation="portrait" />
|
||
```
|
||
|
||
## 技术实现细节
|
||
|
||
### 1. IM接口调用
|
||
|
||
#### 1.1 获取黑名单
|
||
```java
|
||
// 获取黑名单用户ID列表
|
||
List<String> blacklistUserIds = ChatManagerHolder.gChatManager.getBlackList(true);
|
||
```
|
||
|
||
#### 1.2 移除黑名单
|
||
```java
|
||
// 将用户从黑名单中移除
|
||
ChatManagerHolder.gChatManager.setBlackList(userInfo.uid, false, new GeneralCallback() {
|
||
@Override
|
||
public void onSuccess() {
|
||
// 移除成功处理
|
||
}
|
||
|
||
@Override
|
||
public void onFail(int errorCode) {
|
||
// 错误处理
|
||
}
|
||
});
|
||
```
|
||
|
||
### 2. 用户信息获取
|
||
|
||
#### 2.1 同步获取用户信息
|
||
```java
|
||
// 获取用户详细信息
|
||
List<UserInfo> userInfos = userViewModel.getUserInfos(blacklistUserIds);
|
||
```
|
||
|
||
#### 2.2 头像加载
|
||
```java
|
||
// 使用GlideUtils加载用户头像
|
||
if (!TextUtils.isEmpty(userInfo.portrait)) {
|
||
GlideUtils.loadImage(holder.avatarImageView.getContext(), userInfo.portrait, holder.avatarImageView, R.mipmap.icon_default_man, R.mipmap.icon_default_man);
|
||
} else {
|
||
holder.avatarImageView.setImageResource(R.mipmap.icon_default_man);
|
||
}
|
||
```
|
||
|
||
### 3. 界面交互
|
||
|
||
#### 3.1 确认对话框
|
||
```java
|
||
private void showRemoveConfirmDialog(UserInfo userInfo) {
|
||
String userName = TextUtils.isEmpty(userInfo.displayName) ? userInfo.name : userInfo.displayName;
|
||
|
||
new AlertDialog.Builder(this)
|
||
.setTitle("移除黑名单")
|
||
.setMessage("确定要将 " + userName + " 从黑名单中移除吗?")
|
||
.setPositiveButton("确定", (dialog, which) -> removeFromBlacklist(userInfo))
|
||
.setNegativeButton("取消", null)
|
||
.show();
|
||
}
|
||
```
|
||
|
||
#### 3.2 空状态处理
|
||
```java
|
||
private void showEmptyView() {
|
||
findViewById(R.id.emptyView).setVisibility(View.VISIBLE);
|
||
recyclerView.setVisibility(View.GONE);
|
||
}
|
||
```
|
||
|
||
## 功能效果
|
||
|
||
### 1. 设置页面结构
|
||
```
|
||
设置
|
||
├── 账号安全
|
||
├── 消息通知(开关)
|
||
├── 青少年模式
|
||
├── 黑名单 ← 新增
|
||
├── 清除缓存
|
||
├── 意见反馈
|
||
├── 版本更新
|
||
└── 关于我们
|
||
```
|
||
|
||
### 2. 黑名单页面功能
|
||
- **用户列表显示**:显示所有黑名单用户的头像和姓名
|
||
- **移除功能**:点击移除按钮可以移除用户
|
||
- **确认对话框**:移除前显示确认对话框
|
||
- **空状态提示**:无黑名单用户时显示友好提示
|
||
- **实时更新**:移除后立即更新界面
|
||
|
||
### 3. 用户体验
|
||
- **操作简单**:一键移除黑名单用户
|
||
- **安全确认**:移除前需要用户确认
|
||
- **状态反馈**:操作成功或失败都有提示
|
||
- **界面友好**:空状态时提供使用说明
|
||
|
||
## 文件清单
|
||
|
||
### 1. 新增文件
|
||
1. `app/src/main/java/com/xunpaisoft/social/im/setting/BlacklistActivity.java` - 黑名单页面
|
||
2. `app/src/main/java/com/xunpaisoft/social/im/setting/BlacklistAdapter.java` - 列表适配器
|
||
3. `app/src/main/res/layout/activity_blacklist.xml` - 黑名单页面布局
|
||
4. `app/src/main/res/layout/item_blacklist_user.xml` - 用户列表项布局
|
||
5. `app/src/main/res/drawable/btn_remove_blacklist.xml` - 移除按钮样式
|
||
6. `app/src/main/res/drawable/ic_empty_blacklist.xml` - 空状态图标
|
||
|
||
### 2. 修改文件
|
||
1. `app/src/main/res/layout/setting_activity.xml` - 添加黑名单条目
|
||
2. `app/src/main/java/com/xunpaisoft/social/im/setting/SettingActivity.java` - 添加跳转逻辑
|
||
3. `app/src/main/AndroidManifest.xml` - 注册BlacklistActivity
|
||
|
||
## 优势特点
|
||
|
||
### 1. 用户体验
|
||
- **功能完整**:支持查看和移除黑名单用户
|
||
- **操作便捷**:一键移除,操作简单
|
||
- **安全可靠**:移除前需要确认,避免误操作
|
||
- **状态清晰**:空状态时提供友好提示
|
||
|
||
### 2. 技术优势
|
||
- **架构清晰**:使用MVVM架构,代码结构清晰
|
||
- **性能优良**:使用RecyclerView,支持大量数据
|
||
- **内存安全**:正确处理Activity生命周期
|
||
- **错误处理**:完善的网络错误处理机制
|
||
|
||
### 3. 业务价值
|
||
- **用户管理**:提供完整的黑名单管理功能
|
||
- **隐私保护**:用户可以管理不想联系的用户
|
||
- **体验提升**:完善的功能提升用户满意度
|
||
- **系统完整**:补全了IM系统的用户管理功能
|
||
|
||
## 总结
|
||
|
||
本次功能实现成功在设置页面添加了黑名单功能,通过以下方式实现:
|
||
|
||
1. **界面完善**:在设置页面添加黑名单条目,创建专门的黑名单管理页面
|
||
2. **功能完整**:支持查看黑名单用户列表,支持移除黑名单用户
|
||
3. **用户体验**:提供确认对话框、空状态提示、操作反馈等完善的用户体验
|
||
4. **技术实现**:使用IM接口进行黑名单管理,使用RecyclerView展示用户列表
|
||
|
||
功能实现后,用户可以在设置页面进入黑名单管理,查看所有黑名单用户,并可以方便地移除不需要的用户,完全满足了用户需求,提升了应用的用户管理功能。
|