轻量级GridView -- CellLayout
这是一个模仿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; } }