项目地址
- 这个练习是Tab和自定义网格布局组合完成的具体效果如下Gif图
- 首先Tab功能就是TabGroup负责控制每一个TabButton对鼠标进入、离开、选择,针对进入和离开做出不同的反应,针对选择选择激活相应的GameObject,代码就是2个脚本很简单,可以直接看上面项目脚本。
- 从上面Gif中可以看到每个页面都有不同的网格布局,并且都是同一个布局组件实现的。如果想实现自定义布局需要继承LayoutGroup抽象类具体如下代码,覆写的这个函数看名字很奇怪是计算布局的水平,但是这个函数是默认调用的和他名字关系不大。
- 具体思路:
- 就是首先根据子物体确定网格的布局比如是2x2、3x2、1x3
- 然后根据确定的尺寸算出一个单元格的宽高,这里需要考虑到网格的间隙spacing、离4个边的距离等。这里我这算的有点偏差,但是不影响使用,有强迫症的可以自行修改。
- 最后我们就需要设置每个子物体的具体的位置和宽高了,这里采用的是
SetChildAlongAxis
函数,这个函数只能按照轴来设置axis = 0水平 1垂直,后面2个参数分别为x/y、单元格Width/Height
public override void CalculateLayoutInputHorizontal()
{
base.CalculateLayoutInputHorizontal();
float sqrRt = Mathf.Sqrt(transform.childCount);
rows = Mathf.CeilToInt(sqrRt);
columns = Mathf.CeilToInt(sqrRt);
if(fitType == FitType.RowMajor)
{
rows = Mathf.CeilToInt(transform.childCount / (float)columns);
}else if(fitType == FitType.ColumnMajor)
{
columns = Mathf.CeilToInt(transform.childCount / (float)rows);
}else if(fitType == FitType.FixedRow)
{
rows = 1;
columns = transform.childCount;
}
else if(fitType == FitType.FixedColumn)
{
rows = transform.childCount;
columns = 1;
}
float parentWid = rectTransform.rect.width;
float parentHei = rectTransform.rect.height;
cellSize.x = (parentWid - spacing.x - padding.left - padding.right) / (float)columns;
cellSize.y = (parentHei - spacing.y - padding.top - padding.bottom) / (float)rows;
int rowIdx;
int columnIdx;
for (int i = 0,cCount = transform.childCount; i < cCount; i++)
{
rowIdx = i / columns;
columnIdx = i % columns;
var item = rectChildren[i];
var xPos = (cellSize.x + spacing.x) * columnIdx;
var yPos = (cellSize.y + spacing.y) * rowIdx;
xPos += padding.left;
yPos += padding.top;
SetChildAlongAxis(item, 0, xPos, cellSize.x);
SetChildAlongAxis(item, 1, yPos, cellSize.y);
}
}