Merge change I53f94fc2 into eclair

* changes:
  Tweaked the dialer screen to match the designer's PPL.
diff --git a/res/layout-finger/dialpad.xml b/res/layout-finger/dialpad.xml
index 0acb721..82179db 100644
--- a/res/layout-finger/dialpad.xml
+++ b/res/layout-finger/dialpad.xml
@@ -21,8 +21,11 @@
     android:id="@+id/dialpad"
     android:paddingLeft="7dp"
     android:paddingRight="7dp"
-    android:layout_width="fill_parent"
+    android:paddingTop="6dp"
+    android:paddingBottom="6dp"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal"
 >
         <ImageButton android:id="@+id/one"
             android:layout_width="88dp"
diff --git a/res/layout-finger/twelve_key_dialer.xml b/res/layout-finger/twelve_key_dialer.xml
index 018bee8..83eb2cf 100644
--- a/res/layout-finger/twelve_key_dialer.xml
+++ b/res/layout-finger/twelve_key_dialer.xml
@@ -25,9 +25,8 @@
     <!-- TODO: Use a textAppearance to control the display of the number -->
     <EditText android:id="@+id/digits"
         android:layout_width="fill_parent"
-        android:layout_height="66dip"
+        android:layout_height="67dip"
         android:layout_marginBottom="6dip"
-        android:layout_marginTop="1dip"
         android:gravity="center"
         android:maxLines="1"
         android:scrollHorizontally="true"
@@ -42,42 +41,7 @@
     <include layout="@layout/dialpad" />
 
     <!-- Horizontal row of buttons (Voicemail + DialButton + Delete.) -->
-    <LinearLayout android:id="@+id/voicemailAndDialAndDelete"
-        android:layout_width="wrap_content"
-        android:layout_height="fill_parent"
-        android:layout_gravity="center_horizontal"
-        android:layout_marginBottom="6dip"
-        android:orientation="horizontal">
-
-        <!-- Onscreen "Voicemail" button -->
-        <ImageButton android:id="@+id/voicemailButton"
-            android:layout_width="90dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_voicemail"
-            android:src="@drawable/ic_dial_action_voice_mail" />
-
-        <!-- Onscreen "Dial" button, used on all platforms by
-             default. Its usage can be disabled using resources (see
-             config.xml.) -->
-        <ImageButton android:id="@+id/dialButton"
-            android:layout_width="116dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_action"
-            android:src="@drawable/ic_dial_action_call" />
-
-        <!-- Onscreen "Backspace/Delete" button -->
-        <ImageButton android:id="@+id/deleteButton"
-            android:layout_width="90dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_delete"
-            android:src="@drawable/ic_dial_action_delete" />
-    </LinearLayout>
+    <include layout="@layout/voicemail_dial_delete" />
 
     <!-- "Dialpad chooser" UI, shown only when the user brings up the
          Dialer while a call is already in progress.
diff --git a/res/layout-finger/voicemail_dial_delete.xml b/res/layout-finger/voicemail_dial_delete.xml
new file mode 100644
index 0000000..1aa2ac4
--- /dev/null
+++ b/res/layout-finger/voicemail_dial_delete.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Horizontal row of buttons (Voicemail + DialButton + Delete.) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/voicemailAndDialAndDelete"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal"
+    android:layout_marginTop="6dip"
+    android:orientation="horizontal">
+
+    <!-- Onscreen "Voicemail" button.
+         The width is 75 (from the mocks) + 12 of padding from the
+         9patch, total is 87.
+    -->
+    <ImageButton android:id="@+id/voicemailButton"
+        android:layout_width="87dip"
+        android:layout_height="50dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_voicemail"
+        android:src="@drawable/ic_dial_action_voice_mail" />
+
+    <!-- Onscreen "Dial" button, used on all platforms by
+         default. Its usage can be disabled using resources (see
+         config.xml.) -->
+    <ImageButton android:id="@+id/dialButton"
+        android:layout_width="116dip"
+        android:layout_height="50dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_action"
+        android:src="@drawable/ic_dial_action_call" />
+
+    <!-- Onscreen "Backspace/Delete" button
+         The width is 75 (from the mocks) + 12 of padding from the
+         9patch, total is 87.
+    -->
+    <ImageButton android:id="@+id/deleteButton"
+        android:layout_width="87dip"
+        android:layout_height="50dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_delete"
+        android:src="@drawable/ic_dial_action_delete" />
+</LinearLayout>
+
diff --git a/res/layout-land-finger/twelve_key_dialer.xml b/res/layout-land-finger/twelve_key_dialer.xml
index 11ec8d6..8c66ff3 100644
--- a/res/layout-land-finger/twelve_key_dialer.xml
+++ b/res/layout-land-finger/twelve_key_dialer.xml
@@ -26,7 +26,7 @@
     <EditText android:id="@+id/digits"
         android:layout_width="fill_parent"
         android:layout_height="66dip"
-        android:layout_marginBottom="6dip"
+        android:layout_marginBottom="50dip"
         android:layout_marginTop="1dip"
         android:gravity="center"
         android:maxLines="1"
@@ -39,42 +39,7 @@
      />
 
     <!-- Horizontal row of buttons (Voicemail + DialButton + Delete.) -->
-    <LinearLayout android:id="@+id/voicemailAndDialAndDelete"
-        android:layout_width="wrap_content"
-        android:layout_height="fill_parent"
-        android:layout_gravity="center_horizontal"
-        android:layout_marginBottom="6dip"
-        android:orientation="horizontal">
-
-        <!-- Onscreen "Voicemail" button -->
-        <ImageButton android:id="@+id/voicemailButton"
-            android:layout_width="90dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_voicemail"
-            android:src="@drawable/ic_dial_action_voice_mail" />
-
-        <!-- Onscreen "Dial" button, used on all platforms by
-             default. Its usage can be disabled using resources (see
-             config.xml.) -->
-        <ImageButton android:id="@+id/dialButton"
-            android:layout_width="116dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_action"
-            android:src="@drawable/ic_dial_action_call" />
-
-        <!-- Onscreen "Backspace/Delete" button -->
-        <ImageButton android:id="@+id/deleteButton"
-            android:layout_width="90dip"
-            android:layout_height="52dip"
-            android:layout_gravity="center_vertical"
-            android:state_enabled="false"
-            android:background="@drawable/btn_dial_delete"
-            android:src="@drawable/ic_dial_action_delete" />
-    </LinearLayout>
+    <include layout="@layout/voicemail_dial_delete" />
 
     <!-- "Dialpad chooser" UI, shown only when the user brings up the
          Dialer while a call is already in progress.
diff --git a/res/layout-long-finger/dialpad.xml b/res/layout-long-finger/dialpad.xml
new file mode 100644
index 0000000..036c4fa
--- /dev/null
+++ b/res/layout-long-finger/dialpad.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Dialpad in the Contact app.
+     Tall screen version with taller buttons.
+ -->
+
+<com.android.contacts.ButtonGridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/dialpad"
+    android:paddingLeft="7dp"
+    android:paddingRight="7dp"
+    android:paddingTop="6dp"
+    android:paddingBottom="6dp"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal"
+
+>
+        <ImageButton android:id="@+id/one"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_1_no_vm"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_one"
+        />
+
+        <ImageButton android:id="@+id/two"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_2"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_two"
+        />
+
+        <ImageButton android:id="@+id/three"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_3"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_three"
+        />
+
+        <ImageButton android:id="@+id/four"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_4"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_four"
+        />
+
+        <ImageButton android:id="@+id/five"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_5"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_five"
+        />
+
+        <ImageButton android:id="@+id/six"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_6"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_six"
+        />
+
+        <ImageButton android:id="@+id/seven"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_7"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_seven"
+        />
+
+        <ImageButton android:id="@+id/eight"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_8"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_eight"
+        />
+
+        <ImageButton android:id="@+id/nine"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_9"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_nine"
+        />
+
+        <ImageButton android:id="@+id/star"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_star"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_star"
+        />
+
+        <ImageButton android:id="@+id/zero"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_0"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_zero"
+        />
+
+        <ImageButton android:id="@+id/pound"
+            android:layout_width="88dp"
+            android:layout_height="58dp"
+            android:src="@drawable/dial_num_pound"
+            android:background="@drawable/btn_dial"
+            android:soundEffectsEnabled="false"
+            android:contentDescription="@string/description_image_button_pound"
+        />
+</com.android.contacts.ButtonGridLayout>
diff --git a/res/layout-long-finger/twelve_key_dialer.xml b/res/layout-long-finger/twelve_key_dialer.xml
new file mode 100644
index 0000000..77f471e
--- /dev/null
+++ b/res/layout-long-finger/twelve_key_dialer.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/top"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical"
+>
+
+    <!-- Text field above the keypad where the digits are displayed -->
+    <!-- TODO: Use a textAppearance to control the display of the number -->
+    <EditText android:id="@+id/digits"
+        android:layout_width="fill_parent"
+        android:layout_height="74dip"
+        android:layout_marginBottom="20dip"
+        android:gravity="center"
+        android:maxLines="1"
+        android:scrollHorizontally="true"
+        android:textSize="34sp"
+        android:freezesText="true"
+        android:background="@drawable/btn_dial_textfield"
+        android:textColor="@color/dialer_button_text"
+        android:focusableInTouchMode="false"
+    />
+
+    <!-- Keypad section -->
+    <include layout="@layout/dialpad" />
+
+    <!-- Horizontal row of buttons (Voicemail + DialButton + Delete.) -->
+    <include layout="@layout/voicemail_dial_delete" />
+
+    <!-- "Dialpad chooser" UI, shown only when the user brings up the
+         Dialer while a call is already in progress.
+         When this UI is visible, the other Dialer elements
+         (the textfield/button and the dialpad) are hidden. -->
+    <ListView android:id="@+id/dialpadChooser"
+        android:layout_width="fill_parent"
+        android:layout_height="1dip"
+        android:layout_weight="1"
+    />
+
+</LinearLayout>
diff --git a/res/layout-long-finger/voicemail_dial_delete.xml b/res/layout-long-finger/voicemail_dial_delete.xml
new file mode 100644
index 0000000..58c482b
--- /dev/null
+++ b/res/layout-long-finger/voicemail_dial_delete.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Horizontal row of buttons (Voicemail + DialButton + Delete.)
+     Tall screen version with taller buttons.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/voicemailAndDialAndDelete"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal"
+    android:layout_marginTop="24dip"
+    android:orientation="horizontal">
+
+    <!-- Onscreen "Voicemail" button -->
+    <ImageButton android:id="@+id/voicemailButton"
+        android:layout_width="87dip"
+        android:layout_height="58dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_voicemail"
+        android:src="@drawable/ic_dial_action_voice_mail" />
+
+    <!-- Onscreen "Dial" button, used on all platforms by
+         default. Its usage can be disabled using resources (see
+         config.xml.) -->
+    <ImageButton android:id="@+id/dialButton"
+        android:layout_width="116dip"
+        android:layout_height="58dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_action"
+        android:src="@drawable/ic_dial_action_call" />
+
+    <!-- Onscreen "Backspace/Delete" button -->
+    <ImageButton android:id="@+id/deleteButton"
+        android:layout_width="87dip"
+        android:layout_height="58dip"
+        android:layout_gravity="center_vertical"
+        android:state_enabled="false"
+        android:background="@drawable/btn_dial_delete"
+        android:src="@drawable/ic_dial_action_delete" />
+</LinearLayout>
+
diff --git a/res/layout-long-land-finger/twelve_key_dialer.xml b/res/layout-long-land-finger/twelve_key_dialer.xml
new file mode 100644
index 0000000..618792a
--- /dev/null
+++ b/res/layout-long-land-finger/twelve_key_dialer.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/top"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical"
+>
+
+    <!-- Text field above the keypad where the digits are displayed -->
+    <!-- TODO: Use a textAppearance to control the display of the number -->
+    <EditText android:id="@+id/digits"
+        android:layout_width="fill_parent"
+        android:layout_height="74dip"
+        android:layout_marginBottom="30dip"
+        android:layout_marginTop="1dip"
+        android:gravity="center"
+        android:maxLines="1"
+        android:scrollHorizontally="true"
+        android:textSize="34sp"
+        android:freezesText="true"
+        android:background="@drawable/btn_dial_textfield"
+        android:textColor="@color/dialer_button_text"
+        android:hint="@string/dialerKeyboardHintText"
+     />
+
+    <!-- Horizontal row of buttons (Voicemail + DialButton + Delete.) -->
+    <include layout="@layout/voicemail_dial_delete" />
+
+    <!-- "Dialpad chooser" UI, shown only when the user brings up the
+         Dialer while a call is already in progress.
+         When this UI is visible, the other Dialer elements
+         (the textfield and button) are hidden. -->
+    <ListView android:id="@+id/dialpadChooser"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:footerDividersEnabled="true"
+    />
+
+</LinearLayout>
diff --git a/src/com/android/contacts/ButtonGridLayout.java b/src/com/android/contacts/ButtonGridLayout.java
index 69eed97..c3fb1d9 100644
--- a/src/com/android/contacts/ButtonGridLayout.java
+++ b/src/com/android/contacts/ButtonGridLayout.java
@@ -18,13 +18,40 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.View.MeasureSpec;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.MeasureSpec;
 
+/**
+ * Create a 4x3 grid of dial buttons.
+ *
+ * It was easier and more efficient to do it this way than use
+ * standard layouts. It's perfectly fine (and actually encouraged) to
+ * use custom layouts rather than piling up standard layouts.
+ *
+ * The horizontal and vertical spacings between buttons are controlled
+ * by the amount of padding (attributes on the ButtonGridLayout element):
+ *   - horizontal = left + right padding and
+ *   - vertical = top + bottom padding.
+ *
+ * This class assumes that all the buttons have the same size.
+ *
+ * Invocation: onMeasure is called first by the framework to know our
+ * size. Then onLayout is invoked to layout the buttons.
+ */
+// TODO: Blindly layout the buttons w/o checking if we overrun the
+// bottom-right corner.
 public class ButtonGridLayout extends ViewGroup {
+    private final int COLUMNS = 3;
+    private final int ROWS = 4;
 
-    private final int mColumns = 3;
+    // Width and height of a button
+    private int mButtonWidth;
+    private int mButtonHeight;
+
+    // Width and height of a button + padding.
+    private int mWidthInc;
+    private int mHeightInc;
 
     public ButtonGridLayout(Context context) {
         super(context);
@@ -40,64 +67,43 @@
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int i = 0;
         int y = mPaddingTop;
-        final int rows = getRows();
-        final View child0 = getChildAt(0);
-        final int yInc = (getHeight() - mPaddingTop - mPaddingBottom) / rows;
-        final int xInc = (getWidth() - mPaddingLeft - mPaddingRight) / mColumns;
-        final int childWidth = child0.getMeasuredWidth();
-        final int childHeight = child0.getMeasuredHeight();
-        final int xOffset = (xInc - childWidth) / 2;
-        final int yOffset = (yInc - childHeight) / 2;
-
-        for (int row = 0; row < rows; row++) {
+        for (int row = 0; row < ROWS; row++) {
             int x = mPaddingLeft;
-            for (int col = 0; col < mColumns; col++) {
-                int cell = row * mColumns + col;
-                if (cell >= getChildCount()) {
-                    break;
-                }
-                View child = getChildAt(cell);
-                child.layout(x + xOffset, y + yOffset,
-                        x + xOffset + childWidth,
-                        y + yOffset + childHeight);
-                x += xInc;
-            }
-            y += yInc;
-        }
-    }
+            for (int col = 0; col < COLUMNS; col++) {
+                View child = getChildAt(i);
 
-    private int getRows() {
-        return (getChildCount() + mColumns - 1) / mColumns;
-    }
+                child.layout(x, y, x + mButtonWidth, y + mButtonHeight);
+
+                x += mWidthInc;
+                i++;
+            }
+            y += mHeightInc;
+        }
+      }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int width = mPaddingLeft + mPaddingRight;
-        int height = mPaddingTop + mPaddingBottom;
-
-        // Measure the first child and get it's size
+          // Measure the first child and get it's size
         View child = getChildAt(0);
         child.measure(MeasureSpec.UNSPECIFIED , MeasureSpec.UNSPECIFIED);
-        int childWidth = child.getMeasuredWidth();
-        int childHeight = child.getMeasuredHeight();
+
         // Make sure the other children are measured as well, to initialize
         for (int i = 1; i < getChildCount(); i++) {
             getChildAt(i).measure(MeasureSpec.UNSPECIFIED , MeasureSpec.UNSPECIFIED);
         }
-        // All cells are going to be the size of the first child
-        width += mColumns * childWidth;
-        final int finalWidth = resolveSize(width, widthMeasureSpec);
 
-        // The vertical padding between button must be the same as the
-        // horizontal one. The cumulative horizontal padding is the
-        // difference between 'width' and 'finalWidth'.
-        final int padding = (finalWidth - width) / mColumns;
+        // Store these to be reused in onLayout.
+        mButtonWidth = child.getMeasuredWidth();
+        mButtonHeight = child.getMeasuredHeight();
+        mWidthInc = mButtonWidth + mPaddingLeft + mPaddingRight;
+        mHeightInc = mButtonHeight + mPaddingTop + mPaddingBottom;
 
-        height += getRows() * (childHeight + padding);
+        final int width = resolveSize(COLUMNS * mWidthInc, widthMeasureSpec);
+        final int height = resolveSize(ROWS * mHeightInc, heightMeasureSpec);
 
-        final int finalHeight = resolveSize(height, heightMeasureSpec);
-        setMeasuredDimension(finalWidth, finalHeight);
+        setMeasuredDimension(width, height);
     }
 
 }