225 lines
7.9 KiB
C#
225 lines
7.9 KiB
C#
|
|
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] : "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|