DCS/ruiyiweiUX/Assets/Scripts/Base/DynamicTable.cs

225 lines
7.9 KiB
C#
Raw Permalink Normal View History

2026-06-09 13:59:11 +08:00
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class DynamicTable : MonoBehaviour
{
[Header("Table Settings")]
public GameObject tableContainer;
// public GameObject headerPrefab;
public GameObject rowPrefab;
public int columns = 4;
public int rows = 10;
[TextArea]
public string[] tableData;
[Header("Style Settings")]
public Color headerColor = new Color(0.2f, 0.3f, 0.5f);
public Color evenRowColor = new Color(0.9f, 0.9f, 0.9f, 0.5f);
public Color oddRowColor = new Color(0.75f, 0.75f, 0.75f, 0.5f);
public Color selectedRowColor = new Color(0.5f, 0.7f, 1f, 0.8f);
private ScrollRect scrollRect;
// private GameObject headerRow;
private List<GameObject> tableRows = new List<GameObject>();
private int selectedRow = -1;
void Start()
{
InitializeTable();
GenerateTableData();
}
void InitializeTable()
{
// 确保有ScrollRect组件
scrollRect = tableContainer.GetComponent<ScrollRect>();
if (scrollRect == null)
{
scrollRect = tableContainer.AddComponent<ScrollRect>();
}
// 创建内容容器
GameObject content = new GameObject("Content");
RectTransform contentRect = content.AddComponent<RectTransform>();
contentRect.SetParent(tableContainer.transform, false);
contentRect.anchorMin = Vector2.zero;
contentRect.anchorMax = new Vector2(1, 1);
contentRect.pivot = new Vector2(0.5f, 1f);
contentRect.offsetMin = new Vector2(0, 0);
contentRect.offsetMax = new Vector2(0, 0);
// 添加垂直布局组
VerticalLayoutGroup verticalLayout = content.AddComponent<VerticalLayoutGroup>();
verticalLayout.padding = new RectOffset(5, 5, 5, 5);
verticalLayout.spacing = 2f;
verticalLayout.childControlHeight = true;
verticalLayout.childControlWidth = true;
verticalLayout.childForceExpandHeight = false;
verticalLayout.childForceExpandWidth = true;
// 添加内容尺寸适配
ContentSizeFitter contentFitter = content.AddComponent<ContentSizeFitter>();
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
scrollRect.content = contentRect;
}
public void GenerateTableData()
{
// 清除现有行(除了表头)
for (int i = tableRows.Count - 1; i >= 0; i--)
{
Destroy(tableRows[i]);
}
tableRows.Clear();
// 获取内容容器
Transform content = scrollRect.content;
// 生成表格行
for (int rowIdx = 0; rowIdx < rows; rowIdx++)
{
GameObject row = Instantiate(rowPrefab, content);
tableRows.Add(row);
// 添加行点击事件
Button rowButton = row.GetComponent<Button>();
if (rowButton == null) rowButton = row.AddComponent<Button>();
int currentRow = rowIdx;
rowButton.onClick.AddListener(() => SelectRow(currentRow));
// 设置行样式
Image rowImage = row.GetComponent<Image>();
if (rowImage == null) rowImage = row.AddComponent<Image>();
rowImage.color = (rowIdx % 2 == 0) ? evenRowColor : oddRowColor;
// 确保行有水平布局
HorizontalLayoutGroup rowLayout = row.GetComponent<HorizontalLayoutGroup>();
if (rowLayout == null)
{
rowLayout = row.AddComponent<HorizontalLayoutGroup>();
rowLayout.padding = new RectOffset(5, 5, 5, 5);
rowLayout.spacing = 2f;
rowLayout.childControlHeight = true;
rowLayout.childControlWidth = true;
rowLayout.childForceExpandHeight = true;
rowLayout.childForceExpandWidth = true;
}
// 生成单元格
for (int colIdx = 0; colIdx < columns; colIdx++)
{
TextMeshProUGUI cellText;
cellText = row.transform.GetChild(colIdx).GetComponent<TextMeshProUGUI>();
// 从tableData数组中获取数据如果没有设置则使用默认值
int dataIndex = rowIdx * columns + colIdx;
if (tableData != null && dataIndex < tableData.Length && !string.IsNullOrEmpty(tableData[dataIndex]))
{
cellText.text = tableData[dataIndex];
}
else
{
cellText.text = $"数据 ({rowIdx+1}, {colIdx+1})";
}
}
}
}
void SelectRow(int rowIndex)
{
// 恢复之前选中行的颜色
if (selectedRow >= 0 && selectedRow < tableRows.Count)
{
Image prevImage = tableRows[selectedRow].GetComponent<Image>();
prevImage.color = (selectedRow % 2 == 0) ? evenRowColor : oddRowColor;
}
// 设置新选中行的颜色
if (rowIndex >= 0 && rowIndex < tableRows.Count)
{
Image newImage = tableRows[rowIndex].GetComponent<Image>();
newImage.color = selectedRowColor;
selectedRow = rowIndex;
// 这里可以添加选中行后的其他逻辑
Debug.Log($"选中了第 {rowIndex + 1} 行");
}
}
// 清空表格(保留表头)
public void ClearTable()
{
for (int i = tableRows.Count - 1; i >= 0; i--)
{
Destroy(tableRows[i]);
}
tableRows.Clear();
selectedRow = -1;
}
// 添加新行
public void AddRow(List<string> cellData)
{
Transform content = scrollRect.content;
GameObject row = Instantiate(rowPrefab, content);
tableRows.Add(row);
int rowIndex = tableRows.Count - 1;
// 设置行样式
Image rowImage = row.GetComponent<Image>();
if (rowImage == null) rowImage = row.AddComponent<Image>();
rowImage.color = (rowIndex % 2 == 0) ? evenRowColor : oddRowColor;
// 添加行点击事件
Button rowButton = row.GetComponent<Button>();
if (rowButton == null) rowButton = row.AddComponent<Button>();
rowButton.onClick.AddListener(() => SelectRow(rowIndex));
// 确保行有水平布局
HorizontalLayoutGroup rowLayout = row.GetComponent<HorizontalLayoutGroup>();
if (rowLayout == null)
{
rowLayout = row.AddComponent<HorizontalLayoutGroup>();
rowLayout.padding = new RectOffset(5, 5, 5, 5);
rowLayout.spacing = 2f;
rowLayout.childControlHeight = true;
rowLayout.childControlWidth = true;
rowLayout.childForceExpandHeight = true;
rowLayout.childForceExpandWidth = true;
}
// 生成单元格
for (int colIdx = 0; colIdx < columns; colIdx++)
{
Text cellText;
if (colIdx < row.transform.childCount)
{
cellText = row.transform.GetChild(colIdx).GetComponent<Text>();
}
else
{
GameObject textObj = new GameObject("Cell_" + colIdx);
textObj.transform.SetParent(row.transform);
cellText = textObj.AddComponent<Text>();
cellText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
cellText.color = Color.black;
cellText.alignment = TextAnchor.MiddleLeft;
// 添加布局元素
LayoutElement layoutElem = textObj.AddComponent<LayoutElement>();
layoutElem.flexibleWidth = 1;
}
// 设置单元格数据
cellText.text = colIdx < cellData.Count ? cellData[colIdx] : "";
}
}
}