来帮你设计黑名单功能。首先修改adapter添加菜单处理逻辑:
typescript
package com.tplink.trainingapp.clients.view;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.tplink.apps.architecture.BaseMvvmActivity;
import com.tplink.design.dialog.TPModalBottomSheet;
import com.tplink.design.menu.TPPopupMenu;
import com.tplink.trainingapp.R;
import com.tplink.trainingapp.clients.adapter.BlacklistAdapter;
import com.tplink.trainingapp.clients.viewmodel.ClientViewModel;
import com.tplink.trainingapp.databinding.ActivityBlacklistBinding;
public class BlacklistActivity extends BaseMvvmActivity<ActivityBlacklistBinding>
implements BlacklistAdapter.OnDeviceActionListener {
private ClientViewModel viewModel;
private BlacklistAdapter adapter;
@Nullable
@Override
protected ActivityBlacklistBinding bindContentView(@Nullable Bundle bundle) {
return ActivityBlacklistBinding.inflate(getLayoutInflater());
}
@Override
protected void subscribeViewModel(@Nullable Bundle bundle) {
viewModel = new ViewModelProvider(this).get(ClientViewModel.class);
setupToolbar();
setupRecyclerView();
observeViewModel();
}
private void setupToolbar() {
viewBinding.toolbar.setTitle("黑名单");
viewBinding.toolbar.setNavigationOnClickListener(view -> {
onBackPressed();
});
// 设置支持菜单
setSupportActionBar(viewBinding.toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.blacklist_toolbar_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.menu_add) {
showAddDeviceMenu();
return true;
}
return super.onOptionsItemSelected(item);
}
private void showAddDeviceMenu() {
View anchorView = findViewById(R.id.menu_add);
if (anchorView == null) {
anchorView = viewBinding.toolbar;
}
TPPopupMenu popupMenu = new TPPopupMenu(this, anchorView, R.menu.add_device_menu)
.setIconEnable(true);
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.menu_add_by_user) {
// TODO: 实现选择用户端功能
return true;
} else if (item.getItemId() == R.id.menu_add_by_mac) {
showAddByMacModal();
return true;
}
return false;
});
popupMenu.show();
}
private void showAddByMacModal() {
new TPModalBottomSheet.Builder()
.setScreenType(TPModalBottomSheet.ScreenType.FULL_SCREEN)
.setDividerEnable(false)
.setTitle("Add by MAC Address")
.setEndOptionText("Save")
.setContentLayoutId(R.layout.fragment_blacklist)
.setContentViewListener(new TPModalBottomSheet.OnModalContentViewListener() {
@Override
public void onContentViewCreated(TPModalBottomSheet tpModalBottomSheet, View view) {
EditText macInput = view.findViewById(R.id.et_mac_address);
tpModalBottomSheet.setEndOptionClickListener(new TPModalBottomSheet.OnEndOptionClickListener() {
@Override
public void onEndOptionClick(TPModalBottomSheet modalBottomSheet) {
String macAddress = macInput.getText().toString().trim();
if (!macAddress.isEmpty()) {
viewModel.blockDeviceByMac(macAddress);
modalBottomSheet.dismiss();
}
}
});
}
})
.show(getSupportFragmentManager(), "tp");
}
private void setupRecyclerView() {
adapter = new BlacklistAdapter(this);
adapter.setOnDeviceActionListener(this);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
viewBinding.recyclerView.setAdapter(adapter);
}
private void observeViewModel() {
viewModel.getBlacklistItems().observe(this, items -> {
if (items == null || items.isEmpty()) {
showEmptyView();
} else {
showDeviceList();
adapter.updateItems(items);
}
});
}
private void showEmptyView() {
viewBinding.recyclerView.setVisibility(View.GONE);
viewBinding.emptyLayout.setVisibility(View.VISIBLE);
viewBinding.emptyImage.setImageResource(R.drawable.ic_empty_device);
viewBinding.emptyText.setText("没有设备记录");
}
private void showDeviceList() {
viewBinding.recyclerView.setVisibility(View.VISIBLE);
viewBinding.emptyLayout.setVisibility(View.GONE);
}
@Override
public void onUnblockDevice(String identifier, int position) {
viewModel.unblockDevice(identifier);
}
@Override
public void onDeleteDevice(String identifier, int position) {
viewModel.deleteBlacklistDevice(identifier);
}
}
java
package com.tplink.trainingapp.clients.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.tplink.design.list.TPSingleLineItemView;
import com.tplink.design.list.TPSingleLineItemViewHolder;
import com.tplink.design.list.TPTwoLineItemView;
import com.tplink.design.list.TPTwoLineItemViewHolder;
import com.tplink.design.menu.TPPopupMenu;
import com.tplink.trainingapp.R;
import com.tplink.trainingapp.clients.viewmodel.ClientViewModel;
import java.util.ArrayList;
import java.util.List;
public class BlacklistAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_DEVICE = 0; // 设备名称+MAC类型
private static final int TYPE_MAC_ONLY = 1; // 纯MAC地址类型
private List<ClientViewModel.BlacklistItem> blacklistItems;
private Context context;
private OnDeviceActionListener listener;
// 操作监听接口
public interface OnDeviceActionListener {
void onUnblockDevice(String identifier, int position);
void onDeleteDevice(String identifier, int position);
}
public BlacklistAdapter(Context context) {
this.context = context;
this.blacklistItems = new ArrayList<>();
}
public void setOnDeviceActionListener(OnDeviceActionListener listener) {
this.listener = listener;
}
public void updateItems(List<ClientViewModel.BlacklistItem> items) {
this.blacklistItems.clear();
this.blacklistItems.addAll(items);
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
ClientViewModel.BlacklistItem item = blacklistItems.get(position);
return item.isMacOnly() ? TYPE_MAC_ONLY : TYPE_DEVICE;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == TYPE_MAC_ONLY) {
return TPSingleLineItemViewHolder.create(parent);
} else {
return TPTwoLineItemViewHolder.create(parent);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ClientViewModel.BlacklistItem item = blacklistItems.get(position);
if (getItemViewType(position) == TYPE_MAC_ONLY) {
// 纯MAC地址显示
bindMacOnlyItem((TPSingleLineItemViewHolder) holder, item, position);
} else {
// 设备名称+MAC显示
bindDeviceItem((TPTwoLineItemViewHolder) holder, item, position);
}
}
private void bindMacOnlyItem(TPSingleLineItemViewHolder holder, ClientViewModel.BlacklistItem item, int position) {
TPSingleLineItemView lineItem = (TPSingleLineItemView) holder.itemView;
// 设置图标(根据MAC地址显示通用设备图标)
lineItem.setStartIcon(R.mipmap.icon_laptop); // 可以用一个通用图标
// 设置图标尺寸
ViewGroup.LayoutParams layoutParams = lineItem.getStartIcon().getLayoutParams();
int iconSize = (int) context.getResources().getDimension(com.tplink.design.R.dimen.tpds_all_dp_40);
layoutParams.width = iconSize;
layoutParams.height = iconSize;
lineItem.getStartIcon().setLayoutParams(layoutParams);
lineItem.setTitleText(item.getMacAddress());
lineItem.setEndIcon(R.drawable.ic_blocked);
lineItem.showDivider(true);
setupLongClickListener(lineItem, item.getIdentifier(), position);
}
private void bindDeviceItem(TPTwoLineItemViewHolder holder, ClientViewModel.BlacklistItem item, int position) {
TPTwoLineItemView lineItem = (TPTwoLineItemView) holder.itemView;
// 设置设备图标 - 根据设备名称判断类型
if (item.getDisplayName().toLowerCase().contains("iphone") ||
item.getDisplayName().toLowerCase().contains("phone") ||
item.getDisplayName().toLowerCase().contains("mobile")) {
lineItem.setStartIcon(R.mipmap.icon_games);
} else {
lineItem.setStartIcon(R.mipmap.icon_laptop);
}
// 设置图标尺寸
ViewGroup.LayoutParams layoutParams = lineItem.getStartIcon().getLayoutParams();
int iconSize = (int) context.getResources().getDimension(com.tplink.design.R.dimen.tpds_all_dp_40);
layoutParams.width = iconSize;
layoutParams.height = iconSize;
lineItem.getStartIcon().setLayoutParams(layoutParams);
lineItem.setTitleText(item.getDisplayName());
// 显示MAC地址
String macText = "MAC: " + item.getMacAddress();
lineItem.setContentText(macText);
// 设置禁用图标
lineItem.setEndIcon(R.drawable.ic_blocked);
lineItem.showDivider(true);
setupLongClickListener(lineItem, item.getIdentifier(), position);
}
private void setupLongClickListener(View itemView, String identifier, int position) {
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
TPPopupMenu popupMenu = new TPPopupMenu(context, v, R.menu.blacklist_menu)
.setIconEnable(true);
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.menu_unblock) {
showUnblockConfirmDialog(identifier, position);
return true;
} else if (item.getItemId() == R.id.menu_delete) {
showDeleteConfirmDialog(identifier, position);
return true;
}
return false;
});
popupMenu.show();
return true;
}
});
}
@Override
public int getItemCount() {
return blacklistItems.size();
}
// 显示解除拉黑确认对话框
private void showUnblockConfirmDialog(String identifier, int position) {
new androidx.appcompat.app.AlertDialog.Builder(context)
.setTitle("解除拉黑")
.setMessage("确定要将 \"" + identifier + "\" 从黑名单中移除吗?")
.setPositiveButton("确定", (dialog, which) -> {
if (listener != null) {
listener.onUnblockDevice(identifier, position);
}
})
.setNegativeButton("取消", null)
.show();
}
// 显示删除确认对话框
private void showDeleteConfirmDialog(String identifier, int position) {
new androidx.appcompat.app.AlertDialog.Builder(context)
.setTitle("删除设备")
.setMessage("确定要永久删除 \"" + identifier + "\" 吗?")
.setPositiveButton("确定", (dialog, which) -> {
if (listener != null) {
listener.onDeleteDevice(identifier, position);
}
})
.setNegativeButton("取消", null)
.show();
}
}
typescript
package com.tplink.trainingapp.clients.viewmodel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.ArrayList;
import java.util.List;
public class ClientViewModel extends ViewModel {
// 黑名单项目类型
public static class BlacklistItem {
private String displayName;
private String macAddress;
private boolean isMacOnly; // 是否只是MAC地址
// 构造函数 - 设备名称+MAC
public BlacklistItem(String deviceName, String macAddress) {
this.displayName = deviceName;
this.macAddress = macAddress;
this.isMacOnly = false;
}
// 构造函数 - 纯MAC地址
public BlacklistItem(String macAddress) {
this.displayName = macAddress;
this.macAddress = macAddress;
this.isMacOnly = true;
}
// Getters
public String getDisplayName() { return displayName; }
public String getMacAddress() { return macAddress; }
public boolean isMacOnly() { return isMacOnly; }
public String getIdentifier() {
return isMacOnly ? macAddress : displayName;
}
}
// 主网络在线设备数量
private MutableLiveData<Integer> mainOnlineCount = new MutableLiveData<>(4);
// 主网络离线设备数量
private MutableLiveData<Integer> mainOfflineCount = new MutableLiveData<>(3);
// 访客网络设备数量
private MutableLiveData<Integer> guestCount = new MutableLiveData<>(1);
// 刷新状态
private MutableLiveData<Boolean> isRefreshing = new MutableLiveData<>(false);
// 黑名单项目
private MutableLiveData<List<BlacklistItem>> blacklistItems = new MutableLiveData<>(new ArrayList<>());
// 获取主网络在线设备数量
public LiveData<Integer> getMainOnlineCount() {
return mainOnlineCount;
}
// 获取主网络离线设备数量
public LiveData<Integer> getMainOfflineCount() {
return mainOfflineCount;
}
// 获取访客网络设备数量
public LiveData<Integer> getGuestCount() {
return guestCount;
}
// 获取刷新状态
public LiveData<Boolean> getRefreshingState() {
return isRefreshing;
}
// 获取黑名单项目
public LiveData<List<BlacklistItem>> getBlacklistItems() {
return blacklistItems;
}
// 刷新数据
public void refreshData() {
isRefreshing.setValue(true);
// 模拟网络请求延时
new android.os.Handler().postDelayed(new Runnable() {
@Override
public void run() {
mainOnlineCount.setValue((int) (Math.random() * 5) + 1);
mainOfflineCount.setValue((int) (Math.random() * 4) + 1);
guestCount.setValue((int) (Math.random() * 3) + 1);
isRefreshing.setValue(false);
}
}, 1500);
}
// 拉黑设备(设备名称)
public void blockDevice(String deviceName) {
List<BlacklistItem> currentList = blacklistItems.getValue();
if (currentList == null) {
currentList = new ArrayList<>();
}
// 检查是否已存在
boolean exists = currentList.stream()
.anyMatch(item -> item.getIdentifier().equals(deviceName));
if (!exists) {
List<BlacklistItem> newList = new ArrayList<>(currentList);
newList.add(new BlacklistItem(deviceName, "99-99-99-99-99-99")); // 模拟MAC
blacklistItems.setValue(newList);
}
}
// 通过MAC地址拉黑
public void blockDeviceByMac(String macAddress) {
List<BlacklistItem> currentList = blacklistItems.getValue();
if (currentList == null) {
currentList = new ArrayList<>();
}
// 检查是否已存在
boolean exists = currentList.stream()
.anyMatch(item -> item.getMacAddress().equals(macAddress));
if (!exists) {
List<BlacklistItem> newList = new ArrayList<>(currentList);
newList.add(new BlacklistItem(macAddress)); // 纯MAC地址项目
blacklistItems.setValue(newList);
}
}
// 解除拉黑
public void unblockDevice(String identifier) {
List<BlacklistItem> currentList = blacklistItems.getValue();
if (currentList != null) {
List<BlacklistItem> newList = new ArrayList<>();
for (BlacklistItem item : currentList) {
if (!item.getIdentifier().equals(identifier)) {
newList.add(item);
}
}
blacklistItems.setValue(newList);
}
}
// 删除黑名单设备
public void deleteBlacklistDevice(String identifier) {
unblockDevice(identifier); // 删除就是从黑名单中移除
}
// 更新主网络在线设备数量
public void updateMainOnlineCount(int count) {
mainOnlineCount.setValue(count);
}
// 更新主网络离线设备数量
public void updateMainOfflineCount(int count) {
mainOfflineCount.setValue(count);
}
// 更新访客网络设备数量
public void updateGuestCount(int count) {
guestCount.setValue(count);
}
// 获取当前主网络在线设备数量的值
public int getCurrentMainOnlineCount() {
Integer count = mainOnlineCount.getValue();
return count != null ? count : 0;
}
// 获取当前主网络离线设备数量的值
public int getCurrentMainOfflineCount() {
Integer count = mainOfflineCount.getValue();
return count != null ? count : 0;
}
// 获取当前访客网络设备数量的值
public int getCurrentGuestCount() {
Integer count = guestCount.getValue();
return count != null ? count : 0;
}
}
ini
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/toolbar_icon_back"
app:navigationIconTint="?attr/colorOnBackground"
app:title="黑名单"
app:titleCentered="true"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 空状态布局 -->
<LinearLayout
android:id="@+id/emptyLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<ImageView
android:id="@+id/emptyImage"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginBottom="16dp"
android:alpha="0.6"
tools:src="@drawable/ic_empty_device" />
<TextView
android:id="@+id/emptyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="没有设备记录"
android:textColor="?attr/colorOnSurface"
android:textSize="16sp"
android:alpha="0.6" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
🎯 功能概述
实现了完整的设备黑名单管理功能,包括:
- 设备列表长按显示拉黑/删除菜单
- 拉黑/删除前显示确认对话框
- 黑名单页面管理已拉黑设备
- 支持解除拉黑和删除操作
- 空状态显示
📁 已创建的文件
1. ClientListAdapter.java (已修改)
- 添加了设备操作监听接口
OnDeviceActionListener
- 实现长按菜单处理(在线设备:拉黑,离线设备:拉黑+删除)
- 添加确认对话框
showBlockConfirmDialog()
和showDeleteConfirmDialog()
2. BlacklistActivity.java (新建)
- 黑名单管理页面
- 空状态和设备列表状态切换
- 实现设备操作接口处理解除拉黑和删除
3. BlacklistAdapter.java (新建)
- 黑名单设备列表适配器
- 支持长按菜单(解除拉黑、删除)
- 确认对话框处理
4. ClientViewModel.java (已修改)
- 添加黑名单数据管理
blockDevice()
- 拉黑设备unblockDevice()
- 解除拉黑deleteBlacklistDevice()
- 删除黑名单设备
5. ClientPageActivity.java (已修改)
- 添加工具栏菜单支持
- 实现黑名单页面跳转
6. ClientMainFragment.java (已修改)
- 实现设备操作接口
- 处理拉黑和删除操作反馈
7. activity_blacklist.xml (新建)
- 黑名单页面布局
- 包含RecyclerView和空状态布局
🎨 需要的资源文件
菜单文件 (res/menu/)
xml
<!-- clients_online_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_block"
android:title="拉黑"
android:icon="@drawable/ic_block" />
</menu>
<!-- clients_offline_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_block"
android:title="拉黑"
android:icon="@drawable/ic_block" />
<item
android:id="@+id/menu_delete"
android:title="删除"
android:icon="@drawable/ic_delete" />
</menu>
<!-- blacklist_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_unblock"
android:title="解除拉黑"
android:icon="@drawable/ic_unblock" />
<item
android:id="@+id/menu_delete"
android:title="删除"
android:icon="@drawable/ic_delete" />
</menu>
<!-- device_update_toolbar_menu.xml (修改) -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_blacklist"
android:title="黑名单"
android:icon="@drawable/ic_blacklist"
android:showAsAction="always" />
</menu>
图标资源 (res/drawable/)
ic_block.xml
- 拉黑图标ic_unblock.xml
- 解除拉黑图标ic_delete.xml
- 删除图标ic_blacklist.xml
- 黑名单图标ic_blocked.xml
- 已被拉黑状态图标ic_empty_device.xml
- 空设备状态图标toolbar_icon_back.xml
- 返回图标
🔄 工作流程
-
设备列表操作
- 用户长按设备 → 显示菜单
- 点击"拉黑"/"删除" → 显示确认对话框
- 确认后 → 调用ViewModel方法更新数据
-
黑名单管理
- 主页面工具栏点击黑名单图标 → 跳转黑名单页面
- 黑名单为空 → 显示空状态图片和提示
- 黑名单有设备 → 显示设备列表
- 长按黑名单设备 → 解除拉黑/删除菜单
-
数据状态管理
- 所有数据通过
ClientViewModel
的LiveData管理 - 支持Activity和Fragment之间数据共享
- 自动响应数据变化更新UI
- 所有数据通过
🎯 使用方法
- 将所有文件添加到对应目录
- 创建所需的菜单和图标资源
- 在AndroidManifest.xml中注册BlacklistActivity
- 确保string资源包含必要的文本
xml
<!-- AndroidManifest.xml -->
<activity
android:name=".clients.view.BlacklistActivity"
android:label="黑名单"
android:parentActivityName=".clients.view.ClientPageActivity" />
现在你有了一个完整的黑名单功能实现! 🎉��已经为你完整设计了黑名单功能!主要实现了:
✨ 核心功能
- 长按菜单 - 在线设备显示"拉黑",离线设备显示"拉黑+删除"
- 确认对话框 - 所有操作前都有确认提示
- 黑名单页面 - 专门管理已拉黑设备,支持解除拉黑和删除
- 空状态显示 - 没有设备时显示图片和提示文字
- 数据同步 - 通过ViewModel在Activity和Fragment间共享数据
🔧 实现架构
- ClientListAdapter - 添加了设备操作接口和确认对话框
- BlacklistActivity + BlacklistAdapter - 完整的黑名单管理
- ClientViewModel - 统一的数据状态管理
- activity_blacklist.xml - 黑名单页面布局
📋 你还需要准备的资源:
菜单文件 (res/menu/):
clients_online_menu.xml
(包含拉黑选项)clients_offline_menu.xml
(包含拉黑+删除选项)blacklist_menu.xml
(包含解除拉黑+删除选项)- 修改
device_update_toolbar_menu.xml
(添加黑名单图标)
图标资源 (res/drawable/):
- 各种操作图标 (拉黑、删除、黑名单等)
- 空设备状态图标
在AndroidManifest.xml注册BlacklistActivity
现在你的黑名单功能已经完整实现了!用户可以长按设备进行拉黑/删除,点击工具栏进入黑名单管理,所有操作都有确认提示和反馈。🎉
你的需求,需要修改以下几个地方:
1. BlacklistActivity 修改
2. ClientViewModel 修改 - 支持MAC地址管理
3. BlacklistAdapter 修改 - 支持不同类型显示
4. 需要创建的菜单XML文件
ini
<item
android:id="@+id/menu_add"
android:title="添加"
android:icon="@drawable/ic_add"
app:showAsAction="always" />
ini
<item
android:id="@+id/menu_add_by_user"
android:title="选择用户端"
android:icon="@drawable/ic_device" />
<item
android:id="@+id/menu_add_by_mac"
android:title="通过MAC位新增"
android:icon="@drawable/ic_mac_address" />
5. 总结需要修改的主要逻辑
主要修改点总结:
- BlacklistActivity - 添加工具栏菜单,处理添加设备的弹窗逻辑
- ClientViewModel - 创建BlacklistItem内部类,支持两种类型的黑名单项目
- BlacklistAdapter - 使用ViewType区分显示,支持TPSingleLineItemView和TPTwoLineItemView
- 菜单文件 - 创建工具栏菜单和弹出菜单XML
关键实现逻辑:
- BlacklistItem类:区分普通设备(显示设备名+MAC)和纯MAC地址(只显示MAC)
- ViewType机制:adapter根据item类型返回不同的ViewHolder
- TPModalBottomSheet:全屏模态面板处理MAC地址输入
- 数据流 :输入的MAC地址通过
blockDeviceByMac()
方法添加到黑名单
注意点:
- 纯MAC地址项目使用TPSingleLineItemView显示
- 普通设备项目使用TPTwoLineItemView显示设备名和MAC地址
- 需要创建fragment_blacklist.xml布局文件(包含TextView和EditText)
- 需要添加相关图标资源(ic_add, ic_device, ic_mac_address等)
这样就完成了黑名单功能的MAC地址添加支持,用户可以通过右上角菜单添加纯MAC地址到黑名单中。