Merge "Updating NumberPicker, TimePicker, DatePicker to fit different screen and font sizes." into ics-mr1

This commit is contained in:
Svetoslav Ganov
2011-11-02 10:13:17 -07:00
committed by Android (Google) Code Review
8 changed files with 148 additions and 118 deletions

View File

@@ -202,6 +202,11 @@ public class NumberPicker extends LinearLayout {
*/
private final EditText mInputText;
/**
* The min height of this widget.
*/
private final int mMinHeight;
/**
* The max height of this widget.
*/
@@ -210,7 +215,17 @@ public class NumberPicker extends LinearLayout {
/**
* The max width of this widget.
*/
private final int mMaxWidth;
private final int mMinWidth;
/**
* The max width of this widget.
*/
private int mMaxWidth;
/**
* Flag whether to compute the max width.
*/
private final boolean mComputeMaxWidth;
/**
* The height of the text.
@@ -527,8 +542,19 @@ public class NumberPicker extends LinearLayout {
getResources().getDisplayMetrics());
mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);
mMaxHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxHeight, 0);
mMaxWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxWidth, 0);
mMinHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minHeight, 0);
mMaxHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxHeight,
Integer.MAX_VALUE);
if (mMinHeight > mMaxHeight) {
throw new IllegalArgumentException("minHeight > maxHeight");
}
mMinWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minWidth, 0);
mMaxWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxWidth,
Integer.MAX_VALUE);
if (mMinWidth > mMaxWidth) {
throw new IllegalArgumentException("minWidth > maxWidth");
}
mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
attributesArray.recycle();
mShowInputControlsAnimimationDuration = getResources().getInteger(
@@ -677,37 +703,33 @@ public class NumberPicker extends LinearLayout {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mMaxHeight <= 0 && mMaxWidth <= 0) {
super.onLayout(changed, left, top, right, bottom);
} else {
final int msrdWdth = getMeasuredWidth();
final int msrdHght = getMeasuredHeight();
final int msrdWdth = getMeasuredWidth();
final int msrdHght = getMeasuredHeight();
// Increment button at the top.
final int inctBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
final int incrBtnLeft = (msrdWdth - inctBtnMsrdWdth) / 2;
final int incrBtnTop = 0;
final int incrBtnRight = incrBtnLeft + inctBtnMsrdWdth;
final int incrBtnBottom = incrBtnTop + mIncrementButton.getMeasuredHeight();
mIncrementButton.layout(incrBtnLeft, incrBtnTop, incrBtnRight, incrBtnBottom);
// Increment button at the top.
final int inctBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
final int incrBtnLeft = (msrdWdth - inctBtnMsrdWdth) / 2;
final int incrBtnTop = 0;
final int incrBtnRight = incrBtnLeft + inctBtnMsrdWdth;
final int incrBtnBottom = incrBtnTop + mIncrementButton.getMeasuredHeight();
mIncrementButton.layout(incrBtnLeft, incrBtnTop, incrBtnRight, incrBtnBottom);
// Input text centered horizontally.
final int inptTxtMsrdWdth = mInputText.getMeasuredWidth();
final int inptTxtMsrdHght = mInputText.getMeasuredHeight();
final int inptTxtLeft = (msrdWdth - inptTxtMsrdWdth) / 2;
final int inptTxtTop = (msrdHght - inptTxtMsrdHght) / 2;
final int inptTxtRight = inptTxtLeft + inptTxtMsrdWdth;
final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght;
mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom);
// Input text centered horizontally.
final int inptTxtMsrdWdth = mInputText.getMeasuredWidth();
final int inptTxtMsrdHght = mInputText.getMeasuredHeight();
final int inptTxtLeft = (msrdWdth - inptTxtMsrdWdth) / 2;
final int inptTxtTop = (msrdHght - inptTxtMsrdHght) / 2;
final int inptTxtRight = inptTxtLeft + inptTxtMsrdWdth;
final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght;
mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom);
// Decrement button at the top.
final int decrBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
final int decrBtnLeft = (msrdWdth - decrBtnMsrdWdth) / 2;
final int decrBtnTop = msrdHght - mDecrementButton.getMeasuredHeight();
final int decrBtnRight = decrBtnLeft + decrBtnMsrdWdth;
final int decrBtnBottom = msrdHght;
mDecrementButton.layout(decrBtnLeft, decrBtnTop, decrBtnRight, decrBtnBottom);
}
// Decrement button at the top.
final int decrBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
final int decrBtnLeft = (msrdWdth - decrBtnMsrdWdth) / 2;
final int decrBtnTop = msrdHght - mDecrementButton.getMeasuredHeight();
final int decrBtnRight = decrBtnLeft + decrBtnMsrdWdth;
final int decrBtnBottom = msrdHght;
mDecrementButton.layout(decrBtnLeft, decrBtnTop, decrBtnRight, decrBtnBottom);
if (!mScrollWheelAndFadingEdgesInitialized) {
mScrollWheelAndFadingEdgesInitialized = true;
@@ -719,20 +741,9 @@ public class NumberPicker extends LinearLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int measuredWidth;
if (mMaxWidth > 0) {
measuredWidth = getMaxSize(widthMeasureSpec, mMaxWidth);
} else {
measuredWidth = getMeasuredWidth();
}
final int measuredHeight;
if (mMaxHeight > 0) {
measuredHeight = getMaxSize(heightMeasureSpec, mMaxHeight);
} else {
measuredHeight = getMeasuredHeight();
}
setMeasuredDimension(measuredWidth, measuredHeight);
final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMinWidth, mMaxWidth);
final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMinHeight, mMaxHeight);
super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
}
@Override
@@ -1033,6 +1044,49 @@ public class NumberPicker extends LinearLayout {
invalidate();
}
/**
* Computes the max width if no such specified as an attribute.
*/
private void tryComputeMaxWidth() {
if (!mComputeMaxWidth) {
return;
}
int maxTextWidth = 0;
if (mDisplayedValues == null) {
float maxDigitWidth = 0;
for (int i = 0; i <= 9; i++) {
final float digitWidth = mSelectorWheelPaint.measureText(String.valueOf(i));
if (digitWidth > maxDigitWidth) {
maxDigitWidth = digitWidth;
}
}
int numberOfDigits = 0;
int current = mMaxValue;
while (current > 0) {
numberOfDigits++;
current = current / 10;
}
maxTextWidth = (int) (numberOfDigits * maxDigitWidth);
} else {
final int valueCount = mDisplayedValues.length;
for (int i = 0; i < valueCount; i++) {
final float textWidth = mSelectorWheelPaint.measureText(mDisplayedValues[i]);
if (textWidth > maxTextWidth) {
maxTextWidth = (int) textWidth;
}
}
}
maxTextWidth += mInputText.getPaddingLeft() + mInputText.getPaddingRight();
if (mMaxWidth != maxTextWidth) {
if (maxTextWidth > mMinWidth) {
mMaxWidth = maxTextWidth;
} else {
mMaxWidth = mMinWidth;
}
invalidate();
}
}
/**
* Gets whether the selector wheel wraps when reaching the min/max value.
*
@@ -1119,6 +1173,7 @@ public class NumberPicker extends LinearLayout {
setWrapSelectorWheel(wrapSelectorWheel);
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
}
/**
@@ -1150,6 +1205,7 @@ public class NumberPicker extends LinearLayout {
setWrapSelectorWheel(wrapSelectorWheel);
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
}
/**
@@ -1298,24 +1354,28 @@ public class NumberPicker extends LinearLayout {
}
/**
* Gets the max value for a size based on the measure spec passed by
* the parent and the max value for that size.
* Makes a measure spec that tries greedily to use the max value.
*
* @param measureSpec The measure spec.
* @param maxValue The max value for the size.
* @return The max size.
* @return A measure spec greedily imposing the max size.
*/
private int getMaxSize(int measureSpec, int maxValue) {
private int makeMeasureSpec(int measureSpec, int minValue, int maxValue) {
final int size = MeasureSpec.getSize(measureSpec);
if (size < minValue) {
throw new IllegalArgumentException("Available space is less than min size: "
+ size + " < " + minValue);
}
final int mode = MeasureSpec.getMode(measureSpec);
switch (mode) {
case MeasureSpec.EXACTLY:
return MeasureSpec.getSize(measureSpec);
return measureSpec;
case MeasureSpec.AT_MOST:
return Math.min(MeasureSpec.getSize(measureSpec), maxValue);
return MeasureSpec.makeMeasureSpec(Math.min(size, maxValue), MeasureSpec.EXACTLY);
case MeasureSpec.UNSPECIFIED:
return maxValue;
return MeasureSpec.makeMeasureSpec(maxValue, MeasureSpec.EXACTLY);
default:
throw new IllegalArgumentException();
throw new IllegalArgumentException("Unknown measure mode: " + mode);
}
}

View File

@@ -22,4 +22,6 @@
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:spinnersShown="true"
android:calendarViewShown="true"
/>

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageButton android:id="@+id/increment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/numberPickerUpButtonStyle"
android:contentDescription="@string/number_picker_increment_button" />
<EditText android:id="@+id/numberpicker_input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/numberPickerInputTextStyle" />
<ImageButton android:id="@+id/decrement"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/numberPickerDownButtonStyle"
android:contentDescription="@string/number_picker_decrement_button" />
</merge>

View File

@@ -40,7 +40,7 @@
<!-- Month -->
<NumberPicker
android:id="@+id/month"
android:layout_width="80dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
@@ -51,7 +51,7 @@
<!-- Day -->
<NumberPicker
android:id="@+id/day"
android:layout_width="80dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
@@ -62,7 +62,7 @@
<!-- Year -->
<NumberPicker
android:id="@+id/year"
android:layout_width="95dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"

View File

@@ -23,8 +23,8 @@
depending on the date format selected by the user.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:gravity="center">
@@ -32,7 +32,6 @@
<LinearLayout android:id="@+id/pickers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="22dip"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center">
@@ -40,10 +39,10 @@
<!-- Month -->
<NumberPicker
android:id="@+id/month"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dip"
android:layout_marginRight="22dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -51,10 +50,10 @@
<!-- Day -->
<NumberPicker
android:id="@+id/day"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dip"
android:layout_marginRight="22dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -62,10 +61,10 @@
<!-- Year -->
<NumberPicker
android:id="@+id/year"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dip"
android:layout_marginRight="22dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>

View File

@@ -28,10 +28,10 @@
<!-- hour -->
<NumberPicker
android:id="@+id/hour"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dip"
android:layout_marginRight="20dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="14dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -47,10 +47,10 @@
<!-- minute -->
<NumberPicker
android:id="@+id/minute"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="22dip"
android:layout_marginLeft="14dip"
android:layout_marginRight="16dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -58,10 +58,10 @@
<!-- AM / PM -->
<NumberPicker
android:id="@+id/amPm"
android:layout_width="48dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dip"
android:layout_marginRight="22dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>

View File

@@ -3576,8 +3576,14 @@
<attr name="selectionDivider" format="reference" />
<!-- @hide The height of the selection divider. -->
<attr name="selectionDividerHeight" format="dimension" />
<!-- @hide The min height of the NumberPicker. -->
<attr name="minHeight" />
<!-- @hide The max height of the NumberPicker. -->
<attr name="maxHeight" />
<!-- @hide The min width of the NumberPicker. -->
<attr name="minWidth" />
<!-- @hide The max width of the NumberPicker. -->
<attr name="maxWidth" />
<!-- @hide The max width of the NumberPicker. -->
<attr name="maxWidth" />
</declare-styleable>

View File

@@ -1654,8 +1654,8 @@ please see styles_device_defaults.xml.
<item name="android:flingable">true</item>
<item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
<item name="android:selectionDividerHeight">2dip</item>
<item name="android:maxHeight">180dip</item>
<item name="android:maxWidth">56dip</item>
<item name="android:minWidth">48dip</item>
<item name="android:maxHeight">200dip</item>
</style>
<style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
@@ -1684,6 +1684,8 @@ please see styles_device_defaults.xml.
<style name="Widget.Holo.EditText.NumberPickerInputText">
<item name="android:paddingTop">13sp</item>
<item name="android:paddingBottom">13sp</item>
<item name="android:paddingLeft">2sp</item>
<item name="android:paddingRight">2sp</item>
<item name="android:gravity">center</item>
<item name="android:singleLine">true</item>
<item name="android:textSize">18sp</item>