package com.example.kucun2.ui.dingdan;//package com.example.kucun2;
import static android.content.ContentValues.TAG;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
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.annotation.NonNull;
import androidx.annotation.Nullable;
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.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.Iterator;
import java.util.List;
import java.util.Map;
public class OrderDisplayFragment extends Fragment {
private TableLayout table;
private HorizontalScrollView horizontalScrollView;
private ValueAnimator scrollIndicatorAnimator;
private boolean isIndicatorVisible = false;
// 添加排序相关的成员变量
private int currentSortColumn = -1;
private boolean sortAscending = true;
private List<Object[]> allTableRowsData = new ArrayList<>();
// 添加搜索相关成员变量
private SearchView searchView;
private Spinner columnSelector;
private List<Object[]> filteredTableRowsData = new ArrayList<>();
private boolean isDataLoaded = false;
// 添加成员变量保存关键视图引用
private View scrollIndicator;
private View rootView; // 保存根视图引用
// 添加滚动监听器的引用
private final ViewTreeObserver.OnScrollChangedListener scrollListener =
new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// 关键修复:添加全面的空值检查
if (horizontalScrollView == null ||
!isAdded() ||
horizontalScrollView.getChildCount() == 0) {
return;
}
View child = horizontalScrollView.getChildAt(0);
if (child == null) return;
int maxScroll = child.getWidth() - horizontalScrollView.getWidth();
int currentScroll = horizontalScrollView.getScrollX();
if (currentScroll > 0 && maxScroll > 0) {
if (!isIndicatorVisible) {
showScrollIndicator();
}
updateScrollIndicatorPosition(currentScroll, maxScroll);
} else {
hideScrollIndicator();
}
}
};
/**
* 加载初始化
*
* @param inflater The LayoutInflater object that can be used to inflate
* any views in the fragment,
* @param container If non-null, this is the parent view that the fragment's
* UI should be attached to. The fragment should not add the view itself,
* but this can be used to generate the LayoutParams of the view.
* @param savedInstanceState If non-null, this fragment is being re-constructed
* from a previous saved state as given here.
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_order_display, container, false);
table = rootView.findViewById(R.id.orderTable);
horizontalScrollView = rootView.findViewById(R.id.horizontalScrollContainer);
scrollIndicator = rootView.findViewById(R.id.scroll_indicator);
// 获取搜索控件
searchView = rootView.findViewById(R.id.search_view);
columnSelector = rootView.findViewById(R.id.column_selector);
table = rootView.findViewById(R.id.orderTable);
horizontalScrollView = rootView.findViewById(R.id.horizontalScrollContainer);
scrollIndicator = rootView.findViewById(R.id.scroll_indicator);
// 初始化表头选择器
initColumnSelector();
// 设置搜索监听
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
applySearchFilter();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
applySearchFilter();
return true;
}
});
LinearLayout fixedSearchBar = rootView.findViewById(R.id.fixedSearchBar);
View placeholder = rootView.findViewById(R.id.search_bar_placeholder);
// 添加全局布局监听器以获取正确的搜索框高度
fixedSearchBar.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 获取搜索框的实际高度
int searchBarHeight = fixedSearchBar.getHeight();
// 设置占位视图的高度
ViewGroup.LayoutParams params = placeholder.getLayoutParams();
params.height = searchBarHeight;
placeholder.setLayoutParams(params);
// 确保仅运行一次
fixedSearchBar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
);
Log.d(TAG, "onCreateView: " + Data.dingdans.get(0).getNumber());
// 添加表头
addTableHeader(table);
// 检查数据是否已加载
if (Data.dingdans.isEmpty()) {
// 显示加载指示器
showLoadingIndicator();
// 设置数据加载监听器
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).setOnDataLoadListener(new MainActivity.OnDataLoadListener() {
@Override
public void onDataLoaded() {
requireActivity().runOnUiThread(() -> {
hideLoadingIndicator();
isDataLoaded = true;
fillTableData(); // 填充数据
});
}
@Override
public void onDataError() {
requireActivity().runOnUiThread(() -> {
hideLoadingIndicator();
Toast.makeText(getContext(), "检查网络", Toast.LENGTH_SHORT).show();
//showError("数据加载失败");
});
}
});
}
} else {
// 数据已加载,直接填充
fillTableData();
isDataLoaded = true;
}
// 填充表格数据
// fillTableData();
// 添加滚动监听
horizontalScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
// 添加安全检查和空值防护
if (horizontalScrollView == null ||
horizontalScrollView.getChildCount() == 0 ||
getView() == null) {
return;
}
View child = horizontalScrollView.getChildAt(0);
if (child == null) return;
int maxScroll = child.getWidth() - horizontalScrollView.getWidth();
int currentScroll = horizontalScrollView.getScrollX();
if (currentScroll > 0 && maxScroll > 0) {
if (!isIndicatorVisible) {
showScrollIndicator();
}
updateScrollIndicatorPosition(currentScroll, maxScroll);
} else {
hideScrollIndicator();
}
});
return rootView;
}
// 显示/隐藏加载指示器的方法
private void showLoadingIndicator() {
// 实现加载动画或进度条
}
private void hideLoadingIndicator() {
if (scrollIndicator == null || !isAdded()) return;
isIndicatorVisible = false;
View indicator = this.scrollIndicator; // 使用成员变量
// 隐藏加载指示器
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (horizontalScrollView != null) {
ViewTreeObserver observer = horizontalScrollView.getViewTreeObserver();
if (observer.isAlive()) {
observer.removeOnScrollChangedListener(scrollChangedListener);
}
horizontalScrollView = null;
}
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof MainActivity) {
((MainActivity) context).setOnDataLoadListener(new MainActivity.OnDataLoadListener() {
@Override
public void onDataLoaded() {
// 数据加载完成后填充表格
getActivity().runOnUiThread(() -> {
Log.d("DataLoad", "Data loaded, filling table");
fillTableData();
});
}
@Override
public void onDataError() {
//showToast("数据加载失败");
}
});
}
}
/**
* 获取数据
*/
private void fillTableData() {
List<Dingdan> orders = Data.dingdans;
List<Dingdan_Chanpin> orderProducts = Data.dingdan_chanpins;
List<Dingdan_chanpin_zujian> orderMaterials = Data.Dingdan_chanpin_zujians;
allTableRowsData.clear();
filteredTableRowsData.clear();
// 创建映射关系提高效率
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<>();
// 构建映射
for (Dingdan_Chanpin op : orderProducts) {
if (op != null && op.getDingdan() != null) {
int orderId = op.getDingdan().getId();
orderProductMap.computeIfAbsent(orderId, k -> new ArrayList<>()).add(op);
}
}
for (Chanpin_Zujian cz : Data.chanpin_zujians) {
int productId = cz.getChanpin().getId();
productComponentMap.computeIfAbsent(productId, k -> new ArrayList<>()).add(cz);
}
for (Dingdan_chanpin_zujian dm : orderMaterials) {
int componentId = dm.getZujian().getId();
componentMaterialMap.computeIfAbsent(componentId, k -> new ArrayList<>()).add(dm);
}
// 重组数据
for (Dingdan order : orders) {
List<Dingdan_Chanpin> productsForOrder = orderProductMap.get(order.getId());
if (productsForOrder != null) {
for (Dingdan_Chanpin op : productsForOrder) {
Chanpin product = op.getChanpin();
List<Chanpin_Zujian> componentsForProduct = productComponentMap.get(product.getId());
if (componentsForProduct != null) {
for (Chanpin_Zujian cz : componentsForProduct) {
List<Dingdan_chanpin_zujian> materialsForComponent = componentMaterialMap.get(cz.getZujian().getId());
if (materialsForComponent != null) {
for (Dingdan_chanpin_zujian dm : materialsForComponent) {
Object[] rowData = createRowData(order, product, op, cz, dm);
allTableRowsData.add(rowData);
filteredTableRowsData.add(rowData);
}
}
}
}
}
}
}
// 日志记录添加行数
Log.d("TableFill", "Total rows created: " + allTableRowsData.size());
// 初始排序
sortTableData(-1, true);
}
/**
* 排序表格数据并刷新显示
*
* @param columnIndex 要排序的列索引
* @param ascending 是否升序排列
*/
private void sortTableData(int columnIndex, boolean ascending) {
// 更新排序状态
if (columnIndex >= 0) {
if (currentSortColumn == columnIndex) {
// 相同列点击时切换排序方向
sortAscending = !ascending;
} else {
currentSortColumn = columnIndex;
sortAscending = true; // 新列默认升序
}
}
// 创建排序比较器
Comparator<Object[]> comparator = (row1, row2) -> {
if (currentSortColumn < 0) {
return 0; // 返回0表示相等,保持原顺序
}
Object value1 = row1[currentSortColumn];
Object value2 = row2[currentSortColumn];
if (value1 == null && value2 == null) return 0;
if (value1 == null) return -1;
if (value2 == null) return 1;
// 根据不同列数据类型定制比较规则
try {
// 数值列:2(数量), 5(板材/组件), 6(订购数量)
if (currentSortColumn == 2 || currentSortColumn == 5 || currentSortColumn == 6) {
double d1 = Double.parseDouble(value1.toString());
double d2 = Double.parseDouble(value2.toString());
return sortAscending ? Double.compare(d1, d2) : Double.compare(d2, d1);
}
// 其他列按字符串排序
else {
String s1 = value1.toString().toLowerCase();
String s2 = value2.toString().toLowerCase();
return sortAscending ? s1.compareTo(s2) : s2.compareTo(s1);
}
} catch (NumberFormatException e) {
// 解析失败时按字符串比较
String s1 = value1.toString().toLowerCase();
String s2 = value2.toString().toLowerCase();
return sortAscending ? s1.compareTo(s2) : s2.compareTo(s1);
}
};
// 特殊处理初始未排序状态
if (columnIndex == -1) {
// 直接复制数据而不排序
filteredTableRowsData.clear();
filteredTableRowsData.addAll(allTableRowsData);
} else {
Collections.sort(filteredTableRowsData, comparator);
}
// 刷新显示
refreshTableWithData(filteredTableRowsData);
}
/**
* 表格数据动态添加
*
* @param rowData
*/
private void addTableRow(Object[] rowData) {
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));
for (int i = 0; i < rowData.length; i++) {
final Object data = rowData[i];
// 判断是否为操作列(最后一列)
if (i == rowData.length - 1) {
// 创建操作按钮
Button actionButton = new Button(requireContext());
actionButton.setText("操作");
actionButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
actionButton.setBackgroundResource(R.drawable.btn_selector); // 自定义按钮样式
// 设置按钮点击监听器
actionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleRowAction(rowData, v);
}
});
// 设置按钮布局参数
TableRow.LayoutParams btnParams = new TableRow.LayoutParams(
0, // 宽度由权重控制
TableRow.LayoutParams.WRAP_CONTENT,
0.5f
);
btnParams.weight = 0.5f;
int margin = dpToPx(1);
btnParams.setMargins(margin, margin, margin, margin);
actionButton.setLayoutParams(btnParams);
actionButton.setHeight(11);
row.addView(actionButton);
} else {
// 正常文本列的代码(保持原逻辑)
HorizontalScrollTextView textView = new HorizontalScrollTextView(requireContext());
textView.setText(String.valueOf(data));
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
int padding = dpToPx(8);
textView.setPadding(padding, padding / 2, padding, padding);
textView.setMinWidth(dpToPx(50));
TableRow.LayoutParams colParams = null;
// 设置背景边框
textView.setBackgroundResource(R.drawable.cell_border);
if (data.toString().length() > 10) {
colParams = new TableRow.LayoutParams(
0, // 宽度将由权重控制
TableRow.LayoutParams.MATCH_PARENT,
2.0f
);
colParams.weight = 2;
} else {
colParams = new TableRow.LayoutParams(
0, // 宽度将由权重控制
TableRow.LayoutParams.MATCH_PARENT,
1.0f
);
colParams.weight = 1;
}
textView.setLayoutParams(colParams);
row.addView(textView);
}
}
table.addView(row);
}
// 动态添加表头 (使用自定义TextView)
private void addTableHeader(TableLayout table) {
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));
// 定义表头
// 更新表头数组(添加操作列)
String[] headers = getResources().getStringArray(R.array.table_headers);
List<String> headerList = new ArrayList<>(Arrays.asList(headers));
headerList.add("操作"); // 添加操作列标题
headers = headerList.toArray(new String[0]);
// 更新权重数组(添加操作列权重)
float[] weights = {1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 1.0f, 1.0f, 0.5f}; // 新增操作列权重0.5
// 更新优先级数组(添加操作列优先级)
boolean[] priority = {false, false, false, false, true, false, false, false};
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));
// 为优先级高的列设置最小宽度
if (priority[i]) {
headerView.setMinWidth(dpToPx(220));
}
// 设置布局参数
TableRow.LayoutParams colParams = new TableRow.LayoutParams(
priority[i] ? TableRow.LayoutParams.WRAP_CONTENT : 0,
TableRow.LayoutParams.MATCH_PARENT,
priority[i] ? 0 : weights[i] // 优先级列不使用权重
);
headerView.setLayoutParams(colParams);
final int columnIndex = i;
headerView.setOnClickListener(v -> {
// 排序并刷新表格
sortTableData(columnIndex, sortAscending);
// 更新排序指示器(可选)
showSortIndicator(headerView);
});
headerRow.addView(headerView);
}
table.addView(headerRow);
}
// 添加排序指示器(可选)
private void showSortIndicator(View header) {
// 实现:在表头右侧添加↑或↓指示符
// 实现逻辑根据设计需求
// header.setTooltipText(new );
}
/**
*
*/
private void showScrollIndicator() {
if (scrollIndicator == null || !isAdded()) return;
// 使用成员变量而不是findViewById
View indicator = this.scrollIndicator;
isIndicatorVisible = true;
// View indicator = getView().findViewById(R.id.scroll_indicator);
if (scrollIndicatorAnimator != null && scrollIndicatorAnimator.isRunning()) {
scrollIndicatorAnimator.cancel();
}
indicator.setVisibility(View.VISIBLE);
indicator.setAlpha(0f);
scrollIndicatorAnimator = ObjectAnimator.ofFloat(indicator, "alpha", 0f, 0.8f);
scrollIndicatorAnimator.setDuration(300);
scrollIndicatorAnimator.start();
}
/**
* +
*/
private void hideScrollIndicator() {
isIndicatorVisible = false;
View indicator = getView().findViewById(R.id.scroll_indicator);
if (scrollIndicatorAnimator != null && scrollIndicatorAnimator.isRunning()) {
scrollIndicatorAnimator.cancel();
}
scrollIndicatorAnimator = ObjectAnimator.ofFloat(indicator, "alpha", indicator.getAlpha(), 0f);
scrollIndicatorAnimator.setDuration(300);
scrollIndicatorAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
indicator.setVisibility(View.INVISIBLE);
}
});
scrollIndicatorAnimator.start();
}
/**
* @param currentScroll
* @param maxScroll
*/
private void updateScrollIndicatorPosition(int currentScroll, int maxScroll) {
if (scrollIndicator == null || !isAdded()) return;
View indicator = this.scrollIndicator; // 使用成员变量
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) indicator.getLayoutParams();
// 计算指示器位置(0-100%)
float percentage = (float) currentScroll / maxScroll;
int maxMargin = getResources().getDisplayMetrics().widthPixels - indicator.getWidth();
// 设置右边距(控制位置)
params.rightMargin = (int) (maxMargin * percentage);
indicator.setLayoutParams(params);
}
// 处理行操作的方法
private void handleRowAction(Object[] rowData, View anchorButton) {
// 安全地从行数据中提取关键信息
String orderNumber = safeGetString(rowData[0]); // 订单号
String productId = safeGetString(rowData[1]); // 产品ID
String componentName = safeGetString(rowData[3]); // 组件名称
// 安全地获取订购数量
double materialQuantity = 0.0;
try {
if (rowData[6] != null) {
if (rowData[6] instanceof Number) {
materialQuantity = ((Number) rowData[6]).doubleValue();
} else {
materialQuantity = Double.parseDouble(rowData[6].toString());
}
}
} catch (Exception e) {
Log.e("OrderFragment", "Failed to parse material quantity", e);
}
Context context = getContext();
if (context == null || anchorButton == null) {
Log.w("PopupMenu", "Context or anchorButton is null");
return;
}
PopupMenu popupMenu = new PopupMenu(context, anchorButton);
// 强制设置菜单在锚点视图下方显示(关键设置)
popupMenu.setGravity(Gravity.BOTTOM);
// 如果使用支持库,设置弹出方向
// 设置在锚点视图下方显示
// popupMenu.setOverlapAnchor(true);
// 填充菜单项
popupMenu.getMenuInflater().inflate(R.menu.row_actions_menu, popupMenu.getMenu());
// 设置菜单项点击监听器
popupMenu.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_view_details) {
showDetailDialog(orderNumber, productId);
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;
});
popupMenu.show();
}
// 安全获取字符串值的方法
private String safeGetString(Object value) {
if (value == null) return "";
if (value instanceof String) return (String) value;
return value.toString();
}
// 查看详情对话框
private void showDetailDialog(String orderNumber, String productId) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setTitle("订单详情")
.setMessage("订单号: " + orderNumber + "\n产品ID: " + productId)
.setPositiveButton("确定", null)
.show();
}
// 编辑行数据
private void editRowData(Object[] rowData) {
// 实现编辑逻辑
// 这里创建包含表单的对话框
Toast.makeText(requireContext(), "编辑操作: " + rowData[0], Toast.LENGTH_SHORT).show();
}
// 带确认的删除操作
private void deleteRowWithConfirm(Object[] rowData) {
new AlertDialog.Builder(requireContext())
.setTitle("确认删除")
.setMessage("确定要删除订单 " + rowData[0] + " 吗?")
.setPositiveButton("删除", (dialog, which) -> {
// 实际删除逻辑
deleteRow(rowData);
})
.setNegativeButton("取消", null)
.show();
}
// 实际删除行数据
private void deleteRow(Object[] rowData) {
// 1. 从allTableRowsData中移除对应行
for (Iterator<Object[]> iterator = allTableRowsData.iterator(); iterator.hasNext(); ) {
Object[] row = iterator.next();
if (Arrays.equals(row, rowData)) {
iterator.remove();
break;
}
}
// 2. 从filteredTableRowsData中移除
filteredTableRowsData.removeIf(row -> Arrays.equals(row, rowData));
// 3. 刷新表格
refreshTableWithData(filteredTableRowsData);
Toast.makeText(requireContext(), "已删除订单", Toast.LENGTH_SHORT).show();
}
// DP转PX工具方法
private int dpToPx(int dp) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
getResources().getDisplayMetrics()
);
}
/**
* 数据组合
*
* @param order
* @param product
* @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();
String boardInfo = board.TableText();
;
return new Object[]{
order.getNumber(), // 订单号
product.getBianhao(), // 产品编号
dingdan_chanpin.getShuliang(), // 产品数量 (根据需求调整)
component.getZujian().getName(), // 组件名
boardInfo, // 板材信息
Math.round(component.getOne_howmany()), // 板材/组件
material.getShuliang(), // 订购数量
"操作"
};
}
// 初始化列选择器
private void initColumnSelector() {
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);
columnSelector.setAdapter(adapter);
// 添加"所有列"选项
columnSelector.setSelection(0); // 默认选择第一个选项(所有列)
// 列选择变化监听
columnSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
applySearchFilter();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
// 应用搜索过滤
private void applySearchFilter() {
String query = searchView.getQuery().toString().trim().toLowerCase();
int selectedColumn = columnSelector.getSelectedItemPosition();
filteredTableRowsData.clear();
if (query.isEmpty()) {
// 没有搜索词,显示所有数据
filteredTableRowsData.addAll(allTableRowsData);
} else {
// 根据选择的列进行过滤
for (Object[] row : allTableRowsData) {
// 如果选择"所有列"(位置0),检查所有列
if (selectedColumn == 0) {
for (Object cell : row) {
if (cell != null && cell.toString().toLowerCase().contains(query)) {
filteredTableRowsData.add(row);
break;
}
}
}
// 检查特定列
else if (selectedColumn >= 1 && selectedColumn <= row.length) {
int columnIndex = selectedColumn - 1; // 调整索引(0=所有列,1=第一列)
if (row[columnIndex] != null &&
row[columnIndex].toString().toLowerCase().contains(query)) {
filteredTableRowsData.add(row);
}
}
}
}
// 刷新表格显示
refreshTableWithData(filteredTableRowsData);
}
/**
* 刷新表格显示
*/
private void refreshTableWithData(Iterable<? extends Object[]> dataToShow) {
// Log.d("TableRefresh", "Refreshing table with " + currentSortColumn + " rows");
// 添加调试信息
Log.d(“TableRefresh”, “Refreshing table with " + currentSortColumn + " rows”);
removeAllRowsSafely();
int addedRows = 0;
for (Object[] rowData : dataToShow) {
addTableRow(rowData);
addedRows++;
}
// 添加空数据提示
if (addedRows == 0) {
addEmptyTableRow();
}
}
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);
}
private void removeAllRowsSafely() {
// 移除除表头外的所有行(如果有表头)
if (table.getChildCount() > 0) {
// 保留表头(索引0)
for (int i = table.getChildCount() - 1; i >= 1; i--) {
View child = table.getChildAt(i);
table.removeView(child);
// 清理视图引用(非常重要!)
cleanupRowViews((TableRow) child);
}
}
}
private void cleanupRowViews(TableRow row) {
int childCount = row.getChildCount();
for (int i = 0; i < childCount; i++) {
View view = row.getChildAt(i);
// 解除视图的所有监听器
view.setOnClickListener(null);
// 特别是操作按钮,需要取消所有监听器
if (view instanceof Button) {
Button button = (Button) view;
button.setOnClickListener(null);
// 清空按钮的数据引用
button.setTag(null);
}
}
// 从父视图中移除行
if (row.getParent() != null) {
((ViewGroup) row.getParent()).removeView(row);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
// 清理视图引用
// 移除滚动监听器
if (horizontalScrollView != null) {
ViewTreeObserver observer = horizontalScrollView.getViewTreeObserver();
if (observer.isAlive()) {
observer.removeOnScrollChangedListener(scrollListener);
}
}
scrollIndicator = null;
horizontalScrollView = null;
table = null;
rootView = null;
}
}当跳转到另一个Fragment时,当前Fragment销毁,需要再次返回时控件被重新加载能数据和视图重新加载。但现在是在其他fragment中 没有返回这个fragment还是有报错并崩溃