这是一个模仿Android Luncher的CellLayout布局, 可以设置固定的行数和列数, 继承自ViewGroup,故不需要使用Adapter。 只需要使用addView()方法就可以将子View添加到布局,并实现按从左到右,从上到下顺序排序view。还可以设置行间距和列间距
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class CellLayout extends ViewGroup {
private int lineNum;
private int columnNum;
private int vecitcalSpace;
private int horizontalSpace;
public CellLayout(Context context) {
super(context);
}
public CellLayout(Context context, AttributeSet attrs) {
super(context,attrs);
}
public CellLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void dispatchDraw(Canvas canvas) {
final long drawingTime = getDrawingTime();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
drawChild(canvas, getChildAt(i), drawingTime);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}
// The children are given the same width and height as the workspace
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
int layoutWidth = this.getWidth();
int layoutHeight = this.getHeight();
int count = getChildCount();
int index = 0;
int cellWidth = 0;
int cellHeight = 0;
if(this.columnNum > 0) {
//cellWidth = layoutWidth/this.columnNum - (this.columnNum + 1) * this.horizontalSpace;
cellWidth = (layoutWidth - (this.columnNum + 1 ) * this.horizontalSpace)/this.columnNum ;
Toast.makeText(getContext(), " layoutWidth/this.columnNum=" +layoutWidth/this.columnNum, Toast.LENGTH_SHORT).show();
}
if(this.lineNum > 0) {
cellHeight = (layoutHeight - (this.lineNum + 1) * this.vecitcalSpace) / this.lineNum;
}
for(int i = 0; i < this.lineNum; i++) {
for(int j = 0; j < this.columnNum; j++) {
if(index >= count){
break;
}
int x = j * cellWidth + (j+1) * this.horizontalSpace;
int y = i * cellHeight + (i+1) * this.vecitcalSpace;
int width = cellWidth;
int height = cellHeight;
final View child = getChildAt(index);
if(child.getVisibility() != View.GONE) {
child.layout(x, y, x + width, y + height);
}
index ++;
}
}
}
public void setHorizontalSpace(int space) {
this.horizontalSpace = space;
}
public void setVecticalSpace(int space) {
this.vecitcalSpace = space;
}
public int getLineNum() {
return lineNum;
}
public void setLineNum(int lineNum) {
this.lineNum = lineNum;
}
public int getColumnNum() {
return columnNum;
}
public void setColumnNum(int columnNum) {
this.columnNum = columnNum;
}
}