Home | History | Annotate | Download | only in fixedgridlayout
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.fixedgridlayout;
     18 
     19 import android.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.util.AttributeSet;
     22 import android.util.SparseIntArray;
     23 import android.view.Gravity;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.view.ViewDebug;
     27 
     28 /**
     29  * A layout that arranges its children in a grid.  The size of the
     30  * cells is set by the {@link #setCellSize} method and the
     31  * android:cell_width and android:cell_height attributes in XML.
     32  * The number of rows and columns is determined at runtime.  Each
     33  * cell contains exactly one view, and they flow in the natural
     34  * child order (the order in which they were added, or the index
     35  * in {@link #addViewAt}.  Views can not span multiple cells.
     36  */
     37 public class FixedGridLayout extends ViewGroup {
     38     int mCellWidth;
     39     int mCellHeight;
     40 
     41     public FixedGridLayout(Context context) {
     42         super(context);
     43     }
     44 
     45     public FixedGridLayout(Context context, AttributeSet attrs) {
     46         super(context, attrs);
     47 
     48         // Read the resource attributes.
     49         TypedArray a = context.obtainStyledAttributes(
     50                 attrs, R.styleable.FixedGridLayout);
     51         mCellWidth = a.getDimensionPixelSize(
     52                 R.styleable.FixedGridLayout_cellWidth, -1);
     53         mCellHeight = a.getDimensionPixelSize(
     54                 R.styleable.FixedGridLayout_cellHeight, -1);
     55         a.recycle();
     56     }
     57 
     58     public void setCellWidth(int px) {
     59         mCellWidth = px;
     60         requestLayout();
     61     }
     62 
     63     public void setCellHeight(int px) {
     64         mCellHeight = px;
     65         requestLayout();
     66     }
     67 
     68     @Override
     69     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     70         int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth,
     71                 MeasureSpec.AT_MOST);
     72         int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight,
     73                 MeasureSpec.AT_MOST);
     74 
     75         int count = getChildCount();
     76         for (int index=0; index<count; index++) {
     77             final View child = getChildAt(index);
     78             child.measure(cellWidthSpec, cellHeightSpec);
     79         }
     80         // Use the size our parents gave us
     81         setMeasuredDimension(resolveSize(mCellWidth*count, widthMeasureSpec),
     82                 resolveSize(mCellHeight*count, heightMeasureSpec));
     83     }
     84 
     85     @Override
     86     protected void onLayout(boolean changed, int l, int t, int r, int b) {
     87         int cellWidth = mCellWidth;
     88         int cellHeight = mCellHeight;
     89         int columns = (r - l) / cellWidth;
     90         if (columns < 0) {
     91             columns = 1;
     92         }
     93         int x = 0;
     94         int y = 0;
     95         int i = 0;
     96         int count = getChildCount();
     97         for (int index=0; index<count; index++) {
     98             final View child = getChildAt(index);
     99 
    100             int w = child.getMeasuredWidth();
    101             int h = child.getMeasuredHeight();
    102 
    103             int left = x + ((cellWidth-w)/2);
    104             int top = y + ((cellHeight-h)/2);
    105 
    106             child.layout(left, top, left+w, top+h);
    107             if (i >= (columns-1)) {
    108                 // advance to next row
    109                 i = 0;
    110                 x = 0;
    111                 y += cellHeight;
    112             } else {
    113                 i++;
    114                 x += cellWidth;
    115             }
    116         }
    117     }
    118 }
    119 
    120