am 552eca1a: Merge "Implement Material-style delegate for CalendarView" into lmp-mr1-dev

automerge: 6a6b828

* commit '6a6b828090de26aeef7d11a7cc0513a813cbf3a9':
  Implement Material-style delegate for CalendarView
This commit is contained in:
Alan Viverette
2014-11-20 21:09:34 +00:00
committed by android-build-merger
10 changed files with 1938 additions and 1604 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,260 @@
/*
* Copyright (C) 2014 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 android.widget;
import com.android.internal.R;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.MathUtils;
import java.util.Calendar;
import java.util.Locale;
import libcore.icu.LocaleData;
class CalendarViewMaterialDelegate extends CalendarView.AbstractCalendarViewDelegate {
private final DayPickerView mDayPickerView;
private CalendarView.OnDateChangeListener mOnDateChangeListener;
public CalendarViewMaterialDelegate(CalendarView delegator, Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(delegator, context);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CalendarView, defStyleAttr, defStyleRes);
final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
LocaleData.get(Locale.getDefault()).firstDayOfWeek);
final long minDate = parseDateToMillis(a.getString(
R.styleable.CalendarView_minDate), DEFAULT_MIN_DATE);
final long maxDate = parseDateToMillis(a.getString(
R.styleable.CalendarView_maxDate), DEFAULT_MAX_DATE);
if (maxDate < minDate) {
throw new IllegalArgumentException("max date cannot be before min date");
}
final long setDate = MathUtils.constrain(System.currentTimeMillis(), minDate, maxDate);
final int dateTextAppearanceResId = a.getResourceId(
R.styleable.CalendarView_dateTextAppearance,
R.style.TextAppearance_DeviceDefault_Small);
a.recycle();
mDayPickerView = new DayPickerView(context);
mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
mDayPickerView.setCalendarTextAppearance(dateTextAppearanceResId);
mDayPickerView.setMinDate(minDate);
mDayPickerView.setMaxDate(maxDate);
mDayPickerView.setDate(setDate, false, true);
mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
delegator.addView(mDayPickerView);
}
private long parseDateToMillis(String dateStr, String defaultDateStr) {
final Calendar tempCalendar = Calendar.getInstance();
if (TextUtils.isEmpty(dateStr) || !parseDate(dateStr, tempCalendar)) {
parseDate(defaultDateStr, tempCalendar);
}
return tempCalendar.getTimeInMillis();
}
@Override
public void setShownWeekCount(int count) {
// Deprecated.
}
@Override
public int getShownWeekCount() {
// Deprecated.
return 0;
}
@Override
public void setSelectedWeekBackgroundColor(int color) {
// TODO: Should use a ColorStateList. Deprecate?
}
@Override
public int getSelectedWeekBackgroundColor() {
return 0;
}
@Override
public void setFocusedMonthDateColor(int color) {
// TODO: Should use a ColorStateList. Deprecate?
}
@Override
public int getFocusedMonthDateColor() {
return 0;
}
@Override
public void setUnfocusedMonthDateColor(int color) {
// TODO: Should use a ColorStateList. Deprecate?
}
@Override
public int getUnfocusedMonthDateColor() {
return 0;
}
@Override
public void setWeekDayTextAppearance(int resourceId) {
}
@Override
public int getWeekDayTextAppearance() {
return 0;
}
@Override
public void setDateTextAppearance(int resourceId) {
}
@Override
public int getDateTextAppearance() {
return 0;
}
@Override
public void setWeekNumberColor(int color) {
// Deprecated.
}
@Override
public int getWeekNumberColor() {
// Deprecated.
return 0;
}
@Override
public void setWeekSeparatorLineColor(int color) {
// Deprecated.
}
@Override
public int getWeekSeparatorLineColor() {
// Deprecated.
return 0;
}
@Override
public void setSelectedDateVerticalBar(int resourceId) {
// Deprecated.
}
@Override
public void setSelectedDateVerticalBar(Drawable drawable) {
// Deprecated.
}
@Override
public Drawable getSelectedDateVerticalBar() {
// Deprecated.
return null;
}
@Override
public void setMinDate(long minDate) {
mDayPickerView.setMinDate(minDate);
}
@Override
public long getMinDate() {
return mDayPickerView.getMinDate();
}
@Override
public void setMaxDate(long maxDate) {
mDayPickerView.setMaxDate(maxDate);
}
@Override
public long getMaxDate() {
return mDayPickerView.getMaxDate();
}
@Override
public void setShowWeekNumber(boolean showWeekNumber) {
// Deprecated.
}
@Override
public boolean getShowWeekNumber() {
// Deprecated.
return false;
}
@Override
public void setFirstDayOfWeek(int firstDayOfWeek) {
mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
}
@Override
public int getFirstDayOfWeek() {
return mDayPickerView.getFirstDayOfWeek();
}
@Override
public void setDate(long date) {
mDayPickerView.setDate(date, true, false);
}
@Override
public void setDate(long date, boolean animate, boolean center) {
mDayPickerView.setDate(date, animate, center);
}
@Override
public long getDate() {
return mDayPickerView.getDate();
}
@Override
public void setOnDateChangeListener(CalendarView.OnDateChangeListener listener) {
mOnDateChangeListener = listener;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// Nothing to do here, configuration changes are already propagated
// by ViewGroup.
}
private final DayPickerView.OnDaySelectedListener mOnDaySelectedListener =
new DayPickerView.OnDaySelectedListener() {
@Override
public void onDaySelected(DayPickerView view, Calendar day) {
if (mOnDateChangeListener != null) {
final int year = day.get(Calendar.YEAR);
final int month = day.get(Calendar.MONTH);
final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH);
mOnDateChangeListener.onSelectedDayChange(mDelegator, year, month, dayOfMonth);
}
}
};
}

View File

@@ -185,8 +185,9 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
mDayPickerView = new DayPickerView(mContext);
mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
mDayPickerView.setRange(mMinDate, mMaxDate);
mDayPickerView.setDay(mCurrentDate);
mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
mYearPickerView = new YearPickerView(mContext);
@@ -336,7 +337,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
switch (viewIndex) {
case MONTH_AND_DAY_VIEW:
mDayPickerView.setDay(getSelectedDay());
mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
if (mCurrentView != viewIndex) {
mMonthAndDayLayout.setSelected(true);
mHeaderYearTextView.setSelected(false);
@@ -414,7 +415,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
updateDisplay(false);
}
mMinDate.setTimeInMillis(minDate);
mDayPickerView.setRange(mMinDate, mMaxDate);
mDayPickerView.setMinDate(minDate);
mYearPickerView.setRange(mMinDate, mMaxDate);
}
@@ -436,7 +437,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
updateDisplay(false);
}
mMaxDate.setTimeInMillis(maxDate);
mDayPickerView.setRange(mMinDate, mMaxDate);
mDayPickerView.setMaxDate(maxDate);
mYearPickerView.setRange(mMinDate, mMaxDate);
}
@@ -616,7 +617,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
listener.onDateChanged();
}
mDayPickerView.setDay(getSelectedDay());
mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
}
@Override

View File

@@ -58,6 +58,8 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
private Calendar mMinDate = Calendar.getInstance();
private Calendar mMaxDate = Calendar.getInstance();
private Calendar mTempCalendar;
private OnDaySelectedListener mOnDaySelectedListener;
// which month should be displayed/highlighted [0-11]
@@ -77,28 +79,65 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
setDrawSelectorOnTop(false);
setUpListView();
goTo(mSelectedDay, false, true, true);
goTo(mSelectedDay.getTimeInMillis(), false, false, true);
mAdapter.setOnDaySelectedListener(mProxyOnDaySelectedListener);
}
public void setDay(Calendar day) {
goTo(day, false, true, true);
/**
* Sets the currently selected date to the specified timestamp. Jumps
* immediately to the new date. To animate to the new date, use
* {@link #setDate(long, boolean, boolean)}.
*
* @param timeInMillis
*/
public void setDate(long timeInMillis) {
setDate(timeInMillis, false, true);
}
public void setDate(long timeInMillis, boolean animate, boolean forceScroll) {
goTo(timeInMillis, animate, true, forceScroll);
}
public long getDate() {
return mSelectedDay.getTimeInMillis();
}
public void setFirstDayOfWeek(int firstDayOfWeek) {
mAdapter.setFirstDayOfWeek(firstDayOfWeek);
}
public void setRange(Calendar minDate, Calendar maxDate) {
mMinDate.setTimeInMillis(minDate.getTimeInMillis());
mMaxDate.setTimeInMillis(maxDate.getTimeInMillis());
public int getFirstDayOfWeek() {
return mAdapter.getFirstDayOfWeek();
}
public void setMinDate(long timeInMillis) {
mMinDate.setTimeInMillis(timeInMillis);
onRangeChanged();
}
public long getMinDate() {
return mMinDate.getTimeInMillis();
}
public void setMaxDate(long timeInMillis) {
mMaxDate.setTimeInMillis(timeInMillis);
onRangeChanged();
}
public long getMaxDate() {
return mMaxDate.getTimeInMillis();
}
/**
* Handles changes to date range.
*/
public void onRangeChanged() {
mAdapter.setRange(mMinDate, mMaxDate);
// Changing the min/max date changes the selection position since we
// don't really have stable IDs.
goTo(mSelectedDay, false, true, true);
// don't really have stable IDs. Jumps immediately to the new position.
goTo(mSelectedDay.getTimeInMillis(), false, false, true);
}
/**
@@ -136,12 +175,20 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
return diffMonths;
}
private int getPositionFromDay(Calendar day) {
private int getPositionFromDay(long timeInMillis) {
final int diffMonthMax = getDiffMonths(mMinDate, mMaxDate);
final int diffMonth = getDiffMonths(mMinDate, day);
final int diffMonth = getDiffMonths(mMinDate, getTempCalendarForTime(timeInMillis));
return MathUtils.constrain(diffMonth, 0, diffMonthMax);
}
private Calendar getTempCalendarForTime(long timeInMillis) {
if (mTempCalendar == null) {
mTempCalendar = Calendar.getInstance();
}
mTempCalendar.setTimeInMillis(timeInMillis);
return mTempCalendar;
}
/**
* This moves to the specified time in the view. If the time is not already
* in range it will move the list so that the first of the month containing
@@ -157,14 +204,14 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
* visible
* @return Whether or not the view animated to the new location
*/
private boolean goTo(Calendar day, boolean animate, boolean setSelected, boolean forceScroll) {
private boolean goTo(long day, boolean animate, boolean setSelected, boolean forceScroll) {
// Set the selected day
if (setSelected) {
mSelectedDay.setTimeInMillis(day.getTimeInMillis());
mSelectedDay.setTimeInMillis(day);
}
mTempDay.setTimeInMillis(day.getTimeInMillis());
mTempDay.setTimeInMillis(day);
final int position = getPositionFromDay(day);
View child;
@@ -258,6 +305,10 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
mAdapter.setCalendarTextColor(colors);
}
void setCalendarTextAppearance(int resId) {
mAdapter.setCalendarTextAppearance(resId);
}
protected class ScrollStateRunnable implements Runnable {
private int mNewState;
private View mParent;
@@ -415,7 +466,7 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
}
private String getMonthAndYearString(Calendar day) {
StringBuffer sbuf = new StringBuffer();
final StringBuilder sbuf = new StringBuilder();
sbuf.append(day.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
sbuf.append(" ");
sbuf.append(mYearFormat.format(day.getTime()));
@@ -429,8 +480,8 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
}
/**
@@ -474,7 +525,7 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener {
// Go to that month.
announceForAccessibility(getMonthAndYearString(day));
goTo(day, true, false, true);
goTo(day.getTimeInMillis(), true, false, true);
mPerformingScroll = true;
return true;
}

View File

@@ -16,8 +16,12 @@
package android.widget;
import com.android.internal.R;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleMonthView.OnDayClickListener;
@@ -33,15 +37,14 @@ class SimpleMonthAdapter extends BaseAdapter {
private final Context mContext;
private Calendar mSelectedDay;
private ColorStateList mCalendarTextColors;
private Calendar mSelectedDay = Calendar.getInstance();
private ColorStateList mCalendarTextColors = ColorStateList.valueOf(Color.BLACK);
private OnDaySelectedListener mOnDaySelectedListener;
private int mFirstDayOfWeek;
public SimpleMonthAdapter(Context context) {
mContext = context;
mSelectedDay = Calendar.getInstance();
}
public void setRange(Calendar min, Calendar max) {
@@ -57,6 +60,10 @@ class SimpleMonthAdapter extends BaseAdapter {
notifyDataSetInvalidated();
}
public int getFirstDayOfWeek() {
return mFirstDayOfWeek;
}
/**
* Updates the selected day and related parameters.
*
@@ -81,6 +88,24 @@ class SimpleMonthAdapter extends BaseAdapter {
mCalendarTextColors = colors;
}
/**
* Sets the text color, size, style, hint color, and highlight color from
* the specified TextAppearance resource. This is mostly copied from
* {@link TextView#setTextAppearance(Context, int)}.
*/
void setCalendarTextAppearance(int resId) {
final TypedArray a = mContext.obtainStyledAttributes(resId, R.styleable.TextAppearance);
final ColorStateList textColor = a.getColorStateList(R.styleable.TextAppearance_textColor);
if (textColor != null) {
mCalendarTextColors = textColor;
}
// TODO: Support font size, etc.
a.recycle();
}
@Override
public int getCount() {
final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);

View File

@@ -4662,6 +4662,11 @@
<attr name="weekDayTextAppearance" format="reference" />
<!-- The text appearance for the calendar dates. -->
<attr name="dateTextAppearance" format="reference" />
<!-- The number of weeks to be shown. -->
<attr name="calendarViewMode">
<enum name="holo" value="0" />
<enum name="material" value="1" />
</attr>
</declare-styleable>
<declare-styleable name="NumberPicker">

View File

@@ -565,6 +565,7 @@ please see styles_device_defaults.xml.
<item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
<item name="weekDayTextAppearance">@style/TextAppearance.Small.CalendarViewWeekDayView</item>
<item name="dateTextAppearance">?attr/textAppearanceSmall</item>
<item name="calendarViewMode">holo</item>
</style>
<style name="Widget.NumberPicker">

View File

@@ -444,6 +444,7 @@ please see styles_device_defaults.xml.
<item name="weekSeparatorLineColor">#19FFFFFF</item>
<item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
<item name="weekDayTextAppearance">@style/TextAppearance.Holo.CalendarViewWeekDayView</item>
<item name="calendarViewMode">holo</item>
</style>
<style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
@@ -881,6 +882,7 @@ please see styles_device_defaults.xml.
<item name="weekNumberColor">#7F080021</item>
<item name="weekSeparatorLineColor">#7F08002A</item>
<item name="weekDayTextAppearance">@style/TextAppearance.Holo.Light.CalendarViewWeekDayView</item>
<item name="calendarViewMode">holo</item>
</style>
<style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker" />

View File

@@ -612,6 +612,7 @@ please see styles_device_defaults.xml.
<item name="weekSeparatorLineColor">#19FFFFFF</item>
<item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
<item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
<item name="calendarViewMode">material</item>
</style>
<style name="Widget.Material.ImageButton" parent="Widget.ImageButton">
@@ -999,6 +1000,7 @@ please see styles_device_defaults.xml.
<item name="weekNumberColor">#7F080021</item>
<item name="weekSeparatorLineColor">#7F08002A</item>
<item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
<item name="calendarViewMode">material</item>
</style>
<style name="Widget.Material.Light.NumberPicker" parent="Widget.Material.NumberPicker"/>