这是一个实现网格布局的代码,可以为您完成所有计算。它将所有子视图放置在等间距和等边距的网格中。它还优化了列数,以避免所有行都尽可能地填满(例如,9个子视图可以放在3行上,分别为4,4,1,但是3,3,3看起来更好)。所有内容都是动态的,所以不用担心横屏/竖屏/手机/平板电脑/电视。
package .......;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class AutoGridLayout extends ViewGroup
{
private int mMaxHeight;
private int mMaxWidth;
public AutoGridLayout(Context context)
{
super(context);
}
public AutoGridLayout(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public AutoGridLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
public boolean shouldDelayChildPressedState()
{
return false;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int count = getChildCount();
mMaxHeight = 0;
mMaxWidth = 0;
int childState = 0;
for (int i = 0; i < count; i++)
{
final View child = getChildAt(i);
if (child.getVisibility() != GONE)
{
measureChild(child, widthMeasureSpec, heightMeasureSpec);
mMaxWidth = Math.max(mMaxWidth, child.getMeasuredWidth());
mMaxHeight = Math.max(mMaxHeight, child.getMeasuredHeight());
}
}
mMaxHeight = Math.max(mMaxHeight, getSuggestedMinimumHeight());
mMaxWidth = Math.max(mMaxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(resolveSizeAndState(mMaxWidth, widthMeasureSpec, childState),
resolveSizeAndState(mMaxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
final float pxWidth = (right - left + 1);
final float pxHeight = (1 + bottom - top);
final int totalChildCount = getChildCount();
int count = 0;
for (int i = 0; i < totalChildCount; i++)
{
if (getChildAt(i).getVisibility() != GONE)
count++;
}
final float minSpacing = pxWidth / 20;
final int maxPossibleColumns = (int) (pxWidth / (mMaxWidth + minSpacing));
final int rows = (int)Math.ceil((float)count / maxPossibleColumns);
final int voidsAtLastRow = (rows * maxPossibleColumns - count);
final int nColumns = maxPossibleColumns - voidsAtLastRow / rows;
final int xSpace = (int)Math.max(0,(pxWidth - nColumns * mMaxWidth) / (nColumns + 1));
final int ySpace = (int)Math.max(0,(pxHeight - rows * mMaxHeight) / (rows + 1));
int n = 0;
for (int i = 0; i < totalChildCount; i++)
{
final View child = getChildAt(i);
if (child.getVisibility() != GONE)
{
final int col = n % nColumns;
final int x = xSpace + (xSpace + mMaxWidth) * col;
final int row = n / nColumns;
final int y = ySpace + (ySpace + mMaxHeight) * row;
child.layout(x, y,x+mMaxWidth,y+mMaxHeight);
n++;
}
}
}
}
![Sample](https://istack.dev59.com/YKhId.webp)