package com.luciofm.droidcon.ifican.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.luciofm.droidcon.ifican.R;
public class SquareGridLayout extends ViewGroup {
private int mSpacing = 0;
private int mColumns = 2;
public SquareGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SquareGridLayout);
try {
mSpacing = a.getDimensionPixelSize(
R.styleable.SquareGridLayout_spacing, 0);
mColumns = a.getInt(R.styleable.SquareGridLayout_numColumns, 2);
} finally {
a.recycle();
}
mCurrentHeight = new int[mColumns];
}
public SquareGridLayout(Context context) {
super(context);
}
private int[] mCurrentHeight;
public void setColumnCount(int size) {
if (size < 1) {
throw new IllegalArgumentException(
"Layout must have at least one column");
}
mColumns = size;
mCurrentHeight = new int[mColumns];
requestLayout();
}
public int getColumnCount() {
return mColumns;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int padw = getPaddingLeft() + getPaddingRight();
int squareWidth = (widthSize - padw - (mColumns > 1 ? (mColumns + 1)
* mSpacing : 0))
/ mColumns;
int childSpec = MeasureSpec.makeMeasureSpec(squareWidth,
MeasureSpec.EXACTLY);
int width = 0;
int[] height = new int[mColumns];
for (int i = 0; i < mColumns; i++) {
height[i] = getPaddingTop();
mCurrentHeight[i] = 0;
}
int currentWidth = getPaddingLeft();
int currentColumn = 0;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
measureChild(child, childSpec, childSpec);
if (currentWidth + child.getMeasuredWidth() + mSpacing > widthSize) {
for (int j = 0; j < mColumns; j++) {
height[j] += mCurrentHeight[j] + mSpacing;
mCurrentHeight[j] = 0;
}
width = Math.max(width, currentWidth);
currentWidth = getPaddingLeft();
}
lp.x = currentWidth + mSpacing;
lp.y = height[currentColumn] + mSpacing;
currentWidth += child.getMeasuredWidth() + mSpacing;
mCurrentHeight[currentColumn] = Math.max(
mCurrentHeight[currentColumn], child.getMeasuredHeight());
currentColumn++;
if (currentColumn >= mColumns)
currentColumn = 0;
}
for (int i = 0; i < mColumns; i++)
height[i] += mCurrentHeight[i] + mSpacing + getPaddingBottom()
+ mSpacing;
width = Math.max(width, currentWidth - mSpacing);
width += getPaddingRight();
setMeasuredDimension(resolveSize(width, widthMeasureSpec),
resolveSize(getMaxHeight(height), heightMeasureSpec));
}
private int getMaxHeight(int[] heights) {
int height = 0;
for (int i = 0; i < heights.length; i++) {
if (heights[i] > height)
height = heights[i];
}
return height;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y
+ child.getMeasuredHeight());
}
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends ViewGroup.LayoutParams {
public int x;
public int y;
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
}