From e39af763e7bf598306feab4a3d2e1164c9f0421a Mon Sep 17 00:00:00 2001 From: linyuh Date: Fri, 27 Oct 2017 14:19:14 -0700 Subject: Make dialpad key alignment responsive to font size. In portrait mode, we surround the icon and letters with a linear layout so that we can adjust its height. In landscape mode, we add a horizontal placeholder to each key's layout so that we can adjust its width. This approach was put forward by Ryan Oldenburg (roldenburg@). Bug: 30215380 Test: Manual PiperOrigin-RevId: 173717443 Change-Id: I9b60657ca20d371a60c303a9683578663fc28a09 --- .../android/dialer/dialpadview/DialpadView.java | 177 ++++++++++++++++----- .../dialpadview/res/layout-land/dialpad_key.xml | 23 ++- .../res/layout-land/dialpad_key_one.xml | 20 ++- .../res/layout-land/dialpad_key_pound.xml | 9 +- .../res/layout-land/dialpad_key_star.xml | 9 +- .../res/layout-land/dialpad_key_zero.xml | 9 +- .../dialer/dialpadview/res/layout/dialpad_key.xml | 28 ++-- .../dialpadview/res/layout/dialpad_key_one.xml | 49 +++--- .../dialpadview/res/layout/dialpad_key_pound.xml | 17 +- .../dialpadview/res/layout/dialpad_key_star.xml | 17 +- .../dialpadview/res/layout/dialpad_key_zero.xml | 25 ++- 11 files changed, 271 insertions(+), 112 deletions(-) (limited to 'java/com/android/dialer/dialpadview') diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java index 0c53273a4..d70b0a6c2 100644 --- a/java/com/android/dialer/dialpadview/DialpadView.java +++ b/java/com/android/dialer/dialpadview/DialpadView.java @@ -39,6 +39,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.animation.AnimUtils; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; import java.text.DecimalFormat; @@ -50,16 +51,13 @@ public class DialpadView extends LinearLayout { private static final String TAG = DialpadView.class.getSimpleName(); + // Parameters for animation private static final double DELAY_MULTIPLIER = 0.66; private static final double DURATION_MULTIPLIER = 0.8; - // For animation. private static final int KEY_FRAME_DURATION = 33; - /** {@code True} if the dialpad is in landscape orientation. */ - private final boolean mIsLandscape; - /** {@code True} if the dialpad is showing in a right-to-left locale. */ - private final boolean mIsRtl; - private final int[] mButtonIds = + // Resource IDs for buttons (0-9, *, and #) + private static final int[] BUTTON_IDS = new int[] { R.id.zero, R.id.one, @@ -74,6 +72,30 @@ public class DialpadView extends LinearLayout { R.id.star, R.id.pound }; + + // Resource IDs for the button-letter mapping + private static final int[] LETTER_MAPPING_IDS = + new int[] { + R.string.dialpad_0_letters, + R.string.dialpad_1_letters, + R.string.dialpad_2_letters, + R.string.dialpad_3_letters, + R.string.dialpad_4_letters, + R.string.dialpad_5_letters, + R.string.dialpad_6_letters, + R.string.dialpad_7_letters, + R.string.dialpad_8_letters, + R.string.dialpad_9_letters, + R.string.dialpad_star_letters, + R.string.dialpad_pound_letters + }; + + // Whether the device is in landscape mode + private final boolean mIsLandscape; + + // Whether the dialpad is shown in a right-to-left locale + private final boolean mIsRtl; + private EditText mDigits; private ImageButton mDelete; private View mOverflowMenuButton; @@ -110,6 +132,8 @@ public class DialpadView extends LinearLayout { @Override protected void onFinishInflate() { + super.onFinishInflate(); + setupKeypad(); mDigits = (EditText) findViewById(R.id.digits); mDelete = (ImageButton) findViewById(R.id.deleteButton); @@ -127,28 +151,8 @@ public class DialpadView extends LinearLayout { } private void setupKeypad() { - final int[] letterIds = - new int[] { - R.string.dialpad_0_letters, - R.string.dialpad_1_letters, - R.string.dialpad_2_letters, - R.string.dialpad_3_letters, - R.string.dialpad_4_letters, - R.string.dialpad_5_letters, - R.string.dialpad_6_letters, - R.string.dialpad_7_letters, - R.string.dialpad_8_letters, - R.string.dialpad_9_letters, - R.string.dialpad_star_letters, - R.string.dialpad_pound_letters - }; - final Resources resources = getContext().getResources(); - DialpadKeyButton dialpadKey; - TextView numberView; - TextView lettersView; - final Locale currentLocale = resources.getConfiguration().locale; final NumberFormat nf; // We translate dialpad numbers only for "fa" and not any other locale @@ -159,17 +163,16 @@ public class DialpadView extends LinearLayout { nf = DecimalFormat.getInstance(Locale.ENGLISH); } - for (int i = 0; i < mButtonIds.length; i++) { - dialpadKey = (DialpadKeyButton) findViewById(mButtonIds[i]); - numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number); - lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters); + for (int i = 0; i < BUTTON_IDS.length; i++) { + DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(BUTTON_IDS[i]); + TextView numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number); final String numberString; final CharSequence numberContentDescription; - if (mButtonIds[i] == R.id.pound) { + if (BUTTON_IDS[i] == R.id.pound) { numberString = resources.getString(R.string.dialpad_pound_number); numberContentDescription = numberString; - } else if (mButtonIds[i] == R.id.star) { + } else if (BUTTON_IDS[i] == R.id.star) { numberString = resources.getString(R.string.dialpad_star_number); numberContentDescription = numberString; } else { @@ -177,7 +180,7 @@ public class DialpadView extends LinearLayout { // The content description is used for Talkback key presses. The number is // separated by a "," to introduce a slight delay. Convert letters into a verbatim // span so that they are read as letters instead of as one word. - String letters = resources.getString(letterIds[i]); + String letters = resources.getString(LETTER_MAPPING_IDS[i]); Spannable spannable = Spannable.Factory.getInstance().newSpannable(numberString + "," + letters); spannable.setSpan( @@ -199,8 +202,9 @@ public class DialpadView extends LinearLayout { dialpadKey.setContentDescription(numberContentDescription); dialpadKey.setBackground(rippleBackground); + TextView lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters); if (lettersView != null) { - lettersView.setText(resources.getString(letterIds[i])); + lettersView.setText(resources.getString(LETTER_MAPPING_IDS[i])); } } @@ -211,6 +215,103 @@ public class DialpadView extends LinearLayout { zero.setLongHoverContentDescription(resources.getText(R.string.description_image_button_plus)); } + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + + if (changed) { + if (mIsLandscape) { + adjustKeyWidths(); + } else { + adjustKeyHeightsInFirstRow(); + } + } + } + + /** + * Adjust key heights in the first row. + * + *

A voice mail icon is shown under key "1", which makes its height different from other keys + * in the first row. + * + *

This method should be called after the sizes of related layouts have been calculated by the + * framework. + */ + private void adjustKeyHeightsInFirstRow() { + int maxHeight = 0; + for (int i = 1; i <= 3; i++) { + DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(BUTTON_IDS[i]); + LinearLayout keyLayout = (LinearLayout) dialpadKey.findViewById(R.id.dialpad_key_layout); + maxHeight = Math.max(maxHeight, keyLayout.getHeight()); + } + + for (int i = 1; i <= 3; i++) { + DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(BUTTON_IDS[i]); + LinearLayout keyLayout = (LinearLayout) dialpadKey.findViewById(R.id.dialpad_key_layout); + + DialpadTextView numberView = + (DialpadTextView) keyLayout.findViewById(R.id.dialpad_key_number); + MarginLayoutParams numberViewLayoutParams = (MarginLayoutParams) numberView.getLayoutParams(); + + LinearLayout iconOrLettersLayout = + (LinearLayout) keyLayout.findViewById(R.id.dialpad_key_icon_or_letters_layout); + iconOrLettersLayout.setLayoutParams( + new LayoutParams( + LayoutParams.WRAP_CONTENT /* width */, + maxHeight + - numberView.getHeight() + - numberViewLayoutParams.topMargin + - numberViewLayoutParams.bottomMargin /* height */)); + } + } + + /** + * Adjust key widths to align keys in each column. + * + *

When the device is in landscape mode, we first find the maximum among a pre-defined width + * and the width of each key layout. Then we adjust the width of each layout's horizontal + * placeholder to align keys in each column. This is to accommodate the scenario where not all + * letters associated with a key can be displayed in one line due to large font size. + * + *

This method should be called after the sizes of related layouts have been calculated by the + * framework. + */ + private void adjustKeyWidths() { + Assert.checkState(mIsLandscape); + + // A pre-defined minimum width for the letters shown beside a key. + final int minimumKeyLettersWidth = + getContext().getResources().getDimensionPixelSize(R.dimen.dialpad_key_text_width); + + // The maximum width of the key layouts. A key layout includes both the number and the letters. + int maxWidth = 0; + + for (int buttonId : BUTTON_IDS) { + DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(buttonId); + LinearLayout keyLayout = (LinearLayout) dialpadKey.findViewById(R.id.dialpad_key_layout); + TextView keyLettersView = (TextView) keyLayout.findViewById(R.id.dialpad_key_letters); + if (keyLettersView != null && keyLettersView.getWidth() < minimumKeyLettersWidth) { + // If the width of the letters is less than the pre-defined minimum, use the pre-defined + // minimum to obtain the maximum width. + maxWidth = + Math.max( + maxWidth, + keyLayout.getWidth() - keyLettersView.getWidth() + minimumKeyLettersWidth); + } else { + maxWidth = Math.max(maxWidth, keyLayout.getWidth()); + } + } + + for (int buttonId : BUTTON_IDS) { + DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(buttonId); + LinearLayout keyLayout = (LinearLayout) dialpadKey.findViewById(R.id.dialpad_key_layout); + View horizontalPlaceholder = keyLayout.findViewById(R.id.dialpad_key_horizontal_placeholder); + horizontalPlaceholder.setLayoutParams( + new LayoutParams( + maxWidth - keyLayout.getWidth() /* width */, LayoutParams.MATCH_PARENT /* height */)); + } + } + private Drawable getDrawableCompat(Context context, int id) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return context.getDrawable(id); @@ -275,10 +376,10 @@ public class DialpadView extends LinearLayout { // numbers appear at their original position (0) momentarily before animating. final AnimatorListenerAdapter showListener = new AnimatorListenerAdapter() {}; - for (int i = 0; i < mButtonIds.length; i++) { - int delay = (int) (getKeyButtonAnimationDelay(mButtonIds[i]) * DELAY_MULTIPLIER); - int duration = (int) (getKeyButtonAnimationDuration(mButtonIds[i]) * DURATION_MULTIPLIER); - final DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(mButtonIds[i]); + for (int i = 0; i < BUTTON_IDS.length; i++) { + int delay = (int) (getKeyButtonAnimationDelay(BUTTON_IDS[i]) * DELAY_MULTIPLIER); + int duration = (int) (getKeyButtonAnimationDuration(BUTTON_IDS[i]) * DURATION_MULTIPLIER); + final DialpadKeyButton dialpadKey = (DialpadKeyButton) findViewById(BUTTON_IDS[i]); ViewPropertyAnimator animator = dialpadKey.animate(); if (mIsLandscape) { diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key.xml index b126f723f..12f24ac52 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key.xml @@ -14,12 +14,13 @@ limitations under the License. --> - + - + + + + + + + + diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml index 5023413ae..2f2e725d5 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml @@ -13,12 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> + + - + + - + + + + + diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_pound.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_pound.xml index a3e0c7c14..613e73108 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_pound.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_pound.xml @@ -13,12 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> + + + + android:id="@+id/dialpad_key_horizontal_placeholder" + android:layout_width="0dp" + android:layout_height="match_parent"/> diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_star.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_star.xml index 18dc1cb49..2b0a6b554 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_star.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_star.xml @@ -13,12 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> + + + + android:id="@+id/dialpad_key_horizontal_placeholder" + android:layout_width="0dp" + android:layout_height="match_parent"/> diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_zero.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_zero.xml index 4c46447d4..714507202 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_zero.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_zero.xml @@ -21,6 +21,7 @@ style="@style/DialpadKeyButtonStyle"> + style="@style/DialpadKeyLettersStyle"/> + + diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key.xml index 77e4fc53a..6c87cd2b4 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key.xml @@ -14,22 +14,26 @@ limitations under the License. --> - + + xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/DialpadKeyButtonStyle"> - - - + + android:id="@+id/dialpad_key_number" + style="@style/DialpadKeyNumberStyle"/> + + - + + diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml index 4401c5bbd..599c2d8e6 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml @@ -13,29 +13,40 @@ See the License for the specific language governing permissions and limitations under the License. --> + + + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/one" + style="@style/DialpadKeyButtonStyle"> + + - + android:id="@+id/dialpad_key_number" + style="@style/DialpadKeyNumberStyle"/> + + + + + + - - - + android:id="@+id/dialpad_key_voicemail" + android:layout_width="wrap_content" + android:layout_height="@dimen/dialpad_voicemail_icon_size" + android:scaleType="fitCenter" + android:src="@drawable/quantum_ic_voicemail_white_24" + android:tint="?attr/dialpad_voicemail_tint"/> + diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_pound.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_pound.xml index d37a6aa78..5e47ac092 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_pound.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_pound.xml @@ -13,14 +13,19 @@ See the License for the specific language governing permissions and limitations under the License. --> + + + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/pound" + style="@style/DialpadKeyButtonStyle"> + + android:id="@+id/dialpad_key_layout" + style="@style/DialpadKeyInternalLayoutStyle"> + + android:id="@id/dialpad_key_number" + style="@style/DialpadKeyPoundStyle"/> diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_star.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_star.xml index d288475d0..6897d26e7 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_star.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_star.xml @@ -13,14 +13,19 @@ See the License for the specific language governing permissions and limitations under the License. --> + + + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/star" + style="@style/DialpadKeyButtonStyle"> + + android:id="@+id/dialpad_key_layout" + style="@style/DialpadKeyInternalLayoutStyle"> + + android:id="@+id/dialpad_key_number" + style="@style/DialpadKeyStarStyle"/> diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_zero.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_zero.xml index 943ae48dd..8d9c7b216 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_zero.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_zero.xml @@ -14,24 +14,21 @@ limitations under the License. --> - + + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/zero" + style="@style/DialpadKeyButtonStyle"> - - - + - + android:id="@+id/dialpad_key_number" + style="@style/DialpadBottomKeyNumberStyle"/> + android:id="@+id/dialpad_key_letters" + style="@style/DialpadKeyLettersStyle"/> -- cgit v1.2.3