| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.example.android.fixedgridlayout; |
| |
| import android.content.Context; |
| import android.content.res.TypedArray; |
| import android.util.AttributeSet; |
| import android.util.SparseIntArray; |
| import android.view.Gravity; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewDebug; |
| |
| /** |
| * A layout that arranges its children in a grid. The size of the |
| * cells is set by the {@link #setCellSize} method and the |
| * android:cell_width and android:cell_height attributes in XML. |
| * The number of rows and columns is determined at runtime. Each |
| * cell contains exactly one view, and they flow in the natural |
| * child order (the order in which they were added, or the index |
| * in {@link #addViewAt}. Views can not span multiple cells. |
| */ |
| public class FixedGridLayout extends ViewGroup { |
| int mCellWidth; |
| int mCellHeight; |
| |
| public FixedGridLayout(Context context) { |
| super(context); |
| } |
| |
| public FixedGridLayout(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| |
| // Read the resource attributes. |
| TypedArray a = context.obtainStyledAttributes( |
| attrs, R.styleable.FixedGridLayout); |
| mCellWidth = a.getDimensionPixelSize( |
| R.styleable.FixedGridLayout_cellWidth, -1); |
| mCellHeight = a.getDimensionPixelSize( |
| R.styleable.FixedGridLayout_cellHeight, -1); |
| a.recycle(); |
| } |
| |
| public void setCellWidth(int px) { |
| mCellWidth = px; |
| requestLayout(); |
| } |
| |
| public void setCellHeight(int px) { |
| mCellHeight = px; |
| requestLayout(); |
| } |
| |
| @Override |
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth, |
| MeasureSpec.AT_MOST); |
| int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight, |
| MeasureSpec.AT_MOST); |
| |
| int count = getChildCount(); |
| for (int index=0; index<count; index++) { |
| final View child = getChildAt(index); |
| child.measure(cellWidthSpec, cellHeightSpec); |
| } |
| // Use the size our parents gave us |
| setMeasuredDimension(resolveSize(mCellWidth*count, widthMeasureSpec), |
| resolveSize(mCellHeight*count, heightMeasureSpec)); |
| } |
| |
| @Override |
| protected void onLayout(boolean changed, int l, int t, int r, int b) { |
| int cellWidth = mCellWidth; |
| int cellHeight = mCellHeight; |
| int columns = (r - l) / cellWidth; |
| if (columns < 0) { |
| columns = 1; |
| } |
| int x = 0; |
| int y = 0; |
| int i = 0; |
| int count = getChildCount(); |
| for (int index=0; index<count; index++) { |
| final View child = getChildAt(index); |
| |
| int w = child.getMeasuredWidth(); |
| int h = child.getMeasuredHeight(); |
| |
| int left = x + ((cellWidth-w)/2); |
| int top = y + ((cellHeight-h)/2); |
| |
| child.layout(left, top, left+w, top+h); |
| if (i >= (columns-1)) { |
| // advance to next row |
| i = 0; |
| x = 0; |
| y += cellHeight; |
| } else { |
| i++; |
| x += cellWidth; |
| } |
| } |
| } |
| } |
| |