<think>根据要求,我们需要移除滚动指示器动画相关的所有代码,并给整个类加上详细注释。移除的内容包括:1.与滚动指示器相关的成员变量(scrollIndicator,scrollIndicatorAnimator,isIndicatorVisible)2.与滚动监听器相关的成员变量(scrollListener)3.滚动监听器设置(setupScrollListener方法)4.滚动指示器的显示、隐藏和位置更新方法(showScrollIndicator,hideScrollIndicator,updateScrollIndicatorPosition)5.在onCreateView中调用setupScrollListener的代码6.在onDestroyView中移除滚动监听器的代码(注意:移除滚动监听器的代码需要保留,但移除的监听器已经不存在了,所以需要调整)7.滚动监听器的实现(handleScrollChanged方法)同时,我们需要为整个类添加详细的注释,包括类的作用、主要功能、重要方法等。另外,由于移除了滚动指示器,布局中对应的View也应该移除(在布局文件fragment_order_display.xml中移除scroll_indicator视图)。但这里我们只修改Java代码,布局文件修改不在本题要求内。注意:在onDestroyView中,我们之前移除了滚动监听器,现在由于没有设置监听器,所以移除监听器的代码也需要删除。修改步骤:1.删除成员变量:scrollIndicator,scrollIndicatorAnimator,isIndicatorVisible,scrollListener2.删除setupScrollListener方法3.删除handleScrollChanged方法4.删除showScrollIndicator,hideScrollIndicator,updateScrollIndicatorPosition方法5.在onCreateView中,删除调用setupScrollListener的代码6.在onDestroyView中,删除移除滚动监听器的代码(因为已经不再设置监听器)7.在initViews方法中,删除初始化scrollIndicator的代码8.为类和方法添加详细注释同时,我们注意到在initViews方法中初始化scrollIndicator的代码已经被注释掉了,所以直接删除相关代码即可。由于移除了滚动指示器,布局文件中的scroll_indicator视图也应该移除,但题目要求只修改Java代码,所以这里我们只处理Java代码。修改后的代码将不再有滚动指示器相关的功能。下面我们开始修改代码。</think>以下是移除滚动指示器动画并添加详细注释的完整代码:
```java
package com.example.kucun2.ui.dingdan;
import android.app.AlertDialog;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.PopupMenu;
import android.widget.SearchView;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.example.kucun2.MainActivity;
import com.example.kucun2.R;
import com.example.kucun2.View.HorizontalScrollTextView;
import com.example.kucun2.entity.Bancai;
import com.example.kucun2.entity.Chanpin;
import com.example.kucun2.entity.Chanpin_Zujian;
import com.example.kucun2.entity.Dingdan;
import com.example.kucun2.entity.Dingdan_chanpin_zujian;
import com.example.kucun2.entity.Dingdan_Chanpin;
import com.example.kucun2.entity.Zujian;
import com.example.kucun2.entity.data.Data;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 订单展示Fragment - 用于展示订单、产品、组件和板材的四级关系数据
*
* 主要功能:
* 1. 从全局数据源加载订单数据
* 2. 建立订单->产品->组件->板材的四级关系映射
* 3. 提供表格展示数据
* 4. 支持按列排序
* 5. 支持多列搜索过滤
* 6. 提供行操作(查看详情、编辑、删除)
*/
public class OrderDisplayFragment extends Fragment {
//=== 视图组件 ===//
private TableLayout table; // 表格布局,用于显示数据行
private HorizontalScrollView horizontalScrollView; // 水平滚动容器,容纳表格
private SearchView searchView; // 搜索框,用于数据过滤
private Spinner columnSelector; // 列选择器,指定搜索列
private View rootView; // Fragment的根视图
//=== 数据管理 ===//
private List<Object[]> allTableRowsData = new ArrayList<>(); // 所有数据行(未过滤)
private List<Object[]> filteredTableRowsData = new ArrayList<>(); // 过滤后的数据行
private boolean isDataLoaded = false; // 数据加载状态标志
//=== 排序状态 ===//
private int currentSortColumn = -1; // 当前排序列索引(-1表示未排序)
private boolean sortAscending = true; // 排序方向(true为升序)
//=== Fragment生命周期方法 ===//
/**
* 创建Fragment视图
*
* @param inflater 布局填充器
* @param container 父容器
* @param savedInstanceState 保存的状态
* @return 创建的视图
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// 1. 填充布局
rootView = inflater.inflate(R.layout.fragment_order_display, container, false);
// 2. 初始化视图组件
initViews();
// 3. 初始化列选择器
initColumnSelector();
// 4. 设置搜索功能
setupSearchFunctionality();
// 5. 数据加载逻辑
if (Data.dingdans.isEmpty()) {
// 显示加载指示器
showLoadingIndicator();
// 设置数据加载监听器
setupDataLoadListener();
} else {
// 填充表格数据
fillTableData();
isDataLoaded = true;
}
return rootView;
}
/**
* 销毁视图时清理资源
*/
@Override
public void onDestroyView() {
super.onDestroyView();
// 1. 清除视图引用,防止内存泄漏
horizontalScrollView = null;
table = null;
rootView = null;
}
//=== 初始化方法 ===//
/**
* 初始化视图组件
*/
private void initViews() {
// 1. 查找视图组件
table = rootView.findViewById(R.id.orderTable);
horizontalScrollView = rootView.findViewById(R.id.horizontalScrollContainer);
searchView = rootView.findViewById(R.id.search_view);
columnSelector = rootView.findViewById(R.id.column_selector);
// 2. 添加表格表头
addTableHeader(table);
}
/**
* 初始化列选择器(用于指定搜索列)
*/
private void initColumnSelector() {
// 1. 创建适配器(使用资源数组)
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
requireContext(),
R.array.table_headers, // 表头字符串数组资源
android.R.layout.simple_spinner_item
);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// 2. 设置适配器和默认选择
columnSelector.setAdapter(adapter);
columnSelector.setSelection(0); // 默认选择第一项(全部列)
// 3. 设置选择监听器
columnSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// 当列选择变化时应用搜索过滤
applySearchFilter();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// 无操作
}
});
}
/**
* 设置搜索功能
*/
private void setupSearchFunctionality() {
// 设置搜索查询监听器
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// 提交查询时应用过滤
applySearchFilter();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
// 文本变化时实时应用过滤
applySearchFilter();
return true;
}
});
}
//=== 数据加载与处理 ===//
/**
* 填充表格数据 - 核心数据重组逻辑
* 建立订单->产品->组件->板材的四级关系映射
*/
private void fillTableData() {
// 1. 创建映射关系提高查询效率
Map<Integer, List<Dingdan_Chanpin>> orderProductMap = new HashMap<>();
Map<Integer, List<Chanpin_Zujian>> productComponentMap = new HashMap<>();
Map<Integer, List<Dingdan_chanpin_zujian>> componentMaterialMap = new HashMap<>();
// 2. 构建映射关系
// 2.1 订单-产品映射
for (Dingdan_Chanpin op : Data.dingdan_chanpins) {
if (op != null && op.getDingdan() != null) {
orderProductMap.computeIfAbsent(
op.getDingdan().getId(),
k -> new ArrayList<>()
).add(op);
}
}
// 2.2 产品-组件映射
for (Chanpin_Zujian cz : Data.chanpin_zujians) {
if (cz.getChanpin() != null) {
productComponentMap.computeIfAbsent(
cz.getChanpin().getId(),
k -> new ArrayList<>()
).add(cz);
}
}
// 2.3 组件-板材映射
for (Dingdan_chanpin_zujian dm : Data.Dingdan_chanpin_zujians) {
if (dm.getZujian() != null) {
componentMaterialMap.computeIfAbsent(
dm.getZujian().getId(),
k -> new ArrayList<>()
).add(dm);
}
}
// 3. 重组数据(四级关系遍历)
for (Dingdan order : Data.dingdans) {
List<Dingdan_Chanpin> products = orderProductMap.get(order.getId());
if (products != null) {
for (Dingdan_Chanpin op : products) {
Chanpin product = op.getChanpin();
if (product == null) continue;
List<Chanpin_Zujian> components = productComponentMap.get(product.getId());
if (components == null) continue;
for (Chanpin_Zujian cz : components) {
Zujian component = cz.getZujian();
if (component == null) continue;
List<Dingdan_chanpin_zujian> materials = componentMaterialMap.get(component.getId());
if (materials == null) continue;
for (Dingdan_chanpin_zujian dm : materials) {
// 创建行数据并添加到数据集
Object[] rowData = createRowData(order, product, op, cz, dm);
allTableRowsData.add(rowData);
filteredTableRowsData.add(rowData);
}
}
}
}
}
// 4. 初始排序(不指定列,保持原始顺序)
sortTableData(-1, true);
}
/**
* 创建表格行数据对象
*
* @param order 订单对象
* @param product 产品对象
* @param dingdan_chanpin 订单-产品关联对象
* @param component 产品-组件关联对象
* @param material 组件-板材关联对象
* @return 行数据数组
*/
private Object[] createRowData(Dingdan order, Chanpin product, Dingdan_Chanpin dingdan_chanpin,
Chanpin_Zujian component, Dingdan_chanpin_zujian material) {
Bancai board = material.getBancai();
return new Object[]{
order.getNumber(), // 订单号
product.getBianhao(), // 产品编号
dingdan_chanpin.getShuliang(),// 产品数量
component.getZujian().getName(), // 组件名
board != null ? board.TableText() : "N/A", // 板材信息
Math.round(component.getOne_howmany()), // 每组件所需板材数
material.getShuliang(), // 板材订购数量
"操作" // 操作按钮
};
}
//=== 表格操作 ===//
/**
* 排序表格数据
*
* @param columnIndex 列索引(-1表示初始状态)
* @param ascending 是否升序
*/
private void sortTableData(int columnIndex, boolean ascending) {
// 1. 更新排序状态
if (columnIndex >= 0) {
if (currentSortColumn == columnIndex) {
// 同一列点击切换排序方向
sortAscending = !ascending;
} else {
// 不同列点击设为升序
currentSortColumn = columnIndex;
sortAscending = true;
}
}
// 2. 创建自定义比较器
Comparator<Object[]> comparator = (row1, row2) -> {
if (currentSortColumn < 0) return 0; // 不排序
Object val1 = row1[currentSortColumn];
Object val2 = row2[currentSortColumn];
// 2.1 处理空值
if (val1 == null && val2 == null) return 0;
if (val1 == null) return -1;
if (val2 == null) return 1;
try {
// 2.2 数值列比较(第3、6、7列)
if (currentSortColumn == 2 || currentSortColumn == 5 || currentSortColumn == 6) {
double num1 = Double.parseDouble(val1.toString());
double num2 = Double.parseDouble(val2.toString());
return sortAscending ? Double.compare(num1, num2) : Double.compare(num2, num1);
}
// 2.3 字符串列比较
else {
String str1 = val1.toString().toLowerCase();
String str2 = val2.toString().toLowerCase();
return sortAscending ? str1.compareTo(str2) : str2.compareTo(str1);
}
} catch (NumberFormatException e) {
// 2.4 数值解析失败时按字符串比较
String str1 = val1.toString().toLowerCase();
String str2 = val2.toString().toLowerCase();
return sortAscending ? str1.compareTo(str2) : str2.compareTo(str1);
}
};
// 3. 执行排序或直接复制数据
if (columnIndex == -1) {
// 初始状态:复制所有数据
filteredTableRowsData.clear();
filteredTableRowsData.addAll(allTableRowsData);
} else {
// 执行排序
Collections.sort(filteredTableRowsData, comparator);
}
// 4. 刷新表格显示
refreshTableWithData(filteredTableRowsData);
}
/**
* 刷新表格显示
*
* @param dataToShow 要显示的数据集合
*/
private void refreshTableWithData(Iterable<? extends Object[]> dataToShow) {
// 1. 清除旧行(保留表头)
removeAllRowsSafely();
// 2. 添加新行
int addedRows = 0;
for (Object[] rowData : dataToShow) {
addTableRow(rowData);
addedRows++;
}
// 3. 空数据处理
if (addedRows == 0) {
addEmptyTableRow();
}
}
/**
* 添加表格行(动态创建视图)
*
* @param rowData 行数据数组
*/
private void addTableRow(Object[] rowData) {
// 1. 创建行容器
TableRow row = new TableRow(requireContext());
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT
);
row.setLayoutParams(rowParams);
row.setMinimumHeight(dpToPx(36)); // 设置最小高度
// 2. 遍历列数据
for (int i = 0; i < rowData.length; i++) {
if (i == rowData.length - 1) {
// 2.1 操作列(按钮)
Button actionButton = new Button(requireContext());
actionButton.setText("操作");
actionButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
actionButton.setBackgroundResource(R.drawable.btn_selector); // 自定义按钮样式
// 按钮布局参数
TableRow.LayoutParams btnParams = new TableRow.LayoutParams(
0,
TableRow.LayoutParams.WRAP_CONTENT,
0.5f // 权重
);
btnParams.setMargins(dpToPx(1), dpToPx(1), dpToPx(1), dpToPx(1));
actionButton.setLayoutParams(btnParams);
// 设置点击监听
actionButton.setOnClickListener(v -> handleRowAction(rowData, v));
row.addView(actionButton);
} else {
// 2.2 数据列(文本)
HorizontalScrollTextView textView = new HorizontalScrollTextView(requireContext());
textView.setText(String.valueOf(rowData[i]));
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
// 设置内边距
int padding = dpToPx(8);
textView.setPadding(padding, padding/2, padding, padding);
textView.setBackgroundResource(R.drawable.cell_border); // 单元格边框
// 根据内容长度设置权重(长内容占更多空间)
float weight = rowData[i].toString().length() > 10 ? 2.0f : 1.0f;
TableRow.LayoutParams colParams = new TableRow.LayoutParams(
0,
TableRow.LayoutParams.MATCH_PARENT,
weight
);
textView.setLayoutParams(colParams);
row.addView(textView);
}
}
// 3. 将行添加到表格
table.addView(row);
}
//=== 用户交互处理 ===//
/**
* 处理行操作按钮点击
*
* @param rowData 行数据
* @param anchorButton 锚点按钮(用于定位弹出菜单)
*/
private void handleRowAction(Object[] rowData, View anchorButton) {
// 1. 创建弹出菜单
PopupMenu popupMenu = new PopupMenu(requireContext(), anchorButton);
popupMenu.getMenuInflater().inflate(R.menu.row_actions_menu, popupMenu.getMenu());
popupMenu.setGravity(Gravity.BOTTOM); // 菜单显示在下方
// 2. 设置菜单项点击监听
popupMenu.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_view_details) {
// 查看详情
showDetailDialog(rowData[0].toString(), rowData[1].toString());
return true;
} else if (itemId == R.id.action_edit) {
// 编辑行
editRowData(rowData);
return true;
} else if (itemId == R.id.action_delete) {
// 删除行(带确认)
deleteRowWithConfirm(rowData);
return true;
}
return false;
});
// 3. 显示菜单
popupMenu.show();
}
/**
* 删除行数据(带确认对话框)
*
* @param rowData 要删除的行数据
*/
private void deleteRowWithConfirm(Object[] rowData) {
new AlertDialog.Builder(requireContext())
.setTitle("确认删除")
.setMessage("确定要删除订单 " + rowData[0] + " 吗?")
.setPositiveButton("删除", (dialog, which) -> deleteRow(rowData))
.setNegativeButton("取消", null)
.show();
}
/**
* 实际删除逻辑
*
* @param rowData 要删除的行数据
*/
private void deleteRow(Object[] rowData) {
// 1. 从数据集中移除
allTableRowsData.removeIf(row -> Arrays.equals(row, rowData));
filteredTableRowsData.removeIf(row -> Arrays.equals(row, rowData));
// 2. 刷新表格
refreshTableWithData(filteredTableRowsData);
// 3. 显示提示
Toast.makeText(requireContext(), "已删除订单", Toast.LENGTH_SHORT).show();
}
//=== 辅助方法 ===//
/**
* 应用搜索过滤
*/
private void applySearchFilter() {
// 1. 获取搜索查询和选择的列
String query = searchView.getQuery().toString().trim().toLowerCase();
int selectedColumn = columnSelector.getSelectedItemPosition();
// 2. 清空过滤数据集
filteredTableRowsData.clear();
if (query.isEmpty()) {
// 3. 无查询时显示所有数据
filteredTableRowsData.addAll(allTableRowsData);
} else {
// 4. 有查询时过滤数据
for (Object[] row : allTableRowsData) {
if (selectedColumn == 0) {
// 4.1 全局搜索(所有列)
for (Object cell : row) {
if (cell != null && cell.toString().toLowerCase().contains(query)) {
filteredTableRowsData.add(row);
break; // 匹配任一列即可
}
}
} else if (selectedColumn > 0 && selectedColumn <= row.length) {
// 4.2 特定列搜索
int colIndex = selectedColumn - 1; // 调整索引(0是"全部")
if (row[colIndex] != null &&
row[colIndex].toString().toLowerCase().contains(query)) {
filteredTableRowsData.add(row);
}
}
}
}
// 5. 刷新表格显示
refreshTableWithData(filteredTableRowsData);
}
/**
* 添加表格表头
*
* @param table 表格布局
*/
private void addTableHeader(TableLayout table) {
// 1. 创建表头行
TableRow headerRow = new TableRow(requireContext());
headerRow.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT
));
headerRow.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.purple_500)); // 紫色背景
// 2. 获取表头文本和权重
String[] headers = getResources().getStringArray(R.array.table_headers);
float[] weights = {1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 1.0f, 1.0f}; // 各列权重
// 3. 创建表头单元格
for (int i = 0; i < headers.length; i++) {
HorizontalScrollTextView headerView = new HorizontalScrollTextView(requireContext());
headerView.setText(headers[i]);
headerView.setTextColor(Color.WHITE); // 白色文字
headerView.setTypeface(null, Typeface.BOLD); // 粗体
headerView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
headerView.setPadding(dpToPx(8), dpToPx(8), dpToPx(8), dpToPx(8)); // 内边距
// 单元格布局参数
TableRow.LayoutParams colParams = new TableRow.LayoutParams(
0,
TableRow.LayoutParams.MATCH_PARENT,
weights[i] // 使用预定义权重
);
headerView.setLayoutParams(colParams);
// 设置点击排序监听
final int columnIndex = i;
headerView.setOnClickListener(v -> sortTableData(columnIndex, sortAscending));
headerRow.addView(headerView);
}
// 4. 将表头行添加到表格
table.addView(headerRow);
}
/**
* 安全移除所有数据行(保留表头)
*/
private void removeAllRowsSafely() {
// 确保至少保留表头行
if (table.getChildCount() > 1) {
// 从后向前移除(避免索引变化问题)
for (int i = table.getChildCount() - 1; i >= 1; i--) {
View child = table.getChildAt(i);
if (child instanceof TableRow) {
// 清理行内视图资源
cleanupRowViews((TableRow) child);
}
table.removeViewAt(i);
}
}
}
/**
* 清理行视图资源
*
* @param row 表格行
*/
private void cleanupRowViews(TableRow row) {
for (int i = 0; i < row.getChildCount(); i++) {
View view = row.getChildAt(i);
if (view instanceof Button) {
// 清除按钮点击监听
((Button) view).setOnClickListener(null);
}
}
}
/**
* 添加空数据提示行
*/
private void addEmptyTableRow() {
TableRow row = new TableRow(requireContext());
TextView emptyView = new TextView(requireContext());
emptyView.setText("暂无数据");
emptyView.setGravity(Gravity.CENTER);
emptyView.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT
));
row.addView(emptyView);
table.addView(row);
}
/**
* 显示详情对话框
*
* @param orderNumber 订单号
* @param productId 产品ID
*/
private void showDetailDialog(String orderNumber, String productId) {
new AlertDialog.Builder(requireContext())
.setTitle("订单详情")
.setMessage("订单号: " + orderNumber + "\n产品ID: " + productId)
.setPositiveButton("确定", null)
.show();
}
/**
* 编辑行数据
*
* @param rowData 行数据
*/
private void editRowData(Object[] rowData) {
// 实际项目中应实现编辑表单
Toast.makeText(requireContext(), "编辑: " + rowData[0], Toast.LENGTH_SHORT).show();
}
/**
* 显示加载指示器
*/
private void showLoadingIndicator() {
// 实际项目中应显示进度条
Toast.makeText(requireContext(), "加载中...", Toast.LENGTH_SHORT).show();
}
/**
* 设置数据加载监听器
*/
private void setupDataLoadListener() {
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).setOnDataLoadListener(new MainActivity.OnDataLoadListener() {
@Override
public void onDataLoaded() {
// 在主线程更新UI
requireActivity().runOnUiThread(() -> {
hideLoadingIndicator();
isDataLoaded = true;
fillTableData();
});
}
@Override
public void onDataError() {
requireActivity().runOnUiThread(() -> {
hideLoadingIndicator();
Toast.makeText(getContext(), "数据加载失败", Toast.LENGTH_SHORT).show();
});
}
});
}
}
/**
* 隐藏加载指示器
*/
private void hideLoadingIndicator() {
// 实际项目中应隐藏进度条
}
/**
* dp转px工具方法
*
* @param dp 设备无关像素值
* @return 像素值
*/
private int dpToPx(int dp) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
getResources().getDisplayMetrics()
);
}
}
```
### 主要修改说明:
1. **移除了所有滚动指示器相关代码**:
- 删除了 `scrollIndicator` 视图引用
- 移除了 `scrollIndicatorAnimator` 和 `isIndicatorVisible` 变量
- 移除了 `setupScrollListener()` 方法
- 删除了 `showScrollIndicator()`、`hideScrollIndicator()` 和 `updateScrollIndicatorPosition()` 方法
- 在 `onDestroyView()` 中移除了滚动监听器清理代码
2. **添加了详细注释**:
- 类级注释:描述整个 Fragment 的功能和作用
- 方法级注释:每个方法都有详细的功能说明
- 关键代码块注释:解释复杂逻辑的实现
- 变量注释:说明重要变量的用途
3. **优化了代码结构**:
- 使用空行分隔不同功能块
- 保持一致的代码风格和命名规范
- 简化了部分条件判断逻辑
4. **保留了核心功能**:
- 四级数据关系映射(订单->产品->组件->板材)
- 表格动态生成与刷新
- 多列排序功能
- 全局/列过滤搜索
- 行操作功能(查看、编辑、删除)
### 最佳实践建议:
1. **数据加载优化**:
```java
// 使用异步任务加载数据
private void loadDataAsync() {
new AsyncTask<Void, Void, List<Object[]>>() {
@Override
protected List<Object[]> doInBackground(Void... voids) {
// 后台执行数据重组
return prepareTableData();
}
@Override
protected void onPostExecute(List<Object[]> result) {
allTableRowsData = result;
applySearchFilter(); // 应用当前过滤条件
}
}.execute();
}
```
2. **表格性能优化**:
```java
// 使用ViewHolder模式优化表格行
private static class TableRowViewHolder {
HorizontalScrollTextView[] textViews;
Button actionButton;
}
// 在addTableRow中使用复用机制
if (convertView == null) {
// 创建新行和ViewHolder
} else {
// 复用已有行
}
```
3. **分页加载**:
```java
// 实现分页逻辑
private int currentPage = 0;
private static final int PAGE_SIZE = 50;
private void loadNextPage() {
int start = currentPage * PAGE_SIZE;
int end = Math.min(start + PAGE_SIZE, filteredTableRowsData.size());
for (int i = start; i < end; i++) {
addTableRow(filteredTableRowsData.get(i));
}
currentPage++;
}
```
4. **数据变更通知**:
```java
// 使用观察者模式通知数据变化
public interface DataChangeListener {
void onDataChanged();
}
// 在数据变更时通知监听器
private void notifyDataChanged() {
for (DataChangeListener listener : listeners) {
listener.onDataChanged();
}
}
```