Update DatePicker widget and its related dialog
- the old DatePicker widget is still there for obvious layout compatibility reasons - add a new delegate implementation for having a new UI - use the new delegate only for the DatePickerDialog (which does not need to be the same) - added support for Theming and light/dark Themes - added support for RTL - added support for Accessibility - verified support for Keyboard - verified that CTS tests for DatePicker are passing (for both the legacy and the new widgets) Also added a new HapticFeedbackConstants.CALENDAR_DATE and its related code for enabling day selection vibration Change-Id: I256bd7c21edd8f3b910413ca15ce26d3a5ef7d9c
This commit is contained in:
@@ -359,6 +359,7 @@ package android {
|
||||
field public static final int buttonTint = 16843889; // 0x1010471
|
||||
field public static final int buttonTintMode = 16843890; // 0x1010472
|
||||
field public static final int cacheColorHint = 16843009; // 0x1010101
|
||||
field public static final int calendarTextColor = 16843931; // 0x101049b
|
||||
field public static final int calendarViewShown = 16843596; // 0x101034c
|
||||
field public static final int calendarViewStyle = 16843613; // 0x101035d
|
||||
field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
|
||||
@@ -447,6 +448,14 @@ package android {
|
||||
field public static final int dashWidth = 16843174; // 0x10101a6
|
||||
field public static final int data = 16842798; // 0x101002e
|
||||
field public static final int datePickerStyle = 16843612; // 0x101035c
|
||||
field public static final int dateSelectorBackgroundColor = 16843925; // 0x1010495
|
||||
field public static final int dateSelectorDayOfMonthTextAppearance = 16843927; // 0x1010497
|
||||
field public static final int dateSelectorDayOfWeekBackgroundColor = 16843923; // 0x1010493
|
||||
field public static final int dateSelectorDayOfWeekTextAppearance = 16843924; // 0x1010494
|
||||
field public static final int dateSelectorMonthTextAppearance = 16843926; // 0x1010496
|
||||
field public static final int dateSelectorYearListItemTextAppearance = 16843929; // 0x1010499
|
||||
field public static final int dateSelectorYearListSelectedCircleColor = 16843930; // 0x101049a
|
||||
field public static final int dateSelectorYearTextAppearance = 16843928; // 0x1010498
|
||||
field public static final int dateTextAppearance = 16843593; // 0x1010349
|
||||
field public static final int debuggable = 16842767; // 0x101000f
|
||||
field public static final int defaultValue = 16843245; // 0x10101ed
|
||||
@@ -37152,8 +37161,16 @@ package android.widget {
|
||||
ctor public DatePicker(android.content.Context, android.util.AttributeSet);
|
||||
ctor public DatePicker(android.content.Context, android.util.AttributeSet, int);
|
||||
ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int);
|
||||
method public android.content.res.ColorStateList getCalendarTextColor();
|
||||
method public android.widget.CalendarView getCalendarView();
|
||||
method public boolean getCalendarViewShown();
|
||||
method public int getDateSelectorBackgroundColor();
|
||||
method public int getDateSelectorDayOfMonthTextAppearance();
|
||||
method public int getDateSelectorDayOfWeekBackgroundColor();
|
||||
method public int getDateSelectorDayOfWeekTextAppearance();
|
||||
method public int getDateSelectorMonthTextAppearance();
|
||||
method public int getDateSelectorYearListItemTextAppearance();
|
||||
method public int getDateSelectorYearTextAppearance();
|
||||
method public int getDayOfMonth();
|
||||
method public long getMaxDate();
|
||||
method public long getMinDate();
|
||||
@@ -37161,7 +37178,15 @@ package android.widget {
|
||||
method public boolean getSpinnersShown();
|
||||
method public int getYear();
|
||||
method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener);
|
||||
method public void setCalendarTextColor(android.content.res.ColorStateList);
|
||||
method public void setCalendarViewShown(boolean);
|
||||
method public void setDateSelectorBackgroundColor(int);
|
||||
method public void setDateSelectorDayOfMonthTextAppearance(int);
|
||||
method public void setDateSelectorDayOfWeekBackgroundColor(int);
|
||||
method public void setDateSelectorDayOfWeekTextAppearance(int);
|
||||
method public void setDateSelectorMonthTextAppearance(int);
|
||||
method public void setDateSelectorYearListItemTextAppearance(int);
|
||||
method public void setDateSelectorYearTextAppearance(int);
|
||||
method public void setMaxDate(long);
|
||||
method public void setMinDate(long);
|
||||
method public void setSpinnersShown(boolean);
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.os.Bundle;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.DatePicker;
|
||||
@@ -44,10 +45,11 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener,
|
||||
private static final String DAY = "day";
|
||||
|
||||
private final DatePicker mDatePicker;
|
||||
private final OnDateSetListener mCallBack;
|
||||
private final OnDateSetListener mDateSetListener;
|
||||
private final Calendar mCalendar;
|
||||
|
||||
private boolean mTitleNeedsUpdate = true;
|
||||
private boolean mIsCanceled = false;
|
||||
|
||||
/**
|
||||
* The callback used to indicate the user is done filling in the date.
|
||||
@@ -79,29 +81,36 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener,
|
||||
this(context, 0, callBack, year, monthOfYear, dayOfMonth);
|
||||
}
|
||||
|
||||
static int resolveDialogTheme(Context context, int resid) {
|
||||
if (resid == 0) {
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true);
|
||||
return outValue.resourceId;
|
||||
} else {
|
||||
return resid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context The context the dialog is to run in.
|
||||
* @param theme the theme to apply to this dialog
|
||||
* @param callBack How the parent is notified that the date is set.
|
||||
* @param listener How the parent is notified that the date is set.
|
||||
* @param year The initial year of the dialog.
|
||||
* @param monthOfYear The initial month of the dialog.
|
||||
* @param dayOfMonth The initial day of the dialog.
|
||||
*/
|
||||
public DatePickerDialog(Context context,
|
||||
int theme,
|
||||
OnDateSetListener callBack,
|
||||
OnDateSetListener listener,
|
||||
int year,
|
||||
int monthOfYear,
|
||||
int dayOfMonth) {
|
||||
super(context, theme);
|
||||
|
||||
mCallBack = callBack;
|
||||
super(context, resolveDialogTheme(context, theme));
|
||||
|
||||
mDateSetListener = listener;
|
||||
mCalendar = Calendar.getInstance();
|
||||
|
||||
Context themeContext = getContext();
|
||||
setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
|
||||
setIcon(0);
|
||||
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
@@ -109,20 +118,53 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener,
|
||||
setView(view);
|
||||
setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
|
||||
mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
|
||||
|
||||
// Initialize state
|
||||
mDatePicker.setLegacyMode(false, null);
|
||||
mDatePicker.setShowDoneButton(true);
|
||||
mDatePicker.setDismissCallback(new DatePicker.DatePickerDismissCallback() {
|
||||
@Override
|
||||
public void dismiss(DatePicker view, boolean isCancel, int year, int month, int dayOfMonth) {
|
||||
mIsCanceled = isCancel;
|
||||
if (!isCancel) {
|
||||
mDateSetListener.onDateSet(view, year, month, dayOfMonth);
|
||||
}
|
||||
DatePickerDialog.this.dismiss();
|
||||
}
|
||||
});
|
||||
mDatePicker.init(year, monthOfYear, dayOfMonth, this);
|
||||
updateTitle(year, monthOfYear, dayOfMonth);
|
||||
}
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
tryNotifyDateSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
mIsCanceled = true;
|
||||
super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
tryNotifyDateSet();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
public void onDateChanged(DatePicker view, int year,
|
||||
int month, int day) {
|
||||
mDatePicker.init(year, month, day, this);
|
||||
updateTitle(year, month, day);
|
||||
}
|
||||
|
||||
private void tryNotifyDateSet() {
|
||||
if (mDateSetListener != null && !mIsCanceled) {
|
||||
mDatePicker.clearFocus();
|
||||
mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(),
|
||||
mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link DatePicker} contained in this dialog.
|
||||
*
|
||||
@@ -143,20 +185,6 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener,
|
||||
mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
|
||||
}
|
||||
|
||||
private void tryNotifyDateSet() {
|
||||
if (mCallBack != null) {
|
||||
mDatePicker.clearFocus();
|
||||
mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
|
||||
mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
tryNotifyDateSet();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
private void updateTitle(int year, int month, int day) {
|
||||
if (!mDatePicker.getCalendarViewShown()) {
|
||||
mCalendar.set(Calendar.YEAR, year);
|
||||
|
||||
@@ -45,6 +45,12 @@ public class HapticFeedbackConstants {
|
||||
*/
|
||||
public static final int CLOCK_TICK = 4;
|
||||
|
||||
/**
|
||||
* The user has pressed either a day or month or year date of a Calendar.
|
||||
* @hide
|
||||
*/
|
||||
public static final int CALENDAR_DATE = 5;
|
||||
|
||||
/**
|
||||
* This is a private constant. Feel free to renumber as desired.
|
||||
* @hide
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package android.widget;
|
||||
|
||||
import android.annotation.Widget;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Parcel;
|
||||
@@ -49,6 +51,8 @@ import java.util.TimeZone;
|
||||
|
||||
import libcore.icu.ICU;
|
||||
|
||||
import static android.os.Build.VERSION_CODES.L;
|
||||
|
||||
/**
|
||||
* This class is a widget for selecting a date. The date can be selected by a
|
||||
* year, month, and day spinners or a {@link CalendarView}. The set of spinners
|
||||
@@ -70,6 +74,15 @@ import libcore.icu.ICU;
|
||||
* @attr ref android.R.styleable#DatePicker_minDate
|
||||
* @attr ref android.R.styleable#DatePicker_spinnersShown
|
||||
* @attr ref android.R.styleable#DatePicker_calendarViewShown
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekBackgroundColor
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekTextAppearance
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorBackgroundColor
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorMonthTextAppearance
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfMonthTextAppearance
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearTextAppearance
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearListItemTextAppearance
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearListSelectedCircleColor
|
||||
* @attr ref android.R.styleable#DatePicker_calendarTextColor
|
||||
*/
|
||||
@Widget
|
||||
public class DatePicker extends FrameLayout {
|
||||
@@ -78,6 +91,10 @@ public class DatePicker extends FrameLayout {
|
||||
|
||||
private DatePickerDelegate mDelegate;
|
||||
|
||||
private int mDefStyleAttr;
|
||||
private int mDefStyleRes;
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* The callback used to indicate the user changes\d the date.
|
||||
*/
|
||||
@@ -110,7 +127,65 @@ public class DatePicker extends FrameLayout {
|
||||
public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
mDelegate = new LegacyDatePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
|
||||
mContext = context;
|
||||
mDefStyleAttr = defStyleAttr;
|
||||
mDefStyleRes = defStyleRes;
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
|
||||
mDefStyleAttr, mDefStyleRes);
|
||||
|
||||
// Create the correct UI delegate. Default is the legacy one.
|
||||
final boolean isLegacyMode = a.getBoolean(R.styleable.DatePicker_legacyMode,
|
||||
isLegacyMode());
|
||||
|
||||
a.recycle();
|
||||
|
||||
setLegacyMode(isLegacyMode, attrs);
|
||||
}
|
||||
|
||||
private boolean isLegacyMode() {
|
||||
UiModeManager uiModeManager =
|
||||
(UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
|
||||
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
|
||||
return true;
|
||||
}
|
||||
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
|
||||
return targetSdkVersion < L;
|
||||
}
|
||||
|
||||
private DatePickerDelegate createLegacyUIDelegate(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
return new LegacyDatePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
private DatePickerDelegate createNewUIDelegate(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
return new android.widget.DatePickerDelegate(this, context, attrs, defStyleAttr,
|
||||
defStyleRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setLegacyMode(boolean isLegacyMode, AttributeSet attrs) {
|
||||
removeAllViewsInLayout();
|
||||
mDelegate = isLegacyMode ?
|
||||
createLegacyUIDelegate(mContext, attrs, mDefStyleAttr, mDefStyleRes) :
|
||||
createNewUIDelegate(mContext, attrs, mDefStyleAttr, mDefStyleRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setShowDoneButton(boolean showDoneButton) {
|
||||
mDelegate.setShowDoneButton(showDoneButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setDismissCallback(DatePickerDismissCallback callback) {
|
||||
mDelegate.setDismissCallback(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +204,7 @@ public class DatePicker extends FrameLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current date.
|
||||
* Update the current date.
|
||||
*
|
||||
* @param year The year.
|
||||
* @param month The month which is <strong>starting from zero</strong>.
|
||||
@@ -171,7 +246,7 @@ public class DatePicker extends FrameLayout {
|
||||
* @return The minimal supported date.
|
||||
*/
|
||||
public long getMinDate() {
|
||||
return mDelegate.getMinDate();
|
||||
return mDelegate.getMinDate().getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +271,7 @@ public class DatePicker extends FrameLayout {
|
||||
* @return The maximal supported date.
|
||||
*/
|
||||
public long getMaxDate() {
|
||||
return mDelegate.getMaxDate();
|
||||
return mDelegate.getMaxDate().getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,6 +375,182 @@ public class DatePicker extends FrameLayout {
|
||||
mDelegate.setSpinnersShown(shown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the background color for the date selector's day of week.
|
||||
*
|
||||
* @param color The background color.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekBackgroundColor
|
||||
*/
|
||||
public void setDateSelectorDayOfWeekBackgroundColor(int color) {
|
||||
mDelegate.setDateSelectorDayOfWeekBackgroundColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the background color for the date selector's day of week.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekBackgroundColor
|
||||
*/
|
||||
public int getDateSelectorDayOfWeekBackgroundColor() {
|
||||
return mDelegate.getDateSelectorDayOfWeekBackgroundColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text appearance for the date selector's day of week.
|
||||
*
|
||||
* @param resId The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekTextAppearance
|
||||
*/
|
||||
public void setDateSelectorDayOfWeekTextAppearance(int resId) {
|
||||
mDelegate.setDateSelectorDayOfWeekTextAppearance(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text appearance for the date selector's day of week.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfWeekTextAppearance
|
||||
*/
|
||||
public int getDateSelectorDayOfWeekTextAppearance() {
|
||||
return mDelegate.getDateSelectorDayOfWeekTextAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the background color for the date selector's.
|
||||
*
|
||||
* @param color The background color.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorBackgroundColor
|
||||
*/
|
||||
public void setDateSelectorBackgroundColor(int color) {
|
||||
mDelegate.setDateSelectorBackgroundColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the background color for the date selector's.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorBackgroundColor
|
||||
*/
|
||||
public int getDateSelectorBackgroundColor() {
|
||||
return mDelegate.getDateSelectorBackgroundColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text appearance for the date selector's month.
|
||||
*
|
||||
* @param resId The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorMonthTextAppearance
|
||||
*/
|
||||
public void setDateSelectorMonthTextAppearance(int resId) {
|
||||
mDelegate.setDateSelectorMonthTextAppearance(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text appearance for the date selector's month.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorMonthTextAppearance
|
||||
*/
|
||||
public int getDateSelectorMonthTextAppearance() {
|
||||
return mDelegate.getDateSelectorMonthTextAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text appearance for the date selector's day of month.
|
||||
*
|
||||
* @param resId The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfMonthTextAppearance
|
||||
*/
|
||||
public void setDateSelectorDayOfMonthTextAppearance(int resId) {
|
||||
mDelegate.setDateSelectorDayOfMonthTextAppearance(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text appearance for the date selector's day of month.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorDayOfMonthTextAppearance
|
||||
*/
|
||||
public int getDateSelectorDayOfMonthTextAppearance() {
|
||||
return mDelegate.getDateSelectorDayOfMonthTextAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text appearance for the date selector's year.
|
||||
*
|
||||
* @param resId The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearTextAppearance
|
||||
*/
|
||||
public void setDateSelectorYearTextAppearance(int resId) {
|
||||
mDelegate.setDateSelectorYearTextAppearance(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text appearance for the date selector's year.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearTextAppearance
|
||||
*/
|
||||
public int getDateSelectorYearTextAppearance() {
|
||||
return mDelegate.getDateSelectorYearTextAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text appearance for the year list item.
|
||||
*
|
||||
* @param resId The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearListItemTextAppearance
|
||||
*/
|
||||
public void setDateSelectorYearListItemTextAppearance(int resId) {
|
||||
mDelegate.setDateSelectorYearListItemTextAppearance(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text appearance for the year list item.
|
||||
*
|
||||
* @return The text appearance resource id.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_dateSelectorYearListItemTextAppearance
|
||||
*/
|
||||
public int getDateSelectorYearListItemTextAppearance() {
|
||||
return mDelegate.getDateSelectorYearListItemTextAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text color state list for the calendar.
|
||||
*
|
||||
* @param colors The text color state list.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_calendarTextColor
|
||||
*/
|
||||
public void setCalendarTextColor(ColorStateList colors) {
|
||||
mDelegate.setCalendarTextColor(colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text color state list for the calendar.
|
||||
*
|
||||
* @return The text color state list for the calendar.
|
||||
*
|
||||
* @attr ref android.R.styleable#DatePicker_calendarTextColor
|
||||
*/
|
||||
public ColorStateList getCalendarTextColor() {
|
||||
return mDelegate.getCalendarTextColors();
|
||||
}
|
||||
|
||||
// Override so we are in complete control of save / restore for this widget.
|
||||
@Override
|
||||
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
|
||||
@@ -323,6 +574,8 @@ public class DatePicker extends FrameLayout {
|
||||
* A delegate interface that defined the public API of the DatePicker. Allows different
|
||||
* DatePicker implementations. This would need to be implemented by the DatePicker delegates
|
||||
* for the real behavior.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface DatePickerDelegate {
|
||||
void init(int year, int monthOfYear, int dayOfMonth,
|
||||
@@ -335,15 +588,42 @@ public class DatePicker extends FrameLayout {
|
||||
int getDayOfMonth();
|
||||
|
||||
void setMinDate(long minDate);
|
||||
long getMinDate();
|
||||
Calendar getMinDate();
|
||||
|
||||
void setMaxDate(long maxDate);
|
||||
long getMaxDate();
|
||||
Calendar getMaxDate();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
boolean isEnabled();
|
||||
|
||||
CalendarView getCalendarView ();
|
||||
void setDateSelectorDayOfWeekBackgroundColor(int color);
|
||||
int getDateSelectorDayOfWeekBackgroundColor();
|
||||
|
||||
void setDateSelectorDayOfWeekTextAppearance(int resId);
|
||||
int getDateSelectorDayOfWeekTextAppearance();
|
||||
|
||||
void setDateSelectorBackgroundColor(int color);
|
||||
int getDateSelectorBackgroundColor();
|
||||
|
||||
void setDateSelectorMonthTextAppearance(int resId);
|
||||
int getDateSelectorMonthTextAppearance();
|
||||
|
||||
void setDateSelectorDayOfMonthTextAppearance(int resId);
|
||||
int getDateSelectorDayOfMonthTextAppearance();
|
||||
|
||||
void setDateSelectorYearTextAppearance(int resId);
|
||||
int getDateSelectorYearTextAppearance();
|
||||
|
||||
void setDateSelectorYearListItemTextAppearance(int resId);
|
||||
int getDateSelectorYearListItemTextAppearance();
|
||||
|
||||
void setDateSelectorYearListSelectedCircleColor(int color);
|
||||
int getDateSelectorYearListSelectedCircleColor();
|
||||
|
||||
void setCalendarTextColor(ColorStateList colors);
|
||||
ColorStateList getCalendarTextColors();
|
||||
|
||||
CalendarView getCalendarView();
|
||||
|
||||
void setCalendarViewShown(boolean shown);
|
||||
boolean getCalendarViewShown();
|
||||
@@ -351,6 +631,9 @@ public class DatePicker extends FrameLayout {
|
||||
void setSpinnersShown(boolean shown);
|
||||
boolean getSpinnersShown();
|
||||
|
||||
void setShowDoneButton(boolean showDoneButton);
|
||||
void setDismissCallback(DatePickerDismissCallback callback);
|
||||
|
||||
void onConfigurationChanged(Configuration newConfig);
|
||||
|
||||
void dispatchRestoreInstanceState(SparseArray<Parcelable> container);
|
||||
@@ -366,7 +649,7 @@ public class DatePicker extends FrameLayout {
|
||||
/**
|
||||
* An abstract class which can be used as a start for DatePicker implementations
|
||||
*/
|
||||
abstract static class AbstractTimePickerDelegate implements DatePickerDelegate {
|
||||
abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
|
||||
// The delegator
|
||||
protected DatePicker mDelegator;
|
||||
|
||||
@@ -379,7 +662,7 @@ public class DatePicker extends FrameLayout {
|
||||
// Callbacks
|
||||
protected OnDateChangedListener mOnDateChangedListener;
|
||||
|
||||
public AbstractTimePickerDelegate(DatePicker delegator, Context context) {
|
||||
public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
|
||||
mDelegator = delegator;
|
||||
mContext = context;
|
||||
|
||||
@@ -395,10 +678,19 @@ public class DatePicker extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback interface for dismissing the DatePicker when included into a Dialog
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static interface DatePickerDismissCallback {
|
||||
void dismiss(DatePicker view, boolean isCancel, int year, int month, int dayOfMonth);
|
||||
}
|
||||
|
||||
/**
|
||||
* A delegate implementing the basic DatePicker
|
||||
*/
|
||||
private static class LegacyDatePickerDelegate extends AbstractTimePickerDelegate {
|
||||
private static class LegacyDatePickerDelegate extends AbstractDatePickerDelegate {
|
||||
|
||||
private static final String DATE_FORMAT = "MM/dd/yyyy";
|
||||
|
||||
@@ -466,7 +758,7 @@ public class DatePicker extends FrameLayout {
|
||||
String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
|
||||
String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
|
||||
int layoutResourceId = attributesArray.getResourceId(
|
||||
R.styleable.DatePicker_internalLayout, R.layout.date_picker);
|
||||
R.styleable.DatePicker_legacyLayout, R.layout.date_picker_legacy);
|
||||
attributesArray.recycle();
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
@@ -643,8 +935,10 @@ public class DatePicker extends FrameLayout {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinDate() {
|
||||
return mCalendarView.getMinDate();
|
||||
public Calendar getMinDate() {
|
||||
final Calendar minDate = Calendar.getInstance();
|
||||
minDate.setTimeInMillis(mCalendarView.getMinDate());
|
||||
return minDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -664,8 +958,10 @@ public class DatePicker extends FrameLayout {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxDate() {
|
||||
return mCalendarView.getMaxDate();
|
||||
public Calendar getMaxDate() {
|
||||
final Calendar maxDate = Calendar.getInstance();
|
||||
maxDate.setTimeInMillis(mCalendarView.getMaxDate());
|
||||
return maxDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -682,6 +978,87 @@ public class DatePicker extends FrameLayout {
|
||||
return mIsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfWeekBackgroundColor(int color) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfWeekBackgroundColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfWeekTextAppearance(int resId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfWeekTextAppearance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorBackgroundColor(int color) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorBackgroundColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorMonthTextAppearance(int resId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorMonthTextAppearance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfMonthTextAppearance(int resId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfMonthTextAppearance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearTextAppearance(int resId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearTextAppearance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearListItemTextAppearance(int resId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearListItemTextAppearance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearListSelectedCircleColor(int color) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearListSelectedCircleColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCalendarTextColor(ColorStateList colors) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorStateList getCalendarTextColors() {
|
||||
return ColorStateList.valueOf(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalendarView getCalendarView() {
|
||||
return mCalendarView;
|
||||
@@ -707,6 +1084,16 @@ public class DatePicker extends FrameLayout {
|
||||
return mSpinners.isShown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowDoneButton(boolean showDoneButton) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDismissCallback(DatePickerDismissCallback callback) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
setCurrentLocale(newConfig.locale);
|
||||
|
||||
56
core/java/android/widget/DatePickerController.java
Normal file
56
core/java/android/widget/DatePickerController.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Controller class to communicate among the various components of the date picker dialog.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface DatePickerController {
|
||||
|
||||
void onYearSelected(int year);
|
||||
|
||||
void onDayOfMonthSelected(int year, int month, int day);
|
||||
|
||||
void registerOnDateChangedListener(OnDateChangedListener listener);
|
||||
|
||||
void unregisterOnDateChangedListener(OnDateChangedListener listener);
|
||||
|
||||
Calendar getSelectedDay();
|
||||
|
||||
int getFirstDayOfWeek();
|
||||
|
||||
int getMinYear();
|
||||
int getMaxYear();
|
||||
|
||||
int getMinMonth();
|
||||
int getMaxMonth();
|
||||
|
||||
int getMinDay();
|
||||
int getMaxDay();
|
||||
|
||||
void setMinDate(long minDate);
|
||||
Calendar getMinDate();
|
||||
|
||||
void setMaxDate(long maxDate);
|
||||
Calendar getMaxDate();
|
||||
|
||||
void tryVibrate();
|
||||
}
|
||||
979
core/java/android/widget/DatePickerDelegate.java
Normal file
979
core/java/android/widget/DatePickerDelegate.java
Normal file
@@ -0,0 +1,979 @@
|
||||
/*
|
||||
* 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 android.animation.Keyframe;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.widget.AccessibleDateAnimator;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A delegate for picking up a date (day / month / year).
|
||||
*/
|
||||
class DatePickerDelegate extends DatePicker.AbstractDatePickerDelegate implements
|
||||
View.OnClickListener, DatePickerController {
|
||||
|
||||
private static final int UNINITIALIZED = -1;
|
||||
private static final int MONTH_AND_DAY_VIEW = 0;
|
||||
private static final int YEAR_VIEW = 1;
|
||||
|
||||
private static final int DEFAULT_START_YEAR = 1900;
|
||||
private static final int DEFAULT_END_YEAR = 2100;
|
||||
|
||||
private static final int PULSE_ANIMATOR_DURATION = 544;
|
||||
|
||||
private static final int ANIMATION_DURATION = 300;
|
||||
private static final int ANIMATION_DELAY = 650;
|
||||
|
||||
private static final int MONTH_INDEX = 0;
|
||||
private static final int DAY_INDEX = 1;
|
||||
private static final int YEAR_INDEX = 2;
|
||||
|
||||
private SimpleDateFormat mYearFormat = new SimpleDateFormat("y", Locale.getDefault());
|
||||
private SimpleDateFormat mDayFormat = new SimpleDateFormat("d", Locale.getDefault());
|
||||
|
||||
private TextView mDayOfWeekView;
|
||||
private LinearLayout mDateLayout;
|
||||
private LinearLayout mMonthAndDayLayout;
|
||||
private TextView mSelectedMonthTextView;
|
||||
private TextView mSelectedDayTextView;
|
||||
private TextView mSelectedYearView;
|
||||
private DayPickerView mDayPickerView;
|
||||
private YearPickerView mYearPickerView;
|
||||
|
||||
private ViewGroup mLayoutButtons;
|
||||
|
||||
private boolean mIsEnabled = true;
|
||||
|
||||
// Accessibility strings.
|
||||
private String mDayPickerDescription;
|
||||
private String mSelectDay;
|
||||
private String mYearPickerDescription;
|
||||
private String mSelectYear;
|
||||
|
||||
private AccessibleDateAnimator mAnimator;
|
||||
|
||||
private DatePicker.OnDateChangedListener mDateChangedListener;
|
||||
|
||||
private boolean mDelayAnimation = true;
|
||||
|
||||
private int mCurrentView = UNINITIALIZED;
|
||||
|
||||
private Calendar mCurrentDate;
|
||||
private Calendar mTempDate;
|
||||
private Calendar mMinDate;
|
||||
private Calendar mMaxDate;
|
||||
|
||||
// For showing the done button when in a Dialog
|
||||
private Button mDoneButton;
|
||||
private boolean mShowDoneButton;
|
||||
private DatePicker.DatePickerDismissCallback mDismissCallback;
|
||||
|
||||
private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
|
||||
|
||||
private int mDayOfWeekTextAppearanceResId;
|
||||
private int mMonthTextAppearanceResId;
|
||||
private int mDayOfMonthTextAppearanceResId;
|
||||
private int mYearTextAppearanceResId;
|
||||
|
||||
private int mYearListItemTextAppearanceResId;
|
||||
|
||||
private int mDayOfWeekBackgroundColor;
|
||||
private int mMonthAndDayBackgroundColor;
|
||||
|
||||
private ColorStateList mCalendarTextColors;
|
||||
|
||||
public DatePickerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
|
||||
super(delegator, context);
|
||||
|
||||
final Locale locale = Locale.getDefault();
|
||||
mMinDate = getCalendarForLocale(mMinDate, locale);
|
||||
mMaxDate = getCalendarForLocale(mMaxDate, locale);
|
||||
mTempDate = getCalendarForLocale(mMaxDate, locale);
|
||||
|
||||
mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
|
||||
|
||||
mMinDate.set(DEFAULT_START_YEAR, 1, 1);
|
||||
mMaxDate.set(DEFAULT_END_YEAR, 12, 31);
|
||||
|
||||
// process style attributes
|
||||
final TypedArray a = mContext.obtainStyledAttributes(attrs,
|
||||
R.styleable.DatePicker, defStyleAttr, defStyleRes);
|
||||
|
||||
final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
final int layoutResourceId = a.getResourceId(
|
||||
R.styleable.DatePicker_internalLayout, R.layout.date_picker_holo);
|
||||
|
||||
View mainView = inflater.inflate(layoutResourceId, null);
|
||||
mDelegator.addView(mainView);
|
||||
|
||||
mDayOfWeekView = (TextView) mainView.findViewById(R.id.date_picker_header);
|
||||
mDateLayout = (LinearLayout) mainView.findViewById(R.id.day_picker_selector_layout);
|
||||
mMonthAndDayLayout = (LinearLayout) mainView.findViewById(
|
||||
R.id.date_picker_month_and_day_layout);
|
||||
mMonthAndDayLayout.setOnClickListener(this);
|
||||
mSelectedMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_month);
|
||||
mSelectedDayTextView = (TextView) mainView.findViewById(R.id.date_picker_day);
|
||||
mSelectedYearView = (TextView) mainView.findViewById(R.id.date_picker_year);
|
||||
mSelectedYearView.setOnClickListener(this);
|
||||
|
||||
// Use Theme attributes if possible
|
||||
mDayOfWeekTextAppearanceResId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorDayOfWeekTextAppearance, -1);
|
||||
if (mDayOfWeekTextAppearanceResId != -1) {
|
||||
mDayOfWeekView.setTextAppearance(context, mDayOfWeekTextAppearanceResId);
|
||||
}
|
||||
|
||||
mMonthTextAppearanceResId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorMonthTextAppearance, -1);
|
||||
if (mMonthTextAppearanceResId != -1) {
|
||||
mSelectedMonthTextView.setTextAppearance(context, mMonthTextAppearanceResId);
|
||||
}
|
||||
|
||||
mDayOfMonthTextAppearanceResId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorDayOfMonthTextAppearance, -1);
|
||||
if (mDayOfMonthTextAppearanceResId != -1) {
|
||||
mSelectedDayTextView.setTextAppearance(context, mDayOfMonthTextAppearanceResId);
|
||||
}
|
||||
|
||||
mYearTextAppearanceResId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorYearTextAppearance, -1);
|
||||
if (mYearTextAppearanceResId != -1) {
|
||||
mSelectedYearView.setTextAppearance(context, mYearTextAppearanceResId);
|
||||
}
|
||||
|
||||
Resources res = mDelegator.getResources();
|
||||
|
||||
mDayOfWeekBackgroundColor = a.getColor(
|
||||
R.styleable.DatePicker_dateSelectorDayOfWeekBackgroundColor,
|
||||
res.getColor(
|
||||
R.color.datepicker_default_header_dayofweek_background_color_holo_light));
|
||||
mDayOfWeekView.setBackgroundColor(mDayOfWeekBackgroundColor);
|
||||
|
||||
mMonthAndDayBackgroundColor = a.getColor(R.styleable.DatePicker_dateSelectorBackgroundColor,
|
||||
res.getColor(R.color.datepicker_default_header_selector_background_holo_light));
|
||||
mMonthAndDayLayout.setBackgroundColor(mMonthAndDayBackgroundColor);
|
||||
|
||||
mDayPickerView = new DayPickerView(mContext, this);
|
||||
mYearPickerView = new YearPickerView(mContext);
|
||||
mYearPickerView.init(this);
|
||||
|
||||
ColorStateList colors = a.getColorStateList(R.styleable.DatePicker_calendarTextColor);
|
||||
setCalendarTextColor(colors);
|
||||
|
||||
mDayPickerDescription = res.getString(R.string.day_picker_description);
|
||||
mSelectDay = res.getString(R.string.select_day);
|
||||
mYearPickerDescription = res.getString(R.string.year_picker_description);
|
||||
mSelectYear = res.getString(R.string.select_year);
|
||||
|
||||
mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
|
||||
mAnimator.addView(mDayPickerView);
|
||||
mAnimator.addView(mYearPickerView);
|
||||
mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
|
||||
Animation animation = new AlphaAnimation(0.0f, 1.0f);
|
||||
animation.setDuration(ANIMATION_DURATION);
|
||||
mAnimator.setInAnimation(animation);
|
||||
Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
|
||||
animation2.setDuration(ANIMATION_DURATION);
|
||||
mAnimator.setOutAnimation(animation2);
|
||||
|
||||
mLayoutButtons = (ViewGroup) mainView.findViewById(R.id.layout_buttons);
|
||||
mDoneButton = (Button) mainView.findViewById(R.id.done);
|
||||
mDoneButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
tryVibrate();
|
||||
if (mDismissCallback != null) {
|
||||
mDismissCallback.dismiss(mDelegator, false, mCurrentDate.get(Calendar.YEAR),
|
||||
mCurrentDate.get(Calendar.MONTH),
|
||||
mCurrentDate.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateDisplay(false);
|
||||
setCurrentView(MONTH_AND_DAY_VIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a calendar for locale bootstrapped with the value of a given calendar.
|
||||
*
|
||||
* @param oldCalendar The old calendar.
|
||||
* @param locale The locale.
|
||||
*/
|
||||
private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
|
||||
if (oldCalendar == null) {
|
||||
return Calendar.getInstance(locale);
|
||||
} else {
|
||||
final long currentTimeMillis = oldCalendar.getTimeInMillis();
|
||||
Calendar newCalendar = Calendar.getInstance(locale);
|
||||
newCalendar.setTimeInMillis(currentTimeMillis);
|
||||
return newCalendar;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the array representing the order of Month / Day / Year views in their layout.
|
||||
* Will be used for I18N purpose as the order of them depends on the Locale.
|
||||
*/
|
||||
private int[] getMonthDayYearIndexes(String pattern) {
|
||||
int[] result = new int[3];
|
||||
|
||||
final String filteredPattern = pattern.replaceAll("'.*?'", "");
|
||||
|
||||
final int dayIndex = filteredPattern.indexOf('d');
|
||||
final int monthMIndex = filteredPattern.indexOf("M");
|
||||
final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
|
||||
final int yearIndex = filteredPattern.indexOf("y");
|
||||
|
||||
if (yearIndex < monthIndex) {
|
||||
result[YEAR_INDEX] = 0;
|
||||
|
||||
if (monthIndex < dayIndex) {
|
||||
result[MONTH_INDEX] = 1;
|
||||
result[DAY_INDEX] = 2;
|
||||
} else {
|
||||
result[MONTH_INDEX] = 2;
|
||||
result[DAY_INDEX] = 1;
|
||||
}
|
||||
} else {
|
||||
result[YEAR_INDEX] = 2;
|
||||
|
||||
if (monthIndex < dayIndex) {
|
||||
result[MONTH_INDEX] = 0;
|
||||
result[DAY_INDEX] = 1;
|
||||
} else {
|
||||
result[MONTH_INDEX] = 1;
|
||||
result[DAY_INDEX] = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateDisplay(boolean announce) {
|
||||
if (mDayOfWeekView != null) {
|
||||
mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
|
||||
Locale.getDefault()));
|
||||
}
|
||||
final String bestDateTimePattern =
|
||||
DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
|
||||
|
||||
// Compute indices of Month, Day and Year views
|
||||
int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
|
||||
|
||||
// Restart from a clean state
|
||||
mMonthAndDayLayout.removeAllViews();
|
||||
mDateLayout.removeView(mSelectedYearView);
|
||||
|
||||
// Position the Year View at the correct location
|
||||
if (viewIndices[YEAR_INDEX] == 0) {
|
||||
mDateLayout.addView(mSelectedYearView, 0);
|
||||
} else {
|
||||
mDateLayout.addView(mSelectedYearView, 1);
|
||||
}
|
||||
|
||||
// Position Day and Month Views
|
||||
if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
|
||||
// Day View is first
|
||||
mMonthAndDayLayout.addView(mSelectedDayTextView);
|
||||
mMonthAndDayLayout.addView(mSelectedMonthTextView);
|
||||
} else {
|
||||
// Month View is first
|
||||
mMonthAndDayLayout.addView(mSelectedMonthTextView);
|
||||
mMonthAndDayLayout.addView(mSelectedDayTextView);
|
||||
}
|
||||
|
||||
mSelectedMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
|
||||
Locale.getDefault()).toUpperCase(Locale.getDefault()));
|
||||
mSelectedDayTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
|
||||
mSelectedYearView.setText(mYearFormat.format(mCurrentDate.getTime()));
|
||||
|
||||
// Accessibility.
|
||||
long millis = mCurrentDate.getTimeInMillis();
|
||||
mAnimator.setDateMillis(millis);
|
||||
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
|
||||
String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
|
||||
mMonthAndDayLayout.setContentDescription(monthAndDayText);
|
||||
|
||||
if (announce) {
|
||||
flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
|
||||
String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
|
||||
mAnimator.announceForAccessibility(fullDateText);
|
||||
}
|
||||
updatePickers();
|
||||
}
|
||||
|
||||
private void setCurrentView(final int viewIndex) {
|
||||
long millis = mCurrentDate.getTimeInMillis();
|
||||
|
||||
switch (viewIndex) {
|
||||
case MONTH_AND_DAY_VIEW:
|
||||
ObjectAnimator pulseAnimator = getPulseAnimator(mMonthAndDayLayout, 0.9f,
|
||||
1.05f);
|
||||
if (mDelayAnimation) {
|
||||
pulseAnimator.setStartDelay(ANIMATION_DELAY);
|
||||
mDelayAnimation = false;
|
||||
}
|
||||
mDayPickerView.onDateChanged();
|
||||
if (mCurrentView != viewIndex) {
|
||||
mMonthAndDayLayout.setSelected(true);
|
||||
mSelectedYearView.setSelected(false);
|
||||
mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
|
||||
mCurrentView = viewIndex;
|
||||
}
|
||||
pulseAnimator.start();
|
||||
|
||||
int flags = DateUtils.FORMAT_SHOW_DATE;
|
||||
String dayString = DateUtils.formatDateTime(mContext, millis, flags);
|
||||
mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
|
||||
mAnimator.announceForAccessibility(mSelectDay);
|
||||
break;
|
||||
case YEAR_VIEW:
|
||||
pulseAnimator = getPulseAnimator(mSelectedYearView, 0.85f, 1.1f);
|
||||
if (mDelayAnimation) {
|
||||
pulseAnimator.setStartDelay(ANIMATION_DELAY);
|
||||
mDelayAnimation = false;
|
||||
}
|
||||
mYearPickerView.onDateChanged();
|
||||
if (mCurrentView != viewIndex) {
|
||||
mMonthAndDayLayout.setSelected(false);
|
||||
mSelectedYearView.setSelected(true);
|
||||
mAnimator.setDisplayedChild(YEAR_VIEW);
|
||||
mCurrentView = viewIndex;
|
||||
}
|
||||
pulseAnimator.start();
|
||||
|
||||
CharSequence yearString = mYearFormat.format(millis);
|
||||
mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
|
||||
mAnimator.announceForAccessibility(mSelectYear);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(int year, int monthOfYear, int dayOfMonth,
|
||||
DatePicker.OnDateChangedListener callBack) {
|
||||
mDateChangedListener = callBack;
|
||||
mCurrentDate.set(Calendar.YEAR, year);
|
||||
mCurrentDate.set(Calendar.MONTH, monthOfYear);
|
||||
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
updateDisplay(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDate(int year, int month, int dayOfMonth) {
|
||||
mCurrentDate.set(Calendar.YEAR, year);
|
||||
mCurrentDate.set(Calendar.MONTH, month);
|
||||
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
|
||||
updateDisplay(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getYear() {
|
||||
return mCurrentDate.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMonth() {
|
||||
return mCurrentDate.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDayOfMonth() {
|
||||
return mCurrentDate.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinDate(long minDate) {
|
||||
mTempDate.setTimeInMillis(minDate);
|
||||
if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
|
||||
&& mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
|
||||
return;
|
||||
}
|
||||
if (mCurrentDate.before(mTempDate)) {
|
||||
mCurrentDate.setTimeInMillis(minDate);
|
||||
updatePickers();
|
||||
updateDisplay(false);
|
||||
}
|
||||
mMinDate.setTimeInMillis(minDate);
|
||||
mDayPickerView.goTo(getSelectedDay(), false, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getMinDate() {
|
||||
return mMinDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxDate(long maxDate) {
|
||||
mTempDate.setTimeInMillis(maxDate);
|
||||
if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
|
||||
&& mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
|
||||
return;
|
||||
}
|
||||
if (mCurrentDate.after(mTempDate)) {
|
||||
mCurrentDate.setTimeInMillis(maxDate);
|
||||
updatePickers();
|
||||
updateDisplay(false);
|
||||
}
|
||||
mMaxDate.setTimeInMillis(maxDate);
|
||||
mDayPickerView.goTo(getSelectedDay(), false, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getMaxDate() {
|
||||
return mMaxDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstDayOfWeek() {
|
||||
return mCurrentDate.getFirstDayOfWeek();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinYear() {
|
||||
return mMinDate.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxYear() {
|
||||
return mMaxDate.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinMonth() {
|
||||
return mMinDate.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxMonth() {
|
||||
return mMaxDate.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinDay() {
|
||||
return mMinDate.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxDay() {
|
||||
return mMaxDate.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
mMonthAndDayLayout.setEnabled(enabled);
|
||||
mSelectedYearView.setEnabled(enabled);
|
||||
mAnimator.setEnabled(enabled);
|
||||
mIsEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return mIsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfWeekBackgroundColor(int color) {
|
||||
if (mDayOfWeekBackgroundColor != color) {
|
||||
mDayOfWeekBackgroundColor = color;
|
||||
mDayOfWeekView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfWeekBackgroundColor() {
|
||||
return mDayOfWeekBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfWeekTextAppearance(int resId) {
|
||||
if (mDayOfWeekTextAppearanceResId != resId && resId > 0) {
|
||||
mDayOfWeekTextAppearanceResId = resId;
|
||||
mDayOfWeekView.setTextAppearance(mContext, resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfWeekTextAppearance() {
|
||||
return mDayOfWeekTextAppearanceResId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorBackgroundColor(int color) {
|
||||
if (mMonthAndDayBackgroundColor != color) {
|
||||
mMonthAndDayBackgroundColor = color;
|
||||
mMonthAndDayLayout.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorBackgroundColor() {
|
||||
return mMonthAndDayBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorMonthTextAppearance(int resId) {
|
||||
if (mMonthTextAppearanceResId != resId && resId > 0) {
|
||||
mMonthTextAppearanceResId = resId;
|
||||
mSelectedMonthTextView.setTextAppearance(mContext, resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorMonthTextAppearance() {
|
||||
return mMonthTextAppearanceResId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorDayOfMonthTextAppearance(int resId) {
|
||||
if (mDayOfMonthTextAppearanceResId != resId && resId > 0) {
|
||||
mDayOfMonthTextAppearanceResId = resId;
|
||||
mSelectedDayTextView.setTextAppearance(mContext, resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorDayOfMonthTextAppearance() {
|
||||
return mDayOfMonthTextAppearanceResId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearTextAppearance(int resId) {
|
||||
if (mYearTextAppearanceResId != resId && resId > 0) {
|
||||
mYearTextAppearanceResId = resId;
|
||||
mSelectedYearView.setTextAppearance(mContext, resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearTextAppearance() {
|
||||
return mYearTextAppearanceResId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearListItemTextAppearance(int resId) {
|
||||
if (mYearListItemTextAppearanceResId != resId) {
|
||||
mYearListItemTextAppearanceResId = resId;
|
||||
mYearPickerView.setItemTextAppearance(resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearListItemTextAppearance() {
|
||||
return mYearListItemTextAppearanceResId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateSelectorYearListSelectedCircleColor(int color) {
|
||||
mYearPickerView.setYearSelectedCircleColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDateSelectorYearListSelectedCircleColor() {
|
||||
return mYearPickerView.getYearSelectedCircleColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCalendarTextColor(ColorStateList colors) {
|
||||
if (colors == null) {
|
||||
return;
|
||||
}
|
||||
if (mCalendarTextColors == null || !mCalendarTextColors.equals(colors)) {
|
||||
mCalendarTextColors = colors;
|
||||
mDayPickerView.setCalendarTextColor(colors);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorStateList getCalendarTextColors() {
|
||||
return mCalendarTextColors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalendarView getCalendarView() {
|
||||
throw new UnsupportedOperationException(
|
||||
"CalendarView does not exists for the new DatePicker");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCalendarViewShown(boolean shown) {
|
||||
// No-op for compatibility with the old DatePicker.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCalendarViewShown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpinnersShown(boolean shown) {
|
||||
// No-op for compatibility with the old DatePicker.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSpinnersShown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowDoneButton(boolean showDoneButton) {
|
||||
mShowDoneButton = showDoneButton;
|
||||
updateDoneButtonVisibility();
|
||||
}
|
||||
|
||||
private void updateDoneButtonVisibility() {
|
||||
mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDismissCallback(DatePicker.DatePickerDismissCallback callback) {
|
||||
mDismissCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
mYearFormat = new SimpleDateFormat("y", newConfig.locale);
|
||||
mDayFormat = new SimpleDateFormat("d", newConfig.locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState(Parcelable superState) {
|
||||
final int year = mCurrentDate.get(Calendar.YEAR);
|
||||
final int month = mCurrentDate.get(Calendar.MONTH);
|
||||
final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
int listPosition = -1;
|
||||
int listPositionOffset = -1;
|
||||
|
||||
if (mCurrentView == MONTH_AND_DAY_VIEW) {
|
||||
listPosition = mDayPickerView.getMostVisiblePosition();
|
||||
} else if (mCurrentView == YEAR_VIEW) {
|
||||
listPosition = mYearPickerView.getFirstVisiblePosition();
|
||||
listPositionOffset = mYearPickerView.getFirstPositionOffset();
|
||||
}
|
||||
|
||||
return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
|
||||
mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
SavedState ss = (SavedState) state;
|
||||
|
||||
mCurrentDate.set(ss.getSelectedDay(), ss.getSelectedMonth(), ss.getSelectedYear());
|
||||
mCurrentView = ss.getCurrentView();
|
||||
mMinDate.setTimeInMillis(ss.getMinDate());
|
||||
mMaxDate.setTimeInMillis(ss.getMaxDate());
|
||||
|
||||
updateDisplay(false);
|
||||
setCurrentView(mCurrentView);
|
||||
|
||||
final int listPosition = ss.getListPosition();
|
||||
if (listPosition != -1) {
|
||||
if (mCurrentView == MONTH_AND_DAY_VIEW) {
|
||||
mDayPickerView.postSetSelection(listPosition);
|
||||
} else if (mCurrentView == YEAR_VIEW) {
|
||||
mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
onPopulateAccessibilityEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
event.getText().add(mCurrentDate.getTime().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
event.setClassName(DatePicker.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
info.setClassName(DatePicker.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onYearSelected(int year) {
|
||||
adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
|
||||
mCurrentDate.set(Calendar.YEAR, year);
|
||||
updatePickers();
|
||||
setCurrentView(MONTH_AND_DAY_VIEW);
|
||||
updateDisplay(true);
|
||||
updateDoneButtonEnableState();
|
||||
}
|
||||
|
||||
// If the newly selected month / year does not contain the currently selected day number,
|
||||
// change the selected day number to the last day of the selected month or year.
|
||||
// e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
|
||||
// e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
|
||||
private void adjustDayInMonthIfNeeded(int month, int year) {
|
||||
int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
|
||||
int daysInMonth = getDaysInMonth(month, year);
|
||||
if (day > daysInMonth) {
|
||||
mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDaysInMonth(int month, int year) {
|
||||
switch (month) {
|
||||
case Calendar.JANUARY:
|
||||
case Calendar.MARCH:
|
||||
case Calendar.MAY:
|
||||
case Calendar.JULY:
|
||||
case Calendar.AUGUST:
|
||||
case Calendar.OCTOBER:
|
||||
case Calendar.DECEMBER:
|
||||
return 31;
|
||||
case Calendar.APRIL:
|
||||
case Calendar.JUNE:
|
||||
case Calendar.SEPTEMBER:
|
||||
case Calendar.NOVEMBER:
|
||||
return 30;
|
||||
case Calendar.FEBRUARY:
|
||||
return (year % 4 == 0) ? 29 : 28;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Month");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDayOfMonthSelected(int year, int month, int day) {
|
||||
mCurrentDate.set(Calendar.YEAR, year);
|
||||
mCurrentDate.set(Calendar.MONTH, month);
|
||||
mCurrentDate.set(Calendar.DAY_OF_MONTH, day);
|
||||
updatePickers();
|
||||
updateDisplay(true);
|
||||
updateDoneButtonEnableState();
|
||||
}
|
||||
|
||||
private void updateDoneButtonEnableState() {
|
||||
if (mShowDoneButton) {
|
||||
final boolean enabled = mCurrentDate.equals(mMinDate) ||
|
||||
mCurrentDate.equals(mMaxDate) ||
|
||||
(mCurrentDate.after(mMinDate) && mCurrentDate.before(mMaxDate));
|
||||
mDoneButton.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePickers() {
|
||||
Iterator<OnDateChangedListener> iterator = mListeners.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next().onDateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOnDateChangedListener(OnDateChangedListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterOnDateChangedListener(OnDateChangedListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getSelectedDay() {
|
||||
return mCurrentDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tryVibrate() {
|
||||
mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
tryVibrate();
|
||||
if (v.getId() == R.id.date_picker_year) {
|
||||
setCurrentView(YEAR_VIEW);
|
||||
} else if (v.getId() == R.id.date_picker_month_and_day_layout) {
|
||||
setCurrentView(MONTH_AND_DAY_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for managing state storing/restoring.
|
||||
*/
|
||||
private static class SavedState extends View.BaseSavedState {
|
||||
|
||||
private final int mSelectedYear;
|
||||
private final int mSelectedMonth;
|
||||
private final int mSelectedDay;
|
||||
private final long mMinDate;
|
||||
private final long mMaxDate;
|
||||
private final int mCurrentView;
|
||||
private final int mListPosition;
|
||||
private final int mListPositionOffset;
|
||||
|
||||
/**
|
||||
* Constructor called from {@link DatePicker#onSaveInstanceState()}
|
||||
*/
|
||||
private SavedState(Parcelable superState, int year, int month, int day,
|
||||
long minDate, long maxDate, int currentView, int listPosition,
|
||||
int listPositionOffset) {
|
||||
super(superState);
|
||||
mSelectedYear = year;
|
||||
mSelectedMonth = month;
|
||||
mSelectedDay = day;
|
||||
mMinDate = minDate;
|
||||
mMaxDate = maxDate;
|
||||
mCurrentView = currentView;
|
||||
mListPosition = listPosition;
|
||||
mListPositionOffset = listPositionOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called from {@link #CREATOR}
|
||||
*/
|
||||
private SavedState(Parcel in) {
|
||||
super(in);
|
||||
mSelectedYear = in.readInt();
|
||||
mSelectedMonth = in.readInt();
|
||||
mSelectedDay = in.readInt();
|
||||
mMinDate = in.readLong();
|
||||
mMaxDate = in.readLong();
|
||||
mCurrentView = in.readInt();
|
||||
mListPosition = in.readInt();
|
||||
mListPositionOffset = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mSelectedYear);
|
||||
dest.writeInt(mSelectedMonth);
|
||||
dest.writeInt(mSelectedDay);
|
||||
dest.writeLong(mMinDate);
|
||||
dest.writeLong(mMaxDate);
|
||||
dest.writeInt(mCurrentView);
|
||||
dest.writeInt(mListPosition);
|
||||
dest.writeInt(mListPositionOffset);
|
||||
}
|
||||
|
||||
public int getSelectedDay() {
|
||||
return mSelectedDay;
|
||||
}
|
||||
|
||||
public int getSelectedMonth() {
|
||||
return mSelectedMonth;
|
||||
}
|
||||
|
||||
public int getSelectedYear() {
|
||||
return mSelectedYear;
|
||||
}
|
||||
|
||||
public long getMinDate() {
|
||||
return mMinDate;
|
||||
}
|
||||
|
||||
public long getMaxDate() {
|
||||
return mMaxDate;
|
||||
}
|
||||
|
||||
public int getCurrentView() {
|
||||
return mCurrentView;
|
||||
}
|
||||
|
||||
public int getListPosition() {
|
||||
return mListPosition;
|
||||
}
|
||||
|
||||
public int getListPositionOffset() {
|
||||
return mListPositionOffset;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
// suppress unused and hiding
|
||||
public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
|
||||
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an animator to pulsate a view in place.
|
||||
* @param labelToAnimate the view to pulsate.
|
||||
* @return The animator object. Use .start() to begin.
|
||||
*/
|
||||
public static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio,
|
||||
float increaseRatio) {
|
||||
Keyframe k0 = Keyframe.ofFloat(0f, 1f);
|
||||
Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio);
|
||||
Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
|
||||
Keyframe k3 = Keyframe.ofFloat(1f, 1f);
|
||||
|
||||
PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe(View.SCALE_X, k0, k1, k2, k3);
|
||||
PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe(View.SCALE_Y, k0, k1, k2, k3);
|
||||
ObjectAnimator pulseAnimator =
|
||||
ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY);
|
||||
pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION);
|
||||
|
||||
return pulseAnimator;
|
||||
}
|
||||
}
|
||||
506
core/java/android/widget/DayPickerView.java
Normal file
506
core/java/android/widget/DayPickerView.java
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* 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 android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This displays a list of months in a calendar format with selectable days.
|
||||
*/
|
||||
class DayPickerView extends ListView implements AbsListView.OnScrollListener,
|
||||
OnDateChangedListener {
|
||||
|
||||
private static final String TAG = "DayPickerView";
|
||||
|
||||
// How long the GoTo fling animation should last
|
||||
private static final int GOTO_SCROLL_DURATION = 250;
|
||||
|
||||
// How long to wait after receiving an onScrollStateChanged notification before acting on it
|
||||
private static final int SCROLL_CHANGE_DELAY = 40;
|
||||
|
||||
private static int LIST_TOP_OFFSET = -1; // so that the top line will be under the separator
|
||||
|
||||
private SimpleDateFormat mYearFormat = new SimpleDateFormat("yyyy", Locale.getDefault());
|
||||
|
||||
// These affect the scroll speed and feel
|
||||
private float mFriction = 1.0f;
|
||||
|
||||
// highlighted time
|
||||
private Calendar mSelectedDay = Calendar.getInstance();
|
||||
private SimpleMonthAdapter mAdapter;
|
||||
|
||||
private Calendar mTempDay = Calendar.getInstance();
|
||||
|
||||
// which month should be displayed/highlighted [0-11]
|
||||
private int mCurrentMonthDisplayed;
|
||||
// used for tracking what state listview is in
|
||||
private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
|
||||
// used for tracking what state listview is in
|
||||
private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
|
||||
|
||||
private DatePickerController mController;
|
||||
private boolean mPerformingScroll;
|
||||
|
||||
private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable(this);
|
||||
|
||||
public DayPickerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DayPickerView(Context context, DatePickerController controller) {
|
||||
super(context);
|
||||
init();
|
||||
setController(controller);
|
||||
}
|
||||
|
||||
public void setController(DatePickerController controller) {
|
||||
if (mController != null) {
|
||||
mController.unregisterOnDateChangedListener(this);
|
||||
}
|
||||
mController = controller;
|
||||
mController.registerOnDateChangedListener(this);
|
||||
setUpAdapter();
|
||||
setAdapter(mAdapter);
|
||||
onDateChanged();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||
setDrawSelectorOnTop(false);
|
||||
|
||||
setUpListView();
|
||||
}
|
||||
|
||||
public void onChange() {
|
||||
setUpAdapter();
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new adapter if necessary and sets up its parameters. Override
|
||||
* this method to provide a custom adapter.
|
||||
*/
|
||||
protected void setUpAdapter() {
|
||||
if (mAdapter == null) {
|
||||
mAdapter = new SimpleMonthAdapter(getContext(), mController);
|
||||
} else {
|
||||
mAdapter.setSelectedDay(mSelectedDay);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
// refresh the view with the new parameters
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets all the required fields for the list view. Override this method to
|
||||
* set a different list view behavior.
|
||||
*/
|
||||
protected void setUpListView() {
|
||||
// Transparent background on scroll
|
||||
setCacheColorHint(0);
|
||||
// No dividers
|
||||
setDivider(null);
|
||||
// Items are clickable
|
||||
setItemsCanFocus(true);
|
||||
// The thumb gets in the way, so disable it
|
||||
setFastScrollEnabled(false);
|
||||
setVerticalScrollBarEnabled(false);
|
||||
setOnScrollListener(this);
|
||||
setFadingEdgeLength(0);
|
||||
// Make the scrolling behavior nicer
|
||||
setFriction(ViewConfiguration.getScrollFriction() * mFriction);
|
||||
}
|
||||
|
||||
private int getDiffMonths(Calendar start, Calendar end){
|
||||
final int diffYears = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
|
||||
final int diffMonths = end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears;
|
||||
return diffMonths;
|
||||
}
|
||||
|
||||
private int getPositionFromDay(Calendar day) {
|
||||
final int diffMonthMax = getDiffMonths(mController.getMinDate(), mController.getMaxDate());
|
||||
int diffMonth = getDiffMonths(mController.getMinDate(), day);
|
||||
|
||||
if (diffMonth < 0 ) {
|
||||
diffMonth = 0;
|
||||
} else if (diffMonth > diffMonthMax) {
|
||||
diffMonth = diffMonthMax;
|
||||
}
|
||||
|
||||
return diffMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the time is at the top of the view. If the new time is already in view
|
||||
* the list will not be scrolled unless forceScroll is true. This time may
|
||||
* optionally be highlighted as selected as well.
|
||||
*
|
||||
* @param day The day to move to
|
||||
* @param animate Whether to scroll to the given time or just redraw at the
|
||||
* new location
|
||||
* @param setSelected Whether to set the given time as selected
|
||||
* @param forceScroll Whether to recenter even if the time is already
|
||||
* visible
|
||||
* @return Whether or not the view animated to the new location
|
||||
*/
|
||||
public boolean goTo(Calendar day, boolean animate, boolean setSelected,
|
||||
boolean forceScroll) {
|
||||
|
||||
// Set the selected day
|
||||
if (setSelected) {
|
||||
mSelectedDay.setTimeInMillis(day.getTimeInMillis());
|
||||
}
|
||||
|
||||
mTempDay.setTimeInMillis(day.getTimeInMillis());
|
||||
final int position = getPositionFromDay(day);
|
||||
|
||||
View child;
|
||||
int i = 0;
|
||||
int top = 0;
|
||||
// Find a child that's completely in the view
|
||||
do {
|
||||
child = getChildAt(i++);
|
||||
if (child == null) {
|
||||
break;
|
||||
}
|
||||
top = child.getTop();
|
||||
} while (top < 0);
|
||||
|
||||
// Compute the first and last position visible
|
||||
int selectedPosition;
|
||||
if (child != null) {
|
||||
selectedPosition = getPositionForView(child);
|
||||
} else {
|
||||
selectedPosition = 0;
|
||||
}
|
||||
|
||||
if (setSelected) {
|
||||
mAdapter.setSelectedDay(mSelectedDay);
|
||||
}
|
||||
|
||||
// Check if the selected day is now outside of our visible range
|
||||
// and if so scroll to the month that contains it
|
||||
if (position != selectedPosition || forceScroll) {
|
||||
setMonthDisplayed(mTempDay);
|
||||
mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
|
||||
if (animate) {
|
||||
smoothScrollToPositionFromTop(
|
||||
position, LIST_TOP_OFFSET, GOTO_SCROLL_DURATION);
|
||||
return true;
|
||||
} else {
|
||||
postSetSelection(position);
|
||||
}
|
||||
} else if (setSelected) {
|
||||
setMonthDisplayed(mSelectedDay);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void postSetSelection(final int position) {
|
||||
clearFocus();
|
||||
post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setSelection(position);
|
||||
}
|
||||
});
|
||||
onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the title and selected month if the view has moved to a new
|
||||
* month.
|
||||
*/
|
||||
@Override
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
|
||||
int totalItemCount) {
|
||||
SimpleMonthView child = (SimpleMonthView) view.getChildAt(0);
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPreviousScrollState = mCurrentScrollState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the month displayed at the top of this view based on time. Override
|
||||
* to add custom events when the title is changed.
|
||||
*/
|
||||
protected void setMonthDisplayed(Calendar date) {
|
||||
if (mCurrentMonthDisplayed != date.get(Calendar.MONTH)) {
|
||||
mCurrentMonthDisplayed = date.get(Calendar.MONTH);
|
||||
invalidateViews();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||
// use a post to prevent re-entering onScrollStateChanged before it
|
||||
// exits
|
||||
mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
|
||||
}
|
||||
|
||||
void setCalendarTextColor(ColorStateList colors) {
|
||||
mAdapter.setCalendarTextColor(colors);
|
||||
}
|
||||
|
||||
protected class ScrollStateRunnable implements Runnable {
|
||||
private int mNewState;
|
||||
private View mParent;
|
||||
|
||||
ScrollStateRunnable(View view) {
|
||||
mParent = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the runnable with a short delay in case the scroll state
|
||||
* immediately changes again.
|
||||
*
|
||||
* @param view The list view that changed state
|
||||
* @param scrollState The new state it changed to
|
||||
*/
|
||||
public void doScrollStateChange(AbsListView view, int scrollState) {
|
||||
mParent.removeCallbacks(this);
|
||||
mNewState = scrollState;
|
||||
mParent.postDelayed(this, SCROLL_CHANGE_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mCurrentScrollState = mNewState;
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG,
|
||||
"new scroll state: " + mNewState + " old state: " + mPreviousScrollState);
|
||||
}
|
||||
// Fix the position after a scroll or a fling ends
|
||||
if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
|
||||
&& mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE
|
||||
&& mPreviousScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
|
||||
mPreviousScrollState = mNewState;
|
||||
int i = 0;
|
||||
View child = getChildAt(i);
|
||||
while (child != null && child.getBottom() <= 0) {
|
||||
child = getChildAt(++i);
|
||||
}
|
||||
if (child == null) {
|
||||
// The view is no longer visible, just return
|
||||
return;
|
||||
}
|
||||
int firstPosition = getFirstVisiblePosition();
|
||||
int lastPosition = getLastVisiblePosition();
|
||||
boolean scroll = firstPosition != 0 && lastPosition != getCount() - 1;
|
||||
final int top = child.getTop();
|
||||
final int bottom = child.getBottom();
|
||||
final int midpoint = getHeight() / 2;
|
||||
if (scroll && top < LIST_TOP_OFFSET) {
|
||||
if (bottom > midpoint) {
|
||||
smoothScrollBy(top, GOTO_SCROLL_DURATION);
|
||||
} else {
|
||||
smoothScrollBy(bottom, GOTO_SCROLL_DURATION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mPreviousScrollState = mNewState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position of the view that is most prominently displayed within the list view.
|
||||
*/
|
||||
public int getMostVisiblePosition() {
|
||||
final int firstPosition = getFirstVisiblePosition();
|
||||
final int height = getHeight();
|
||||
|
||||
int maxDisplayedHeight = 0;
|
||||
int mostVisibleIndex = 0;
|
||||
int i=0;
|
||||
int bottom = 0;
|
||||
while (bottom < height) {
|
||||
View child = getChildAt(i);
|
||||
if (child == null) {
|
||||
break;
|
||||
}
|
||||
bottom = child.getBottom();
|
||||
int displayedHeight = Math.min(bottom, height) - Math.max(0, child.getTop());
|
||||
if (displayedHeight > maxDisplayedHeight) {
|
||||
mostVisibleIndex = i;
|
||||
maxDisplayedHeight = displayedHeight;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return firstPosition + mostVisibleIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDateChanged() {
|
||||
goTo(mController.getSelectedDay(), false, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return the date that has accessibility focus.
|
||||
*
|
||||
* @return The date that has accessibility focus, or {@code null} if no date
|
||||
* has focus.
|
||||
*/
|
||||
private Calendar findAccessibilityFocus() {
|
||||
final int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child instanceof SimpleMonthView) {
|
||||
final Calendar focus = ((SimpleMonthView) child).getAccessibilityFocus();
|
||||
if (focus != null) {
|
||||
return focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to restore accessibility focus to a given date. No-op if
|
||||
* {@code day} is {@code null}.
|
||||
*
|
||||
* @param day The date that should receive accessibility focus
|
||||
* @return {@code true} if focus was restored
|
||||
*/
|
||||
private boolean restoreAccessibilityFocus(Calendar day) {
|
||||
if (day == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child instanceof SimpleMonthView) {
|
||||
if (((SimpleMonthView) child).restoreAccessibilityFocus(day)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layoutChildren() {
|
||||
final Calendar focusedDay = findAccessibilityFocus();
|
||||
super.layoutChildren();
|
||||
if (mPerformingScroll) {
|
||||
mPerformingScroll = false;
|
||||
} else {
|
||||
restoreAccessibilityFocus(focusedDay);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
mYearFormat = new SimpleDateFormat("yyyy", Locale.getDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
event.setItemCount(-1);
|
||||
}
|
||||
|
||||
private String getMonthAndYearString(Calendar day) {
|
||||
StringBuffer sbuf = new StringBuffer();
|
||||
sbuf.append(day.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
|
||||
sbuf.append(" ");
|
||||
sbuf.append(mYearFormat.format(day.getTime()));
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Necessary for accessibility, to ensure we support "scrolling" forward and backward
|
||||
* in the month list.
|
||||
*/
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
|
||||
}
|
||||
|
||||
/**
|
||||
* When scroll forward/backward events are received, announce the newly scrolled-to month.
|
||||
*/
|
||||
@Override
|
||||
public boolean performAccessibilityAction(int action, Bundle arguments) {
|
||||
if (action != AccessibilityNodeInfo.ACTION_SCROLL_FORWARD &&
|
||||
action != AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
|
||||
return super.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
|
||||
// Figure out what month is showing.
|
||||
int firstVisiblePosition = getFirstVisiblePosition();
|
||||
int month = firstVisiblePosition % 12;
|
||||
int year = firstVisiblePosition / 12 + mController.getMinYear();
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.set(year, month, 1);
|
||||
|
||||
// Scroll either forward or backward one month.
|
||||
if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
|
||||
day.add(Calendar.MONTH, 1);
|
||||
if (day.get(Calendar.MONTH) == 12) {
|
||||
day.set(Calendar.MONTH, 0);
|
||||
day.add(Calendar.YEAR, 1);
|
||||
}
|
||||
} else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
|
||||
View firstVisibleView = getChildAt(0);
|
||||
// If the view is fully visible, jump one month back. Otherwise, we'll just jump
|
||||
// to the first day of first visible month.
|
||||
if (firstVisibleView != null && firstVisibleView.getTop() >= -1) {
|
||||
// There's an off-by-one somewhere, so the top of the first visible item will
|
||||
// actually be -1 when it's at the exact top.
|
||||
day.add(Calendar.MONTH, -1);
|
||||
if (day.get(Calendar.MONTH) == -1) {
|
||||
day.set(Calendar.MONTH, 11);
|
||||
day.add(Calendar.YEAR, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go to that month.
|
||||
announceForAccessibility(getMonthAndYearString(day));
|
||||
goTo(day, true, false, true);
|
||||
mPerformingScroll = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
27
core/java/android/widget/OnDateChangedListener.java
Normal file
27
core/java/android/widget/OnDateChangedListener.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* The callback used to notify other date picker components of a change in the selected date.
|
||||
*
|
||||
*/
|
||||
interface OnDateChangedListener {
|
||||
|
||||
public void onDateChanged();
|
||||
}
|
||||
|
||||
178
core/java/android/widget/SimpleMonthAdapter.java
Normal file
178
core/java/android/widget/SimpleMonthAdapter.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* An adapter for a list of {@link android.widget.SimpleMonthView} items.
|
||||
*/
|
||||
class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayClickListener {
|
||||
private static final String TAG = "SimpleMonthAdapter";
|
||||
|
||||
private final Context mContext;
|
||||
private final DatePickerController mController;
|
||||
private Calendar mSelectedDay;
|
||||
|
||||
private ColorStateList mCalendarTextColors;
|
||||
|
||||
public SimpleMonthAdapter(Context context, DatePickerController controller) {
|
||||
mContext = context;
|
||||
mController = controller;
|
||||
init();
|
||||
setSelectedDay(mController.getSelectedDay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the selected day and related parameters.
|
||||
*
|
||||
* @param day The day to highlight
|
||||
*/
|
||||
public void setSelectedDay(Calendar day) {
|
||||
if (mSelectedDay != day) {
|
||||
mSelectedDay = day;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void setCalendarTextColor(ColorStateList colors) {
|
||||
mCalendarTextColors = colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the gesture detector and selected time
|
||||
*/
|
||||
protected void init() {
|
||||
mSelectedDay = Calendar.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int diffYear = mController.getMaxYear() - mController.getMinYear();
|
||||
final int diffMonth = 1 + mController.getMaxMonth() - mController.getMinMonth()
|
||||
+ 12 * diffYear;
|
||||
return diffMonth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
SimpleMonthView v;
|
||||
HashMap<String, Integer> drawingParams = null;
|
||||
if (convertView != null) {
|
||||
v = (SimpleMonthView) convertView;
|
||||
// We store the drawing parameters in the view so it can be recycled
|
||||
drawingParams = (HashMap<String, Integer>) v.getTag();
|
||||
} else {
|
||||
v = new SimpleMonthView(mContext);
|
||||
// Set up the new view
|
||||
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
|
||||
AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT);
|
||||
v.setLayoutParams(params);
|
||||
v.setClickable(true);
|
||||
v.setOnDayClickListener(this);
|
||||
if (mCalendarTextColors != null) {
|
||||
v.setTextColor(mCalendarTextColors);
|
||||
}
|
||||
}
|
||||
if (drawingParams == null) {
|
||||
drawingParams = new HashMap<String, Integer>();
|
||||
} else {
|
||||
drawingParams.clear();
|
||||
}
|
||||
final int currentMonth = position + mController.getMinMonth();
|
||||
final int month = currentMonth % 12;
|
||||
final int year = currentMonth / 12 + mController.getMinYear();
|
||||
|
||||
int selectedDay = -1;
|
||||
if (isSelectedDayInMonth(year, month)) {
|
||||
selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
// Invokes requestLayout() to ensure that the recycled view is set with the appropriate
|
||||
// height/number of weeks before being displayed.
|
||||
v.reuse();
|
||||
|
||||
final int enabledDayRangeStart;
|
||||
if (mController.getMinMonth() == month && mController.getMinYear() == year) {
|
||||
enabledDayRangeStart = mController.getMinDay();
|
||||
} else {
|
||||
enabledDayRangeStart = 1;
|
||||
}
|
||||
|
||||
final int enabledDayRangeEnd;
|
||||
if (mController.getMaxMonth() == month && mController.getMaxYear() == year) {
|
||||
enabledDayRangeEnd = mController.getMaxDay();
|
||||
} else {
|
||||
enabledDayRangeEnd = 31;
|
||||
}
|
||||
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_DAY, selectedDay);
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_YEAR, year);
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_MONTH, month);
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_WEEK_START, mController.getFirstDayOfWeek());
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_ENABLEDDAYRANGE_START, enabledDayRangeStart);
|
||||
drawingParams.put(SimpleMonthView.VIEW_PARAMS_ENABLEDDAYRANGE_END, enabledDayRangeEnd);
|
||||
v.setMonthParams(drawingParams);
|
||||
v.invalidate();
|
||||
return v;
|
||||
}
|
||||
|
||||
private boolean isSelectedDayInMonth(int year, int month) {
|
||||
return mSelectedDay.get(Calendar.YEAR) == year && mSelectedDay.get(Calendar.MONTH) == month;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDayClick(SimpleMonthView view, Calendar day) {
|
||||
if (day != null) {
|
||||
onDayTapped(day);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maintains the same hour/min/sec but moves the day to the tapped day.
|
||||
*
|
||||
* @param day The day that was tapped
|
||||
*/
|
||||
protected void onDayTapped(Calendar day) {
|
||||
mController.tryVibrate();
|
||||
mController.onDayOfMonthSelected(day.get(Calendar.YEAR), day.get(Calendar.MONTH),
|
||||
day.get(Calendar.DAY_OF_MONTH));
|
||||
setSelectedDay(day);
|
||||
}
|
||||
}
|
||||
720
core/java/android/widget/SimpleMonthView.java
Normal file
720
core/java/android/widget/SimpleMonthView.java
Normal file
@@ -0,0 +1,720 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.widget.ExploreByTouchHelper;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A calendar-like view displaying a specified month and the appropriate selectable day numbers
|
||||
* within the specified month.
|
||||
*/
|
||||
class SimpleMonthView extends View {
|
||||
private static final String TAG = "SimpleMonthView";
|
||||
|
||||
/**
|
||||
* These params can be passed into the view to control how it appears.
|
||||
* {@link #VIEW_PARAMS_WEEK} is the only required field, though the default
|
||||
* values are unlikely to fit most layouts correctly.
|
||||
*/
|
||||
/**
|
||||
* This sets the height of this week in pixels
|
||||
*/
|
||||
static final String VIEW_PARAMS_HEIGHT = "height";
|
||||
/**
|
||||
* This specifies the position (or weeks since the epoch) of this week,
|
||||
* calculated using
|
||||
*/
|
||||
static final String VIEW_PARAMS_MONTH = "month";
|
||||
/**
|
||||
* This specifies the position (or weeks since the epoch) of this week,
|
||||
* calculated using
|
||||
*/
|
||||
static final String VIEW_PARAMS_YEAR = "year";
|
||||
/**
|
||||
* This sets one of the days in this view as selected {@link Time#SUNDAY}
|
||||
* through {@link Time#SATURDAY}.
|
||||
*/
|
||||
static final String VIEW_PARAMS_SELECTED_DAY = "selected_day";
|
||||
/**
|
||||
* Which day the week should start on. {@link Time#SUNDAY} through
|
||||
* {@link Time#SATURDAY}.
|
||||
*/
|
||||
static final String VIEW_PARAMS_WEEK_START = "week_start";
|
||||
/**
|
||||
* First enabled day.
|
||||
*/
|
||||
static final String VIEW_PARAMS_ENABLEDDAYRANGE_START = "enabled_day_range_start";
|
||||
/**
|
||||
* Last enabled day.
|
||||
*/
|
||||
static final String VIEW_PARAMS_ENABLEDDAYRANGE_END = "enabled_day_range_end";
|
||||
|
||||
private static int DEFAULT_HEIGHT = 32;
|
||||
private static int MIN_HEIGHT = 10;
|
||||
|
||||
private static final int DEFAULT_SELECTED_DAY = -1;
|
||||
private static final int DEFAULT_WEEK_START = Calendar.SUNDAY;
|
||||
private static final int DEFAULT_NUM_DAYS = 7;
|
||||
private static final int DEFAULT_NUM_ROWS = 6;
|
||||
private static final int MAX_NUM_ROWS = 6;
|
||||
|
||||
private static final int SELECTED_CIRCLE_ALPHA = 60;
|
||||
|
||||
private static int DAY_SEPARATOR_WIDTH = 1;
|
||||
|
||||
private int mMiniDayNumberTextSize;
|
||||
private int mMonthLabelTextSize;
|
||||
private int mMonthDayLabelTextSize;
|
||||
private int mMonthHeaderSize;
|
||||
private int mDaySelectedCircleSize;
|
||||
|
||||
// used for scaling to the device density
|
||||
private static float mScale = 0;
|
||||
|
||||
// affects the padding on the sides of this view
|
||||
private int mPadding = 0;
|
||||
|
||||
private String mDayOfWeekTypeface;
|
||||
private String mMonthTitleTypeface;
|
||||
|
||||
private Paint mDayNumberPaint;
|
||||
private Paint mDayNumberDisabledPaint;
|
||||
private Paint mDayNumberSelectedPaint;
|
||||
|
||||
private Paint mMonthTitlePaint;
|
||||
private Paint mMonthDayLabelPaint;
|
||||
|
||||
private final Formatter mFormatter;
|
||||
private final StringBuilder mStringBuilder;
|
||||
|
||||
private int mMonth;
|
||||
private int mYear;
|
||||
|
||||
// Quick reference to the width of this view, matches parent
|
||||
private int mWidth;
|
||||
|
||||
// The height this view should draw at in pixels, set by height param
|
||||
private int mRowHeight = DEFAULT_HEIGHT;
|
||||
|
||||
// If this view contains the today
|
||||
private boolean mHasToday = false;
|
||||
|
||||
// Which day is selected [0-6] or -1 if no day is selected
|
||||
private int mSelectedDay = -1;
|
||||
|
||||
// Which day is today [0-6] or -1 if no day is today
|
||||
private int mToday = DEFAULT_SELECTED_DAY;
|
||||
|
||||
// Which day of the week to start on [0-6]
|
||||
private int mWeekStart = DEFAULT_WEEK_START;
|
||||
|
||||
// How many days to display
|
||||
private int mNumDays = DEFAULT_NUM_DAYS;
|
||||
|
||||
// The number of days + a spot for week number if it is displayed
|
||||
private int mNumCells = mNumDays;
|
||||
|
||||
private int mDayOfWeekStart = 0;
|
||||
|
||||
// First enabled day
|
||||
private int mEnabledDayStart = 1;
|
||||
|
||||
// Last enabled day
|
||||
private int mEnabledDayEnd = 31;
|
||||
|
||||
private final Calendar mCalendar = Calendar.getInstance();
|
||||
private final Calendar mDayLabelCalendar = Calendar.getInstance();
|
||||
|
||||
private final MonthViewTouchHelper mTouchHelper;
|
||||
|
||||
private int mNumRows = DEFAULT_NUM_ROWS;
|
||||
|
||||
// Optional listener for handling day click actions
|
||||
private OnDayClickListener mOnDayClickListener;
|
||||
|
||||
// Whether to prevent setting the accessibility delegate
|
||||
private boolean mLockAccessibilityDelegate;
|
||||
|
||||
private int mNormalTextColor;
|
||||
private int mDisabledTextColor;
|
||||
private int mSelectedDayColor;
|
||||
|
||||
public SimpleMonthView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SimpleMonthView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.datePickerStyle);
|
||||
}
|
||||
|
||||
public SimpleMonthView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs);
|
||||
|
||||
final Resources res = context.getResources();
|
||||
|
||||
mDayOfWeekTypeface = res.getString(R.string.day_of_week_label_typeface);
|
||||
mMonthTitleTypeface = res.getString(R.string.sans_serif);
|
||||
|
||||
mStringBuilder = new StringBuilder(50);
|
||||
mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
|
||||
|
||||
mMiniDayNumberTextSize = res.getDimensionPixelSize(R.dimen.datepicker_day_number_size);
|
||||
mMonthLabelTextSize = res.getDimensionPixelSize(R.dimen.datepicker_month_label_size);
|
||||
mMonthDayLabelTextSize = res.getDimensionPixelSize(
|
||||
R.dimen.datepicker_month_day_label_text_size);
|
||||
mMonthHeaderSize = res.getDimensionPixelOffset(
|
||||
R.dimen.datepicker_month_list_item_header_height);
|
||||
mDaySelectedCircleSize = res.getDimensionPixelSize(
|
||||
R.dimen.datepicker_day_number_select_circle_radius);
|
||||
|
||||
mRowHeight = (res.getDimensionPixelOffset(R.dimen.datepicker_view_animator_height)
|
||||
- mMonthHeaderSize) / MAX_NUM_ROWS;
|
||||
|
||||
// Set up accessibility components.
|
||||
mTouchHelper = new MonthViewTouchHelper(this);
|
||||
setAccessibilityDelegate(mTouchHelper);
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
mLockAccessibilityDelegate = true;
|
||||
|
||||
// Sets up any standard paints that will be used
|
||||
initView();
|
||||
}
|
||||
|
||||
void setTextColor(ColorStateList colors) {
|
||||
final Resources res = getContext().getResources();
|
||||
|
||||
mNormalTextColor = colors.getColorForState(ENABLED_STATE_SET,
|
||||
res.getColor(R.color.datepicker_default_normal_text_color_holo_light));
|
||||
mMonthTitlePaint.setColor(mNormalTextColor);
|
||||
mMonthDayLabelPaint.setColor(mNormalTextColor);
|
||||
|
||||
mDisabledTextColor = colors.getColorForState(EMPTY_STATE_SET,
|
||||
res.getColor(R.color.datepicker_default_disabled_text_color_holo_light));
|
||||
mDayNumberDisabledPaint.setColor(mDisabledTextColor);
|
||||
|
||||
mSelectedDayColor = colors.getColorForState(ENABLED_SELECTED_STATE_SET,
|
||||
res.getColor(R.color.holo_blue_light));
|
||||
mDayNumberSelectedPaint.setColor(mSelectedDayColor);
|
||||
mDayNumberSelectedPaint.setAlpha(SELECTED_CIRCLE_ALPHA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
|
||||
// Workaround for a JB MR1 issue where accessibility delegates on
|
||||
// top-level ListView items are overwritten.
|
||||
if (!mLockAccessibilityDelegate) {
|
||||
super.setAccessibilityDelegate(delegate);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnDayClickListener(OnDayClickListener listener) {
|
||||
mOnDayClickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
||||
// First right-of-refusal goes the touch exploration helper.
|
||||
if (mTouchHelper.dispatchHoverEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
return super.dispatchHoverEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_UP:
|
||||
final int day = getDayFromLocation(event.getX(), event.getY());
|
||||
if (day >= 0) {
|
||||
onDayClick(day);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the text and style properties for painting.
|
||||
*/
|
||||
private void initView() {
|
||||
mMonthTitlePaint = new Paint();
|
||||
mMonthTitlePaint.setAntiAlias(true);
|
||||
mMonthTitlePaint.setColor(mNormalTextColor);
|
||||
mMonthTitlePaint.setTextSize(mMonthLabelTextSize);
|
||||
mMonthTitlePaint.setTypeface(Typeface.create(mMonthTitleTypeface, Typeface.BOLD));
|
||||
mMonthTitlePaint.setTextAlign(Align.CENTER);
|
||||
mMonthTitlePaint.setStyle(Style.FILL);
|
||||
mMonthTitlePaint.setFakeBoldText(true);
|
||||
|
||||
mMonthDayLabelPaint = new Paint();
|
||||
mMonthDayLabelPaint.setAntiAlias(true);
|
||||
mMonthDayLabelPaint.setColor(mNormalTextColor);
|
||||
mMonthDayLabelPaint.setTextSize(mMonthDayLabelTextSize);
|
||||
mMonthDayLabelPaint.setTypeface(Typeface.create(mDayOfWeekTypeface, Typeface.NORMAL));
|
||||
mMonthDayLabelPaint.setTextAlign(Align.CENTER);
|
||||
mMonthDayLabelPaint.setStyle(Style.FILL);
|
||||
mMonthDayLabelPaint.setFakeBoldText(true);
|
||||
|
||||
mDayNumberSelectedPaint = new Paint();
|
||||
mDayNumberSelectedPaint.setAntiAlias(true);
|
||||
mDayNumberSelectedPaint.setColor(mSelectedDayColor);
|
||||
mDayNumberSelectedPaint.setAlpha(SELECTED_CIRCLE_ALPHA);
|
||||
mDayNumberSelectedPaint.setTextAlign(Align.CENTER);
|
||||
mDayNumberSelectedPaint.setStyle(Style.FILL);
|
||||
mDayNumberSelectedPaint.setFakeBoldText(true);
|
||||
|
||||
mDayNumberPaint = new Paint();
|
||||
mDayNumberPaint.setAntiAlias(true);
|
||||
mDayNumberPaint.setTextSize(mMiniDayNumberTextSize);
|
||||
mDayNumberPaint.setTextAlign(Align.CENTER);
|
||||
mDayNumberPaint.setStyle(Style.FILL);
|
||||
mDayNumberPaint.setFakeBoldText(false);
|
||||
|
||||
mDayNumberDisabledPaint = new Paint();
|
||||
mDayNumberDisabledPaint.setAntiAlias(true);
|
||||
mDayNumberDisabledPaint.setColor(mDisabledTextColor);
|
||||
mDayNumberDisabledPaint.setTextSize(mMiniDayNumberTextSize);
|
||||
mDayNumberDisabledPaint.setTextAlign(Align.CENTER);
|
||||
mDayNumberDisabledPaint.setStyle(Style.FILL);
|
||||
mDayNumberDisabledPaint.setFakeBoldText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
drawMonthTitle(canvas);
|
||||
drawWeekDayLabels(canvas);
|
||||
drawDays(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all the parameters for displaying this week. The only required
|
||||
* parameter is the week number. Other parameters have a default value and
|
||||
* will only update if a new value is included, except for focus month,
|
||||
* which will always default to no focus month if no value is passed in. See
|
||||
* {@link #VIEW_PARAMS_HEIGHT} for more info on parameters.
|
||||
*
|
||||
* @param params A map of the new parameters, see
|
||||
* {@link #VIEW_PARAMS_HEIGHT}
|
||||
*/
|
||||
void setMonthParams(HashMap<String, Integer> params) {
|
||||
if (!params.containsKey(VIEW_PARAMS_MONTH) && !params.containsKey(VIEW_PARAMS_YEAR)) {
|
||||
throw new InvalidParameterException(
|
||||
"You must specify the month and year for this view");
|
||||
}
|
||||
setTag(params);
|
||||
// We keep the current value for any params not present
|
||||
if (params.containsKey(VIEW_PARAMS_HEIGHT)) {
|
||||
mRowHeight = params.get(VIEW_PARAMS_HEIGHT);
|
||||
if (mRowHeight < MIN_HEIGHT) {
|
||||
mRowHeight = MIN_HEIGHT;
|
||||
}
|
||||
}
|
||||
if (params.containsKey(VIEW_PARAMS_SELECTED_DAY)) {
|
||||
mSelectedDay = params.get(VIEW_PARAMS_SELECTED_DAY);
|
||||
}
|
||||
|
||||
// Allocate space for caching the day numbers and focus values
|
||||
mMonth = params.get(VIEW_PARAMS_MONTH);
|
||||
mYear = params.get(VIEW_PARAMS_YEAR);
|
||||
|
||||
// Figure out what day today is
|
||||
final Time today = new Time(Time.getCurrentTimezone());
|
||||
today.setToNow();
|
||||
mHasToday = false;
|
||||
mToday = -1;
|
||||
|
||||
mCalendar.set(Calendar.MONTH, mMonth);
|
||||
mCalendar.set(Calendar.YEAR, mYear);
|
||||
mCalendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
mDayOfWeekStart = mCalendar.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
|
||||
mWeekStart = params.get(VIEW_PARAMS_WEEK_START);
|
||||
} else {
|
||||
mWeekStart = mCalendar.getFirstDayOfWeek();
|
||||
}
|
||||
|
||||
if (params.containsKey(VIEW_PARAMS_ENABLEDDAYRANGE_START)) {
|
||||
mEnabledDayStart = params.get(VIEW_PARAMS_ENABLEDDAYRANGE_START);
|
||||
}
|
||||
if (params.containsKey(VIEW_PARAMS_ENABLEDDAYRANGE_END)) {
|
||||
mEnabledDayEnd = params.get(VIEW_PARAMS_ENABLEDDAYRANGE_END);
|
||||
}
|
||||
|
||||
mNumCells = getDaysInMonth(mMonth, mYear);
|
||||
for (int i = 0; i < mNumCells; i++) {
|
||||
final int day = i + 1;
|
||||
if (sameDay(day, today)) {
|
||||
mHasToday = true;
|
||||
mToday = day;
|
||||
}
|
||||
}
|
||||
mNumRows = calculateNumRows();
|
||||
|
||||
// Invalidate cached accessibility information.
|
||||
mTouchHelper.invalidateRoot();
|
||||
}
|
||||
|
||||
private static int getDaysInMonth(int month, int year) {
|
||||
switch (month) {
|
||||
case Calendar.JANUARY:
|
||||
case Calendar.MARCH:
|
||||
case Calendar.MAY:
|
||||
case Calendar.JULY:
|
||||
case Calendar.AUGUST:
|
||||
case Calendar.OCTOBER:
|
||||
case Calendar.DECEMBER:
|
||||
return 31;
|
||||
case Calendar.APRIL:
|
||||
case Calendar.JUNE:
|
||||
case Calendar.SEPTEMBER:
|
||||
case Calendar.NOVEMBER:
|
||||
return 30;
|
||||
case Calendar.FEBRUARY:
|
||||
return (year % 4 == 0) ? 29 : 28;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Month");
|
||||
}
|
||||
}
|
||||
|
||||
public void reuse() {
|
||||
mNumRows = DEFAULT_NUM_ROWS;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
private int calculateNumRows() {
|
||||
int offset = findDayOffset();
|
||||
int dividend = (offset + mNumCells) / mNumDays;
|
||||
int remainder = (offset + mNumCells) % mNumDays;
|
||||
return (dividend + (remainder > 0 ? 1 : 0));
|
||||
}
|
||||
|
||||
private boolean sameDay(int day, Time today) {
|
||||
return mYear == today.year &&
|
||||
mMonth == today.month &&
|
||||
day == today.monthDay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mRowHeight * mNumRows
|
||||
+ mMonthHeaderSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
mWidth = w;
|
||||
|
||||
// Invalidate cached accessibility information.
|
||||
mTouchHelper.invalidateRoot();
|
||||
}
|
||||
|
||||
private String getMonthAndYearString() {
|
||||
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
|
||||
| DateUtils.FORMAT_NO_MONTH_DAY;
|
||||
mStringBuilder.setLength(0);
|
||||
long millis = mCalendar.getTimeInMillis();
|
||||
return DateUtils.formatDateRange(getContext(), mFormatter, millis, millis, flags,
|
||||
Time.getCurrentTimezone()).toString();
|
||||
}
|
||||
|
||||
private void drawMonthTitle(Canvas canvas) {
|
||||
int x = (mWidth + 2 * mPadding) / 2;
|
||||
int y = (mMonthHeaderSize - mMonthDayLabelTextSize) / 2 + (mMonthLabelTextSize / 3);
|
||||
canvas.drawText(getMonthAndYearString(), x, y, mMonthTitlePaint);
|
||||
}
|
||||
|
||||
private void drawWeekDayLabels(Canvas canvas) {
|
||||
int y = mMonthHeaderSize - (mMonthDayLabelTextSize / 2);
|
||||
int dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
|
||||
|
||||
for (int i = 0; i < mNumDays; i++) {
|
||||
int calendarDay = (i + mWeekStart) % mNumDays;
|
||||
int x = (2 * i + 1) * dayWidthHalf + mPadding;
|
||||
mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay);
|
||||
canvas.drawText(mDayLabelCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT,
|
||||
Locale.getDefault()).toUpperCase(Locale.getDefault()), x, y,
|
||||
mMonthDayLabelPaint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the month days.
|
||||
*/
|
||||
private void drawDays(Canvas canvas) {
|
||||
int y = (((mRowHeight + mMiniDayNumberTextSize) / 2) - DAY_SEPARATOR_WIDTH)
|
||||
+ mMonthHeaderSize;
|
||||
int dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
|
||||
int j = findDayOffset();
|
||||
for (int day = 1; day <= mNumCells; day++) {
|
||||
int x = (2 * j + 1) * dayWidthHalf + mPadding;
|
||||
if (mSelectedDay == day) {
|
||||
canvas.drawCircle(x, y - (mMiniDayNumberTextSize / 3), mDaySelectedCircleSize,
|
||||
mDayNumberSelectedPaint);
|
||||
}
|
||||
|
||||
if (mHasToday && mToday == day) {
|
||||
mDayNumberPaint.setColor(mSelectedDayColor);
|
||||
} else {
|
||||
mDayNumberPaint.setColor(mNormalTextColor);
|
||||
}
|
||||
final Paint paint = (day < mEnabledDayStart || day > mEnabledDayEnd) ?
|
||||
mDayNumberDisabledPaint : mDayNumberPaint;
|
||||
canvas.drawText(String.format("%d", day), x, y, paint);
|
||||
j++;
|
||||
if (j == mNumDays) {
|
||||
j = 0;
|
||||
y += mRowHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int findDayOffset() {
|
||||
return (mDayOfWeekStart < mWeekStart ? (mDayOfWeekStart + mNumDays) : mDayOfWeekStart)
|
||||
- mWeekStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the day that the given x position is in, accounting for week
|
||||
* number. Returns the day or -1 if the position wasn't in a day.
|
||||
*
|
||||
* @param x The x position of the touch event
|
||||
* @return The day number, or -1 if the position wasn't in a day
|
||||
*/
|
||||
private int getDayFromLocation(float x, float y) {
|
||||
int dayStart = mPadding;
|
||||
if (x < dayStart || x > mWidth - mPadding) {
|
||||
return -1;
|
||||
}
|
||||
// Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
|
||||
int row = (int) (y - mMonthHeaderSize) / mRowHeight;
|
||||
int column = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));
|
||||
|
||||
int day = column - findDayOffset() + 1;
|
||||
day += row * mNumDays;
|
||||
if (day < 1 || day > mNumCells) {
|
||||
return -1;
|
||||
}
|
||||
return day;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user clicks on a day. Handles callbacks to the
|
||||
* {@link OnDayClickListener} if one is set.
|
||||
*
|
||||
* @param day The day that was clicked
|
||||
*/
|
||||
private void onDayClick(int day) {
|
||||
if (mOnDayClickListener != null) {
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.set(mYear, mMonth, day);
|
||||
mOnDayClickListener.onDayClick(this, date);
|
||||
}
|
||||
|
||||
// This is a no-op if accessibility is turned off.
|
||||
mTouchHelper.sendEventForVirtualView(day, AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The date that has accessibility focus, or {@code null} if no date
|
||||
* has focus
|
||||
*/
|
||||
Calendar getAccessibilityFocus() {
|
||||
final int day = mTouchHelper.getFocusedVirtualView();
|
||||
Calendar date = null;
|
||||
if (day >= 0) {
|
||||
date = Calendar.getInstance();
|
||||
date.set(mYear, mMonth, day);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears accessibility focus within the view. No-op if the view does not
|
||||
* contain accessibility focus.
|
||||
*/
|
||||
public void clearAccessibilityFocus() {
|
||||
mTouchHelper.clearFocusedVirtualView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to restore accessibility focus to the specified date.
|
||||
*
|
||||
* @param day The date which should receive focus
|
||||
* @return {@code false} if the date is not valid for this month view, or
|
||||
* {@code true} if the date received focus
|
||||
*/
|
||||
boolean restoreAccessibilityFocus(Calendar day) {
|
||||
if ((day.get(Calendar.YEAR) != mYear) || (day.get(Calendar.MONTH) != mMonth) ||
|
||||
(day.get(Calendar.DAY_OF_MONTH) > mNumCells)) {
|
||||
return false;
|
||||
}
|
||||
mTouchHelper.setFocusedVirtualView(day.get(Calendar.DAY_OF_MONTH));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a virtual view hierarchy for interfacing with an accessibility
|
||||
* service.
|
||||
*/
|
||||
private class MonthViewTouchHelper extends ExploreByTouchHelper {
|
||||
private static final String DATE_FORMAT = "dd MMMM yyyy";
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
private final Calendar mTempCalendar = Calendar.getInstance();
|
||||
|
||||
public MonthViewTouchHelper(View host) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
public void setFocusedVirtualView(int virtualViewId) {
|
||||
getAccessibilityNodeProvider(SimpleMonthView.this).performAction(
|
||||
virtualViewId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
|
||||
}
|
||||
|
||||
public void clearFocusedVirtualView() {
|
||||
final int focusedVirtualView = getFocusedVirtualView();
|
||||
if (focusedVirtualView != ExploreByTouchHelper.INVALID_ID) {
|
||||
getAccessibilityNodeProvider(SimpleMonthView.this).performAction(
|
||||
focusedVirtualView,
|
||||
AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS,
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVirtualViewAt(float x, float y) {
|
||||
final int day = getDayFromLocation(x, y);
|
||||
if (day >= 0) {
|
||||
return day;
|
||||
}
|
||||
return ExploreByTouchHelper.INVALID_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
|
||||
for (int day = 1; day <= mNumCells; day++) {
|
||||
virtualViewIds.add(day);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
|
||||
event.setContentDescription(getItemDescription(virtualViewId));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) {
|
||||
getItemBounds(virtualViewId, mTempRect);
|
||||
|
||||
node.setContentDescription(getItemDescription(virtualViewId));
|
||||
node.setBoundsInParent(mTempRect);
|
||||
node.addAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
|
||||
if (virtualViewId == mSelectedDay) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onPerformActionForVirtualView(int virtualViewId, int action,
|
||||
Bundle arguments) {
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_CLICK:
|
||||
onDayClick(virtualViewId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the bounding rectangle of a given time object.
|
||||
*
|
||||
* @param day The day to calculate bounds for
|
||||
* @param rect The rectangle in which to store the bounds
|
||||
*/
|
||||
private void getItemBounds(int day, Rect rect) {
|
||||
final int offsetX = mPadding;
|
||||
final int offsetY = mMonthHeaderSize;
|
||||
final int cellHeight = mRowHeight;
|
||||
final int cellWidth = ((mWidth - (2 * mPadding)) / mNumDays);
|
||||
final int index = ((day - 1) + findDayOffset());
|
||||
final int row = (index / mNumDays);
|
||||
final int column = (index % mNumDays);
|
||||
final int x = (offsetX + (column * cellWidth));
|
||||
final int y = (offsetY + (row * cellHeight));
|
||||
|
||||
rect.set(x, y, (x + cellWidth), (y + cellHeight));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a description for a given time object. Since this
|
||||
* description will be spoken, the components are ordered by descending
|
||||
* specificity as DAY MONTH YEAR.
|
||||
*
|
||||
* @param day The day to generate a description for
|
||||
* @return A description of the time object
|
||||
*/
|
||||
private CharSequence getItemDescription(int day) {
|
||||
mTempCalendar.set(mYear, mMonth, day);
|
||||
final CharSequence date = DateFormat.format(DATE_FORMAT,
|
||||
mTempCalendar.getTimeInMillis());
|
||||
|
||||
if (day == mSelectedDay) {
|
||||
return getContext().getString(R.string.item_is_selected, date);
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles callbacks when the user clicks on a time object.
|
||||
*/
|
||||
public interface OnDayClickListener {
|
||||
public void onDayClick(SimpleMonthView view, Calendar day);
|
||||
}
|
||||
}
|
||||
114
core/java/android/widget/TextViewWithCircularIndicator.java
Normal file
114
core/java/android/widget/TextViewWithCircularIndicator.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
class TextViewWithCircularIndicator extends TextView {
|
||||
|
||||
private static final int SELECTED_CIRCLE_ALPHA = 60;
|
||||
|
||||
private final Paint mCirclePaint = new Paint();
|
||||
|
||||
private final String mItemIsSelectedText;
|
||||
private int mCircleColor;
|
||||
private boolean mDrawIndicator;
|
||||
|
||||
public TextViewWithCircularIndicator(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TextViewWithCircularIndicator(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public TextViewWithCircularIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public TextViewWithCircularIndicator(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
|
||||
super(context, attrs);
|
||||
Resources res = context.getResources();
|
||||
|
||||
// Use Theme attributes if possible
|
||||
final TypedArray a = mContext.obtainStyledAttributes(attrs,
|
||||
R.styleable.DatePicker, defStyleAttr, defStyleRes);
|
||||
|
||||
final int resId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorYearListItemTextAppearance, -1);
|
||||
if (resId != -1) {
|
||||
setTextAppearance(context, resId);
|
||||
}
|
||||
|
||||
mItemIsSelectedText = res.getString(R.string.item_is_selected);
|
||||
|
||||
a.recycle();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mCirclePaint.setTypeface(Typeface.create(mCirclePaint.getTypeface(), Typeface.BOLD));
|
||||
mCirclePaint.setAntiAlias(true);
|
||||
mCirclePaint.setTextAlign(Paint.Align.CENTER);
|
||||
mCirclePaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
public void setCircleColor(int color) {
|
||||
if (color != mCircleColor) {
|
||||
mCircleColor = color;
|
||||
mCirclePaint.setColor(mCircleColor);
|
||||
mCirclePaint.setAlpha(SELECTED_CIRCLE_ALPHA);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDrawIndicator(boolean drawIndicator) {
|
||||
mDrawIndicator = drawIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (mDrawIndicator) {
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
int radius = Math.min(width, height) / 2;
|
||||
canvas.drawCircle(width / 2, height / 2, radius, mCirclePaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getContentDescription() {
|
||||
CharSequence itemText = getText();
|
||||
if (mDrawIndicator) {
|
||||
return String.format(mItemIsSelectedText, itemText);
|
||||
} else {
|
||||
return itemText;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1389,8 +1389,8 @@ class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implement
|
||||
final Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
|
||||
final Keyframe k3 = Keyframe.ofFloat(1f, 1f);
|
||||
|
||||
PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3);
|
||||
PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", k0, k1, k2, k3);
|
||||
PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe(View.SCALE_X, k0, k1, k2, k3);
|
||||
PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe(View.SCALE_Y, k0, k1, k2, k3);
|
||||
ObjectAnimator pulseAnimator =
|
||||
ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY);
|
||||
pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION);
|
||||
|
||||
200
core/java/android/widget/YearPickerView.java
Normal file
200
core/java/android/widget/YearPickerView.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* Displays a selectable list of years.
|
||||
*/
|
||||
class YearPickerView extends ListView implements AdapterView.OnItemClickListener,
|
||||
OnDateChangedListener {
|
||||
private static final String TAG = "YearPickerView";
|
||||
|
||||
private DatePickerController mController;
|
||||
private YearAdapter mAdapter;
|
||||
private int mViewSize;
|
||||
private int mChildSize;
|
||||
private int mSelectedPosition = -1;
|
||||
private int mYearSelectedCircleColor;
|
||||
|
||||
public YearPickerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public YearPickerView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public YearPickerView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public YearPickerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
ViewGroup.LayoutParams frame = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT);
|
||||
setLayoutParams(frame);
|
||||
|
||||
Resources res = context.getResources();
|
||||
mViewSize = res.getDimensionPixelOffset(R.dimen.datepicker_view_animator_height);
|
||||
mChildSize = res.getDimensionPixelOffset(R.dimen.datepicker_year_label_height);
|
||||
|
||||
setVerticalFadingEdgeEnabled(true);
|
||||
setFadingEdgeLength(mChildSize / 3);
|
||||
|
||||
final int paddingTop = res.getDimensionPixelSize(
|
||||
R.dimen.datepicker_year_picker_padding_top);
|
||||
setPadding(0, paddingTop, 0, 0);
|
||||
|
||||
// Use Theme attributes if possible
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.DatePicker, defStyleAttr, defStyleRes);
|
||||
|
||||
final int colorResId = a.getResourceId(
|
||||
R.styleable.DatePicker_dateSelectorYearListSelectedCircleColor,
|
||||
R.color.datepicker_default_circle_background_color_holo_light);
|
||||
mYearSelectedCircleColor = res.getColor(colorResId);
|
||||
|
||||
a.recycle();
|
||||
|
||||
setOnItemClickListener(this);
|
||||
setDividerHeight(0);
|
||||
}
|
||||
|
||||
public void init(DatePickerController controller) {
|
||||
mController = controller;
|
||||
mController.registerOnDateChangedListener(this);
|
||||
|
||||
mAdapter = new YearAdapter(getContext(), R.layout.year_label_text_view);
|
||||
updateAdapterData();
|
||||
setAdapter(mAdapter);
|
||||
|
||||
onDateChanged();
|
||||
}
|
||||
|
||||
public void setYearSelectedCircleColor(int color) {
|
||||
if (color != mYearSelectedCircleColor) {
|
||||
mYearSelectedCircleColor = color;
|
||||
}
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public int getYearSelectedCircleColor() {
|
||||
return mYearSelectedCircleColor;
|
||||
}
|
||||
|
||||
private void updateAdapterData() {
|
||||
mAdapter.clear();
|
||||
final int maxYear = mController.getMaxYear();
|
||||
for (int year = mController.getMinYear(); year <= maxYear; year++) {
|
||||
mAdapter.add(year);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
mController.tryVibrate();
|
||||
if (position != mSelectedPosition) {
|
||||
mSelectedPosition = position;
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
mController.onYearSelected(mAdapter.getItem(position));
|
||||
}
|
||||
|
||||
void setItemTextAppearance(int resId) {
|
||||
mAdapter.setItemTextAppearance(resId);
|
||||
}
|
||||
|
||||
private class YearAdapter extends ArrayAdapter<Integer> {
|
||||
int mItemTextAppearanceResId;
|
||||
|
||||
public YearAdapter(Context context, int resource) {
|
||||
super(context, resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextViewWithCircularIndicator v = (TextViewWithCircularIndicator)
|
||||
super.getView(position, convertView, parent);
|
||||
v.setTextAppearance(getContext(), mItemTextAppearanceResId);
|
||||
v.requestLayout();
|
||||
int year = getItem(position);
|
||||
boolean selected = mController.getSelectedDay().get(Calendar.YEAR) == year;
|
||||
v.setDrawIndicator(selected);
|
||||
if (selected) {
|
||||
v.setCircleColor(mYearSelectedCircleColor);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public void setItemTextAppearance(int resId) {
|
||||
mItemTextAppearanceResId = resId;
|
||||
}
|
||||
}
|
||||
|
||||
public void postSetSelectionCentered(final int position) {
|
||||
postSetSelectionFromTop(position, mViewSize / 2 - mChildSize / 2);
|
||||
}
|
||||
|
||||
public void postSetSelectionFromTop(final int position, final int offset) {
|
||||
post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setSelectionFromTop(position, offset);
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getFirstPositionOffset() {
|
||||
final View firstChild = getChildAt(0);
|
||||
if (firstChild == null) {
|
||||
return 0;
|
||||
}
|
||||
return firstChild.getTop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDateChanged() {
|
||||
updateAdapterData();
|
||||
mAdapter.notifyDataSetChanged();
|
||||
postSetSelectionCentered(
|
||||
mController.getSelectedDay().get(Calendar.YEAR) - mController.getMinYear());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
|
||||
event.setFromIndex(0);
|
||||
event.setToIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 com.android.internal.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class AccessibleDateAnimator extends ViewAnimator {
|
||||
private long mDateMillis;
|
||||
|
||||
public AccessibleDateAnimator(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setDateMillis(long dateMillis) {
|
||||
mDateMillis = dateMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announce the currently-selected date when launched.
|
||||
*/
|
||||
@Override
|
||||
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
|
||||
// Clear the event's current text so that only the current date will be spoken.
|
||||
event.getText().clear();
|
||||
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR |
|
||||
DateUtils.FORMAT_SHOW_WEEKDAY;
|
||||
|
||||
String dateString = DateUtils.formatDateTime(getContext(), mDateMillis, flags);
|
||||
event.getText().add(dateString);
|
||||
return true;
|
||||
}
|
||||
return super.dispatchPopulateAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
719
core/java/com/android/internal/widget/ExploreByTouchHelper.java
Normal file
719
core/java/com/android/internal/widget/ExploreByTouchHelper.java
Normal file
@@ -0,0 +1,719 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 com.android.internal.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.view.accessibility.*;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeProvider;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ExploreByTouchHelper is a utility class for implementing accessibility
|
||||
* support in custom {@link android.view.View}s that represent a collection of View-like
|
||||
* logical items. It extends {@link android.view.accessibility.AccessibilityNodeProvider} and
|
||||
* simplifies many aspects of providing information to accessibility services
|
||||
* and managing accessibility focus. This class does not currently support
|
||||
* hierarchies of logical items.
|
||||
* <p>
|
||||
* This should be applied to the parent view using
|
||||
* {@link android.view.View#setAccessibilityDelegate}:
|
||||
*
|
||||
* <pre>
|
||||
* mAccessHelper = ExploreByTouchHelper.create(someView, mAccessHelperCallback);
|
||||
* ViewCompat.setAccessibilityDelegate(someView, mAccessHelper);
|
||||
* </pre>
|
||||
*/
|
||||
public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
|
||||
/** Virtual node identifier value for invalid nodes. */
|
||||
public static final int INVALID_ID = Integer.MIN_VALUE;
|
||||
|
||||
/** Default class name used for virtual views. */
|
||||
private static final String DEFAULT_CLASS_NAME = View.class.getName();
|
||||
|
||||
// Temporary, reusable data structures.
|
||||
private final Rect mTempScreenRect = new Rect();
|
||||
private final Rect mTempParentRect = new Rect();
|
||||
private final Rect mTempVisibleRect = new Rect();
|
||||
private final int[] mTempGlobalRect = new int[2];
|
||||
|
||||
/** View's context **/
|
||||
private Context mContext;
|
||||
|
||||
/** System accessibility manager, used to check state and send events. */
|
||||
private final AccessibilityManager mManager;
|
||||
|
||||
/** View whose internal structure is exposed through this helper. */
|
||||
private final View mView;
|
||||
|
||||
/** Node provider that handles creating nodes and performing actions. */
|
||||
private ExploreByTouchNodeProvider mNodeProvider;
|
||||
|
||||
/** Virtual view id for the currently focused logical item. */
|
||||
private int mFocusedVirtualViewId = INVALID_ID;
|
||||
|
||||
/** Virtual view id for the currently hovered logical item. */
|
||||
private int mHoveredVirtualViewId = INVALID_ID;
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link ExploreByTouchHelper}.
|
||||
*
|
||||
* @param forView View whose logical children are exposed by this helper.
|
||||
*/
|
||||
public ExploreByTouchHelper(View forView) {
|
||||
if (forView == null) {
|
||||
throw new IllegalArgumentException("View may not be null");
|
||||
}
|
||||
|
||||
mView = forView;
|
||||
mContext = forView.getContext();
|
||||
mManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link android.view.accessibility.AccessibilityNodeProvider} for this helper.
|
||||
*
|
||||
* @param host View whose logical children are exposed by this helper.
|
||||
* @return The accessibility node provider for this helper.
|
||||
*/
|
||||
@Override
|
||||
public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
|
||||
if (mNodeProvider == null) {
|
||||
mNodeProvider = new ExploreByTouchNodeProvider();
|
||||
}
|
||||
return mNodeProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches hover {@link android.view.MotionEvent}s to the virtual view hierarchy when
|
||||
* the Explore by Touch feature is enabled.
|
||||
* <p>
|
||||
* This method should be called by overriding
|
||||
* {@link View#dispatchHoverEvent}:
|
||||
*
|
||||
* <pre>@Override
|
||||
* public boolean dispatchHoverEvent(MotionEvent event) {
|
||||
* if (mHelper.dispatchHoverEvent(this, event) {
|
||||
* return true;
|
||||
* }
|
||||
* return super.dispatchHoverEvent(event);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param event The hover event to dispatch to the virtual view hierarchy.
|
||||
* @return Whether the hover event was handled.
|
||||
*/
|
||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
||||
if (!mManager.isEnabled() || !mManager.isTouchExplorationEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
final int virtualViewId = getVirtualViewAt(event.getX(), event.getY());
|
||||
updateHoveredVirtualView(virtualViewId);
|
||||
return (virtualViewId != INVALID_ID);
|
||||
case MotionEvent.ACTION_HOVER_EXIT:
|
||||
if (mFocusedVirtualViewId != INVALID_ID) {
|
||||
updateHoveredVirtualView(INVALID_ID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates an event of the specified type with information about an item
|
||||
* and attempts to send it up through the view hierarchy.
|
||||
* <p>
|
||||
* You should call this method after performing a user action that normally
|
||||
* fires an accessibility event, such as clicking on an item.
|
||||
*
|
||||
* <pre>public void performItemClick(T item) {
|
||||
* ...
|
||||
* sendEventForVirtualViewId(item.id, AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param virtualViewId The virtual view id for which to send an event.
|
||||
* @param eventType The type of event to send.
|
||||
* @return true if the event was sent successfully.
|
||||
*/
|
||||
public boolean sendEventForVirtualView(int virtualViewId, int eventType) {
|
||||
if ((virtualViewId == INVALID_ID) || !mManager.isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ViewParent parent = mView.getParent();
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AccessibilityEvent event = createEvent(virtualViewId, eventType);
|
||||
return parent.requestSendAccessibilityEvent(mView, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the accessibility framework that the properties of the parent
|
||||
* view have changed.
|
||||
* <p>
|
||||
* You <b>must</b> call this method after adding or removing items from the
|
||||
* parent view.
|
||||
*/
|
||||
public void invalidateRoot() {
|
||||
invalidateVirtualView(View.NO_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the accessibility framework that the properties of a particular
|
||||
* item have changed.
|
||||
* <p>
|
||||
* You <b>must</b> call this method after changing any of the properties set
|
||||
* in {@link #onPopulateNodeForVirtualView}.
|
||||
*
|
||||
* @param virtualViewId The virtual view id to invalidate.
|
||||
*/
|
||||
public void invalidateVirtualView(int virtualViewId) {
|
||||
sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the virtual view id for the currently focused item,
|
||||
*
|
||||
* @return A virtual view id, or {@link #INVALID_ID} if no item is
|
||||
* currently focused.
|
||||
*/
|
||||
public int getFocusedVirtualView() {
|
||||
return mFocusedVirtualViewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently hovered item, sending hover accessibility events as
|
||||
* necessary to maintain the correct state.
|
||||
*
|
||||
* @param virtualViewId The virtual view id for the item currently being
|
||||
* hovered, or {@link #INVALID_ID} if no item is hovered within
|
||||
* the parent view.
|
||||
*/
|
||||
private void updateHoveredVirtualView(int virtualViewId) {
|
||||
if (mHoveredVirtualViewId == virtualViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int previousVirtualViewId = mHoveredVirtualViewId;
|
||||
mHoveredVirtualViewId = virtualViewId;
|
||||
|
||||
// Stay consistent with framework behavior by sending ENTER/EXIT pairs
|
||||
// in reverse order. This is accurate as of API 18.
|
||||
sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
|
||||
sendEventForVirtualView(previousVirtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link AccessibilityEvent} for the specified
|
||||
* virtual view id, which includes the host view ({@link View#NO_ID}).
|
||||
*
|
||||
* @param virtualViewId The virtual view id for the item for which to
|
||||
* construct an event.
|
||||
* @param eventType The type of event to construct.
|
||||
* @return An {@link AccessibilityEvent} populated with information about
|
||||
* the specified item.
|
||||
*/
|
||||
private AccessibilityEvent createEvent(int virtualViewId, int eventType) {
|
||||
switch (virtualViewId) {
|
||||
case View.NO_ID:
|
||||
return createEventForHost(eventType);
|
||||
default:
|
||||
return createEventForChild(virtualViewId, eventType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link AccessibilityEvent} for the host node.
|
||||
*
|
||||
* @param eventType The type of event to construct.
|
||||
* @return An {@link AccessibilityEvent} populated with information about
|
||||
* the specified item.
|
||||
*/
|
||||
private AccessibilityEvent createEventForHost(int eventType) {
|
||||
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
||||
onInitializeAccessibilityEvent(mView, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link AccessibilityEvent} populated with
|
||||
* information about the specified item.
|
||||
*
|
||||
* @param virtualViewId The virtual view id for the item for which to
|
||||
* construct an event.
|
||||
* @param eventType The type of event to construct.
|
||||
* @return An {@link AccessibilityEvent} populated with information about
|
||||
* the specified item.
|
||||
*/
|
||||
private AccessibilityEvent createEventForChild(int virtualViewId, int eventType) {
|
||||
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
||||
event.setEnabled(true);
|
||||
event.setClassName(DEFAULT_CLASS_NAME);
|
||||
|
||||
// Allow the client to populate the event.
|
||||
onPopulateEventForVirtualView(virtualViewId, event);
|
||||
|
||||
// Make sure the developer is following the rules.
|
||||
if (event.getText().isEmpty() && (event.getContentDescription() == null)) {
|
||||
throw new RuntimeException("Callbacks must add text or a content description in "
|
||||
+ "populateEventForVirtualViewId()");
|
||||
}
|
||||
|
||||
// Don't allow the client to override these properties.
|
||||
event.setPackageName(mView.getContext().getPackageName());
|
||||
event.setSource(mView, virtualViewId);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link android.view.accessibility.AccessibilityNodeInfo} for the
|
||||
* specified virtual view id, which includes the host view
|
||||
* ({@link View#NO_ID}).
|
||||
*
|
||||
* @param virtualViewId The virtual view id for the item for which to
|
||||
* construct a node.
|
||||
* @return An {@link android.view.accessibility.AccessibilityNodeInfo} populated with information
|
||||
* about the specified item.
|
||||
*/
|
||||
private AccessibilityNodeInfo createNode(int virtualViewId) {
|
||||
switch (virtualViewId) {
|
||||
case View.NO_ID:
|
||||
return createNodeForHost();
|
||||
default:
|
||||
return createNodeForChild(virtualViewId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link AccessibilityNodeInfo} for the
|
||||
* host view populated with its virtual descendants.
|
||||
*
|
||||
* @return An {@link AccessibilityNodeInfo} for the parent node.
|
||||
*/
|
||||
private AccessibilityNodeInfo createNodeForHost() {
|
||||
final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(mView);
|
||||
onInitializeAccessibilityNodeInfo(mView, node);
|
||||
|
||||
// Add the virtual descendants.
|
||||
final LinkedList<Integer> virtualViewIds = new LinkedList<Integer>();
|
||||
getVisibleVirtualViews(virtualViewIds);
|
||||
|
||||
for (Integer childVirtualViewId : virtualViewIds) {
|
||||
node.addChild(mView, childVirtualViewId);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an {@link AccessibilityNodeInfo} for the
|
||||
* specified item. Automatically manages accessibility focus actions.
|
||||
* <p>
|
||||
* Allows the implementing class to specify most node properties, but
|
||||
* overrides the following:
|
||||
* <ul>
|
||||
* <li>{@link AccessibilityNodeInfo#setPackageName}
|
||||
* <li>{@link AccessibilityNodeInfo#setClassName}
|
||||
* <li>{@link AccessibilityNodeInfo#setParent(View)}
|
||||
* <li>{@link AccessibilityNodeInfo#setSource(View, int)}
|
||||
* <li>{@link AccessibilityNodeInfo#setVisibleToUser}
|
||||
* <li>{@link AccessibilityNodeInfo#setBoundsInScreen(Rect)}
|
||||
* </ul>
|
||||
* <p>
|
||||
* Uses the bounds of the parent view and the parent-relative bounding
|
||||
* rectangle specified by
|
||||
* {@link AccessibilityNodeInfo#getBoundsInParent} to automatically
|
||||
* update the following properties:
|
||||
* <ul>
|
||||
* <li>{@link AccessibilityNodeInfo#setVisibleToUser}
|
||||
* <li>{@link AccessibilityNodeInfo#setBoundsInParent}
|
||||
* </ul>
|
||||
*
|
||||
* @param virtualViewId The virtual view id for item for which to construct
|
||||
* a node.
|
||||
* @return An {@link AccessibilityNodeInfo} for the specified item.
|
||||
*/
|
||||
private AccessibilityNodeInfo createNodeForChild(int virtualViewId) {
|
||||
final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain();
|
||||
|
||||
// Ensure the client has good defaults.
|
||||
node.setEnabled(true);
|
||||
node.setClassName(DEFAULT_CLASS_NAME);
|
||||
|
||||
// Allow the client to populate the node.
|
||||
onPopulateNodeForVirtualView(virtualViewId, node);
|
||||
|
||||
// Make sure the developer is following the rules.
|
||||
if ((node.getText() == null) && (node.getContentDescription() == null)) {
|
||||
throw new RuntimeException("Callbacks must add text or a content description in "
|
||||
+ "populateNodeForVirtualViewId()");
|
||||
}
|
||||
|
||||
node.getBoundsInParent(mTempParentRect);
|
||||
if (mTempParentRect.isEmpty()) {
|
||||
throw new RuntimeException("Callbacks must set parent bounds in "
|
||||
+ "populateNodeForVirtualViewId()");
|
||||
}
|
||||
|
||||
final int actions = node.getActions();
|
||||
if ((actions & AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) != 0) {
|
||||
throw new RuntimeException("Callbacks must not add ACTION_ACCESSIBILITY_FOCUS in "
|
||||
+ "populateNodeForVirtualViewId()");
|
||||
}
|
||||
if ((actions & AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS) != 0) {
|
||||
throw new RuntimeException("Callbacks must not add ACTION_CLEAR_ACCESSIBILITY_FOCUS in "
|
||||
+ "populateNodeForVirtualViewId()");
|
||||
}
|
||||
|
||||
// Don't allow the client to override these properties.
|
||||
node.setPackageName(mView.getContext().getPackageName());
|
||||
node.setSource(mView, virtualViewId);
|
||||
node.setParent(mView);
|
||||
|
||||
// Manage internal accessibility focus state.
|
||||
if (mFocusedVirtualViewId == virtualViewId) {
|
||||
node.setAccessibilityFocused(true);
|
||||
node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
|
||||
} else {
|
||||
node.setAccessibilityFocused(false);
|
||||
node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
|
||||
}
|
||||
|
||||
// Set the visibility based on the parent bound.
|
||||
if (intersectVisibleToUser(mTempParentRect)) {
|
||||
node.setVisibleToUser(true);
|
||||
node.setBoundsInParent(mTempParentRect);
|
||||
}
|
||||
|
||||
// Calculate screen-relative bound.
|
||||
mView.getLocationOnScreen(mTempGlobalRect);
|
||||
final int offsetX = mTempGlobalRect[0];
|
||||
final int offsetY = mTempGlobalRect[1];
|
||||
mTempScreenRect.set(mTempParentRect);
|
||||
mTempScreenRect.offset(offsetX, offsetY);
|
||||
node.setBoundsInScreen(mTempScreenRect);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
||||
switch (virtualViewId) {
|
||||
case View.NO_ID:
|
||||
return performActionForHost(action, arguments);
|
||||
default:
|
||||
return performActionForChild(virtualViewId, action, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean performActionForHost(int action, Bundle arguments) {
|
||||
return performAccessibilityAction(mView, action, arguments);
|
||||
}
|
||||
|
||||
private boolean performActionForChild(int virtualViewId, int action, Bundle arguments) {
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
|
||||
return manageFocusForChild(virtualViewId, action, arguments);
|
||||
default:
|
||||
return onPerformActionForVirtualView(virtualViewId, action, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean manageFocusForChild(int virtualViewId, int action, Bundle arguments) {
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
return requestAccessibilityFocus(virtualViewId);
|
||||
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
|
||||
return clearAccessibilityFocus(virtualViewId);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes whether the specified {@link Rect} intersects with the visible
|
||||
* portion of its parent {@link View}. Modifies {@code localRect} to contain
|
||||
* only the visible portion.
|
||||
*
|
||||
* @param localRect A rectangle in local (parent) coordinates.
|
||||
* @return Whether the specified {@link Rect} is visible on the screen.
|
||||
*/
|
||||
private boolean intersectVisibleToUser(Rect localRect) {
|
||||
// Missing or empty bounds mean this view is not visible.
|
||||
if ((localRect == null) || localRect.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attached to invisible window means this view is not visible.
|
||||
if (mView.getWindowVisibility() != View.VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// An invisible predecessor means that this view is not visible.
|
||||
ViewParent viewParent = mView.getParent();
|
||||
while (viewParent instanceof View) {
|
||||
final View view = (View) viewParent;
|
||||
if ((view.getAlpha() <= 0) || (view.getVisibility() != View.VISIBLE)) {
|
||||
return false;
|
||||
}
|
||||
viewParent = view.getParent();
|
||||
}
|
||||
|
||||
// A null parent implies the view is not visible.
|
||||
if (viewParent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no portion of the parent is visible, this view is not visible.
|
||||
if (!mView.getLocalVisibleRect(mTempVisibleRect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the view intersects the visible portion of the parent.
|
||||
return localRect.intersect(mTempVisibleRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this virtual view is accessibility focused.
|
||||
*
|
||||
* @return True if the view is accessibility focused.
|
||||
*/
|
||||
private boolean isAccessibilityFocused(int virtualViewId) {
|
||||
return (mFocusedVirtualViewId == virtualViewId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to give accessibility focus to a virtual view.
|
||||
* <p>
|
||||
* A virtual view will not actually take focus if
|
||||
* {@link AccessibilityManager#isEnabled()} returns false,
|
||||
* {@link AccessibilityManager#isTouchExplorationEnabled()} returns false,
|
||||
* or the view already has accessibility focus.
|
||||
*
|
||||
* @param virtualViewId The id of the virtual view on which to place
|
||||
* accessibility focus.
|
||||
* @return Whether this virtual view actually took accessibility focus.
|
||||
*/
|
||||
private boolean requestAccessibilityFocus(int virtualViewId) {
|
||||
final AccessibilityManager accessibilityManager =
|
||||
(AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
|
||||
if (!mManager.isEnabled()
|
||||
|| !accessibilityManager.isTouchExplorationEnabled()) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Check virtual view visibility.
|
||||
if (!isAccessibilityFocused(virtualViewId)) {
|
||||
mFocusedVirtualViewId = virtualViewId;
|
||||
// TODO: Only invalidate virtual view bounds.
|
||||
mView.invalidate();
|
||||
sendEventForVirtualView(virtualViewId,
|
||||
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to clear accessibility focus from a virtual view.
|
||||
*
|
||||
* @param virtualViewId The id of the virtual view from which to clear
|
||||
* accessibility focus.
|
||||
* @return Whether this virtual view actually cleared accessibility focus.
|
||||
*/
|
||||
private boolean clearAccessibilityFocus(int virtualViewId) {
|
||||
if (isAccessibilityFocused(virtualViewId)) {
|
||||
mFocusedVirtualViewId = INVALID_ID;
|
||||
mView.invalidate();
|
||||
sendEventForVirtualView(virtualViewId,
|
||||
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a mapping between view-relative coordinates and logical
|
||||
* items.
|
||||
*
|
||||
* @param x The view-relative x coordinate
|
||||
* @param y The view-relative y coordinate
|
||||
* @return virtual view identifier for the logical item under
|
||||
* coordinates (x,y)
|
||||
*/
|
||||
protected abstract int getVirtualViewAt(float x, float y);
|
||||
|
||||
/**
|
||||
* Populates a list with the view's visible items. The ordering of items
|
||||
* within {@code virtualViewIds} specifies order of accessibility focus
|
||||
* traversal.
|
||||
*
|
||||
* @param virtualViewIds The list to populate with visible items
|
||||
*/
|
||||
protected abstract void getVisibleVirtualViews(List<Integer> virtualViewIds);
|
||||
|
||||
/**
|
||||
* Populates an {@link AccessibilityEvent} with information about the
|
||||
* specified item.
|
||||
* <p>
|
||||
* Implementations <b>must</b> populate the following required fields:
|
||||
* <ul>
|
||||
* <li>event text, see {@link AccessibilityEvent#getText} or
|
||||
* {@link AccessibilityEvent#setContentDescription}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The helper class automatically populates the following fields with
|
||||
* default values, but implementations may optionally override them:
|
||||
* <ul>
|
||||
* <li>item class name, set to android.view.View, see
|
||||
* {@link AccessibilityEvent#setClassName}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The following required fields are automatically populated by the
|
||||
* helper class and may not be overridden:
|
||||
* <ul>
|
||||
* <li>package name, set to the package of the host view's
|
||||
* {@link Context}, see {@link AccessibilityEvent#setPackageName}
|
||||
* <li>event source, set to the host view and virtual view identifier,
|
||||
* see {@link AccessibilityRecord#setSource(View, int)}
|
||||
* </ul>
|
||||
*
|
||||
* @param virtualViewId The virtual view id for the item for which to
|
||||
* populate the event
|
||||
* @param event The event to populate
|
||||
*/
|
||||
protected abstract void onPopulateEventForVirtualView(
|
||||
int virtualViewId, AccessibilityEvent event);
|
||||
|
||||
/**
|
||||
* Populates an {@link AccessibilityNodeInfo} with information
|
||||
* about the specified item.
|
||||
* <p>
|
||||
* Implementations <b>must</b> populate the following required fields:
|
||||
* <ul>
|
||||
* <li>event text, see {@link AccessibilityNodeInfo#setText} or
|
||||
* {@link AccessibilityNodeInfo#setContentDescription}
|
||||
* <li>bounds in parent coordinates, see
|
||||
* {@link AccessibilityNodeInfo#setBoundsInParent}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The helper class automatically populates the following fields with
|
||||
* default values, but implementations may optionally override them:
|
||||
* <ul>
|
||||
* <li>enabled state, set to true, see
|
||||
* {@link AccessibilityNodeInfo#setEnabled}
|
||||
* <li>item class name, identical to the class name set by
|
||||
* {@link #onPopulateEventForVirtualView}, see
|
||||
* {@link AccessibilityNodeInfo#setClassName}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The following required fields are automatically populated by the
|
||||
* helper class and may not be overridden:
|
||||
* <ul>
|
||||
* <li>package name, identical to the package name set by
|
||||
* {@link #onPopulateEventForVirtualView}, see
|
||||
* {@link AccessibilityNodeInfo#setPackageName}
|
||||
* <li>node source, identical to the event source set in
|
||||
* {@link #onPopulateEventForVirtualView}, see
|
||||
* {@link AccessibilityNodeInfo#setSource(View, int)}
|
||||
* <li>parent view, set to the host view, see
|
||||
* {@link AccessibilityNodeInfo#setParent(View)}
|
||||
* <li>visibility, computed based on parent-relative bounds, see
|
||||
* {@link AccessibilityNodeInfo#setVisibleToUser}
|
||||
* <li>accessibility focus, computed based on internal helper state, see
|
||||
* {@link AccessibilityNodeInfo#setAccessibilityFocused}
|
||||
* <li>bounds in screen coordinates, computed based on host view bounds,
|
||||
* see {@link AccessibilityNodeInfo#setBoundsInScreen}
|
||||
* </ul>
|
||||
* <p>
|
||||
* Additionally, the helper class automatically handles accessibility
|
||||
* focus management by adding the appropriate
|
||||
* {@link AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS} or
|
||||
* {@link AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS}
|
||||
* action. Implementations must <b>never</b> manually add these actions.
|
||||
* <p>
|
||||
* The helper class also automatically modifies parent- and
|
||||
* screen-relative bounds to reflect the portion of the item visible
|
||||
* within its parent.
|
||||
*
|
||||
* @param virtualViewId The virtual view identifier of the item for
|
||||
* which to populate the node
|
||||
* @param node The node to populate
|
||||
*/
|
||||
protected abstract void onPopulateNodeForVirtualView(
|
||||
int virtualViewId, AccessibilityNodeInfo node);
|
||||
|
||||
/**
|
||||
* Performs the specified accessibility action on the item associated
|
||||
* with the virtual view identifier. See
|
||||
* {@link AccessibilityNodeInfo#performAction(int, Bundle)} for
|
||||
* more information.
|
||||
* <p>
|
||||
* Implementations <b>must</b> handle any actions added manually in
|
||||
* {@link #onPopulateNodeForVirtualView}.
|
||||
* <p>
|
||||
* The helper class automatically handles focus management resulting
|
||||
* from {@link AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS}
|
||||
* and
|
||||
* {@link AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS}
|
||||
* actions.
|
||||
*
|
||||
* @param virtualViewId The virtual view identifier of the item on which
|
||||
* to perform the action
|
||||
* @param action The accessibility action to perform
|
||||
* @param arguments (Optional) A bundle with additional arguments, or
|
||||
* null
|
||||
* @return true if the action was performed
|
||||
*/
|
||||
protected abstract boolean onPerformActionForVirtualView(
|
||||
int virtualViewId, int action, Bundle arguments);
|
||||
|
||||
/**
|
||||
* Exposes a virtual view hierarchy to the accessibility framework. Only
|
||||
* used in API 16+.
|
||||
*/
|
||||
private class ExploreByTouchNodeProvider extends AccessibilityNodeProvider {
|
||||
@Override
|
||||
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
|
||||
return ExploreByTouchHelper.this.createNode(virtualViewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
||||
return ExploreByTouchHelper.this.performAction(virtualViewId, action, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
core/res/res/color/date_picker_calendar_holo_dark.xml
Normal file
25
core/res/res/color/date_picker_calendar_holo_dark.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_enabled="true" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_dark"/>
|
||||
<item android:state_enabled="true" android:state_selected="true"
|
||||
android:color="@color/holo_blue_light"/>
|
||||
<item android:state_enabled="false"
|
||||
android:color="@color/datepicker_default_disabled_text_color_holo_dark"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_calendar_holo_light.xml
Normal file
25
core/res/res/color/date_picker_calendar_holo_light.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_enabled="true" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_light"/>
|
||||
<item android:state_enabled="true" android:state_selected="true"
|
||||
android:color="@color/holo_blue_light"/>
|
||||
<item android:state_enabled="false"
|
||||
android:color="@color/datepicker_default_disabled_text_color_holo_light"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_calendar_material_dark.xml
Normal file
25
core/res/res/color/date_picker_calendar_material_dark.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_enabled="true" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_dark"/>
|
||||
<item android:state_enabled="true" android:state_selected="true"
|
||||
android:color="@color/holo_blue_light"/>
|
||||
<item android:state_enabled="false"
|
||||
android:color="@color/datepicker_default_disabled_text_color_material_dark"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_calendar_material_light.xml
Normal file
25
core/res/res/color/date_picker_calendar_material_light.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_enabled="true" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_light"/>
|
||||
<item android:state_enabled="true" android:state_selected="true"
|
||||
android:color="@color/holo_blue_light"/>
|
||||
<item android:state_enabled="false"
|
||||
android:color="@color/datepicker_default_disabled_text_color_material_light"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_selector_holo_dark.xml
Normal file
25
core/res/res/color/date_picker_selector_holo_dark.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_holo_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="true"
|
||||
android:color="@color/datepicker_default_selected_text_color_holo_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_dark"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_selector_holo_light.xml
Normal file
25
core/res/res/color/date_picker_selector_holo_light.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_holo_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="true"
|
||||
android:color="@color/datepicker_default_selected_text_color_holo_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_light"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_selector_material_dark.xml
Normal file
25
core/res/res/color/date_picker_selector_material_dark.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_material_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="true"
|
||||
android:color="@color/datepicker_default_selected_text_color_material_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_dark"/>
|
||||
|
||||
</selector>
|
||||
25
core/res/res/color/date_picker_selector_material_light.xml
Normal file
25
core/res/res/color/date_picker_selector_material_light.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_material_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="true"
|
||||
android:color="@color/datepicker_default_selected_text_color_material_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_light"/>
|
||||
|
||||
</selector>
|
||||
23
core/res/res/color/date_picker_year_selector_holo_dark.xml
Normal file
23
core/res/res/color/date_picker_year_selector_holo_dark.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_holo_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_dark"/>
|
||||
|
||||
</selector>
|
||||
23
core/res/res/color/date_picker_year_selector_holo_light.xml
Normal file
23
core/res/res/color/date_picker_year_selector_holo_light.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_holo_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_holo_light"/>
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_material_dark"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_dark"/>
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:color="@color/datepicker_default_pressed_text_color_material_light"/>
|
||||
<item android:state_pressed="false" android:state_selected="false"
|
||||
android:color="@color/datepicker_default_normal_text_color_material_light"/>
|
||||
|
||||
</selector>
|
||||
46
core/res/res/layout-land/date_picker_holo.xml
Normal file
46
core/res/res/layout-land/date_picker_holo.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2011 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:layout_width="match_parent"
|
||||
android:layout_height="@dimen/datepicker_view_animator_height"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/datePickerHeaderSelectorBackgroundColor"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<include layout="@layout/date_picker_header_view" />
|
||||
|
||||
<include layout="@layout/date_picker_selected_date" />
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/date_picker_done_button" />
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/date_picker_view_animator" />
|
||||
|
||||
</LinearLayout>
|
||||
38
core/res/res/layout-sw600dp/date_picker_holo.xml
Normal file
38
core/res/res/layout-sw600dp/date_picker_holo.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2011 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:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/datepicker_default_view_animator_color_holo_light"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/datepicker_selected_calendar_layout_height"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<include layout="@layout/date_picker_header_view" />
|
||||
|
||||
<include layout="@layout/date_picker_selected_date" />
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/date_picker_view_animator" />
|
||||
|
||||
<include layout="@layout/date_picker_done_button" />
|
||||
|
||||
</LinearLayout>
|
||||
33
core/res/res/layout/date_picker_done_button.xml
Normal file
33
core/res/res/layout/date_picker_done_button.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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/layout_buttons"
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="@dimen/datepicker_component_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:divider="?android:attr/dividerHorizontal"
|
||||
android:showDividers="beginning" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/done"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:text="@string/done_label"
|
||||
android:textSize="@dimen/datepicker_done_label_size" />
|
||||
</LinearLayout>
|
||||
26
core/res/res/layout/date_picker_header_view.xml
Normal file
26
core/res/res/layout/date_picker_header_view.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2013 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/date_picker_header"
|
||||
android:layout_width="@dimen/datepicker_component_width"
|
||||
android:layout_height="@dimen/datepicker_header_height"
|
||||
android:background="?android:attr/datePickerHeaderDayOfWeekLabelBackgroundColor"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/datePickerHeaderDayOfWeekLabelTextAppearance"
|
||||
android:importantForAccessibility="no"
|
||||
android:textAllCaps="true"
|
||||
/>
|
||||
@@ -1,92 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
**
|
||||
** Copyright 2011, 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.
|
||||
*/
|
||||
-->
|
||||
Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
<!-- Layout of date picker-->
|
||||
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
|
||||
|
||||
<!-- Warning: everything within the "pickers" layout is removed and re-ordered
|
||||
depending on the date format selected by the user.
|
||||
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:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
android:layout_width="@dimen/datepicker_component_width"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout android:id="@+id/pickers"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<!-- Month -->
|
||||
<NumberPicker
|
||||
android:id="@+id/month"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="8dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
android:orientation="vertical" >
|
||||
|
||||
<!-- Day -->
|
||||
<NumberPicker
|
||||
android:id="@+id/day"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="8dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
|
||||
<!-- Year -->
|
||||
<NumberPicker
|
||||
android:id="@+id/year"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="16dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
<include layout="@layout/date_picker_header_view" />
|
||||
|
||||
<include layout="@layout/date_picker_selected_date" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- calendar view -->
|
||||
<CalendarView
|
||||
android:id="@+id/calendar_view"
|
||||
android:layout_width="245dip"
|
||||
android:layout_height="280dip"
|
||||
android:layout_marginStart="16dip"
|
||||
android:layout_marginEnd="16dip"
|
||||
android:layout_weight="1"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
<include layout="@layout/date_picker_view_animator" />
|
||||
|
||||
</LinearLayout>
|
||||
<include layout="@layout/date_picker_done_button" />
|
||||
|
||||
</LinearLayout>
|
||||
92
core/res/res/layout/date_picker_legacy_holo.xml
Normal file
92
core/res/res/layout/date_picker_legacy_holo.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
**
|
||||
** Copyright 2011, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- Layout of date picker-->
|
||||
|
||||
<!-- Warning: everything within the "pickers" layout is removed and re-ordered
|
||||
depending on the date format selected by the user.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<LinearLayout android:id="@+id/pickers"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<!-- Month -->
|
||||
<NumberPicker
|
||||
android:id="@+id/month"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="8dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
|
||||
<!-- Day -->
|
||||
<NumberPicker
|
||||
android:id="@+id/day"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="8dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
|
||||
<!-- Year -->
|
||||
<NumberPicker
|
||||
android:id="@+id/year"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:layout_marginStart="8dip"
|
||||
android:layout_marginEnd="16dip"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- calendar view -->
|
||||
<CalendarView
|
||||
android:id="@+id/calendar_view"
|
||||
android:layout_width="245dip"
|
||||
android:layout_height="280dip"
|
||||
android:layout_marginStart="16dip"
|
||||
android:layout_marginEnd="16dip"
|
||||
android:layout_weight="1"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
65
core/res/res/layout/date_picker_selected_date.xml
Normal file
65
core/res/res/layout/date_picker_selected_date.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/day_picker_selector_layout"
|
||||
android:layout_width="@dimen/datepicker_component_width"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="8dip"
|
||||
android:paddingBottom="8dip"
|
||||
android:background="?android:attr/datePickerHeaderSelectorBackgroundColor"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/date_picker_month_and_day_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date_picker_month"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:duplicateParentState="true"
|
||||
android:gravity="center_horizontal|bottom"
|
||||
android:textAppearance="?android:attr/datePickerHeaderSelectorMonthLabelTextAppearance" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date_picker_day"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="-10dip"
|
||||
android:layout_marginTop="-10dip"
|
||||
android:duplicateParentState="true"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/datePickerHeaderSelectorDayOfMonthLabelTextAppearance" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date_picker_year"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center_horizontal|top"
|
||||
android:textAppearance="?android:attr/datePickerHeaderSelectorYearLabelTextAppearance" />
|
||||
|
||||
</LinearLayout>
|
||||
21
core/res/res/layout/date_picker_view_animator.xml
Normal file
21
core/res/res/layout/date_picker_view_animator.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.internal.widget.AccessibleDateAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/animator"
|
||||
android:layout_width="@dimen/datepicker_component_width"
|
||||
android:layout_height="@dimen/datepicker_view_animator_height"
|
||||
android:gravity="center" />
|
||||
23
core/res/res/layout/year_label_text_view.xml
Normal file
23
core/res/res/layout/year_label_text_view.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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.
|
||||
-->
|
||||
<android.widget.TextViewWithCircularIndicator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/month_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/datepicker_year_label_height"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/datePickerHeaderListYearLabelTextAppearance" />
|
||||
@@ -691,6 +691,33 @@
|
||||
<!-- The DatePicker style. -->
|
||||
<attr name="datePickerStyle" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header day of week label background color . -->
|
||||
<attr name="datePickerHeaderDayOfWeekLabelBackgroundColor" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header day of week label text appearance -->
|
||||
<attr name="datePickerHeaderDayOfWeekLabelTextAppearance" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header selector background color . -->
|
||||
<attr name="datePickerHeaderSelectorBackgroundColor" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header selector month label text appearance -->
|
||||
<attr name="datePickerHeaderSelectorMonthLabelTextAppearance" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header selector day of month label text appearance -->
|
||||
<attr name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header selector year label text appearance -->
|
||||
<attr name="datePickerHeaderSelectorYearLabelTextAppearance" format="reference" />
|
||||
|
||||
<!-- The DatePicker Header list year label text appearance -->
|
||||
<attr name="datePickerHeaderListYearLabelTextAppearance" format="reference" />
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<attr name="datePickerHeaderListYearLabelCircleBackgroundColor" format="reference" />
|
||||
|
||||
<!-- The DatePicker dialog theme. -->
|
||||
<attr name="datePickerDialogTheme" format="reference" />
|
||||
|
||||
<!-- Default ActivityChooserView style. -->
|
||||
<attr name="activityChooserViewStyle" format="reference" />
|
||||
|
||||
@@ -4183,6 +4210,28 @@
|
||||
<attr name="maxDate" format="string" />
|
||||
<!-- @hide The layout of the date picker. -->
|
||||
<attr name="internalLayout" format="reference" />
|
||||
<!-- @hide The layout of the legacy DatePicker. -->
|
||||
<attr name="legacyLayout" />
|
||||
<!-- @hide Enables or disable the use of the legacy layout for the DatePicker. -->
|
||||
<attr name="legacyMode" />
|
||||
<!-- The background color for the date selector 's day of week of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorDayOfWeekBackgroundColor" format="color|reference" />
|
||||
<!-- The text color for the date selector's day of week of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorDayOfWeekTextAppearance" format="reference" />
|
||||
<!-- The background color for the date selector of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorBackgroundColor" format="color|reference" />
|
||||
<!-- The month's text appearance in the date selector of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorMonthTextAppearance" format="reference" />
|
||||
<!-- The day of month's text appearance in the date selector of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorDayOfMonthTextAppearance" format="reference" />
|
||||
<!-- The year's text appearance in the date selector of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorYearTextAppearance" format="reference" />
|
||||
<!-- The list year's text appearance in the list of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorYearListItemTextAppearance" format="reference" />
|
||||
<!-- The list year's selected circle color in the list of the non legacy DatePicker. -->
|
||||
<attr name="dateSelectorYearListSelectedCircleColor" format="color|reference" />
|
||||
<!-- The text color list of the calendar of the non legacy DatePicker. -->
|
||||
<attr name="calendarTextColor" format="color|reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="TwoLineListItem">
|
||||
|
||||
@@ -120,4 +120,32 @@
|
||||
|
||||
<color name="timepicker_default_ampm_unselected_background_color_holo_light">@color/white</color>
|
||||
<color name="timepicker_default_ampm_unselected_background_color_holo_dark">@color/transparent</color>
|
||||
|
||||
<!-- DatePicker colors -->
|
||||
<eat-comment />
|
||||
|
||||
<color name="datepicker_default_header_selector_background_holo_light">@android:color/white</color>
|
||||
<color name="datepicker_default_header_selector_background_holo_dark">#ff303030</color>
|
||||
|
||||
<color name="datepicker_default_header_dayofweek_background_color_holo_light">#999999</color>
|
||||
<color name="datepicker_default_header_dayofweek_background_color_holo_dark">@android:color/white</color>
|
||||
|
||||
<color name="datepicker_default_normal_text_color_holo_light">#ff999999</color>
|
||||
<color name="datepicker_default_normal_text_color_holo_dark">@android:color/white</color>
|
||||
|
||||
<color name="datepicker_default_disabled_text_color_holo_light">#80999999</color>
|
||||
<color name="datepicker_default_disabled_text_color_holo_dark">#80999999</color>
|
||||
|
||||
<color name="datepicker_default_selected_text_color_holo_light">#33b5e5</color>
|
||||
<color name="datepicker_default_selected_text_color_holo_dark">#33b5e5</color>
|
||||
|
||||
<color name="datepicker_default_pressed_text_color_holo_light">#0099cc</color>
|
||||
<color name="datepicker_default_pressed_text_color_holo_dark">#0099cc</color>
|
||||
|
||||
<color name="datepicker_default_circle_background_color_holo_light">@android:color/holo_blue_light</color>
|
||||
<color name="datepicker_default_circle_background_color_holo_dark">@android:color/holo_blue_light</color>
|
||||
|
||||
<color name="datepicker_default_view_animator_color_holo_light">#f2f2f2</color>
|
||||
<color name="datepicker_default_view_animator_color_holo_dark">#ff303030</color>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -166,4 +166,32 @@
|
||||
<color name="timepicker_default_ampm_unselected_background_color_material">@color/transparent</color>
|
||||
<color name="timepicker_default_selector_color_material">@color/material_light_blue_A200</color>
|
||||
<color name="timepicker_default_numbers_background_color_material">@color/transparent</color>
|
||||
|
||||
<!-- DatePicker colors -->
|
||||
<eat-comment />
|
||||
|
||||
<color name="datepicker_default_header_selector_background_material_light">@android:color/white</color>
|
||||
<color name="datepicker_default_header_selector_background_material_dark">#ff303030</color>
|
||||
|
||||
<color name="datepicker_default_header_dayofweek_background_color_material_light">#999999</color>
|
||||
<color name="datepicker_default_header_dayofweek_background_color_material_dark">@android:color/white</color>
|
||||
|
||||
<color name="datepicker_default_normal_text_color_material_light">#ff999999</color>
|
||||
<color name="datepicker_default_normal_text_color_material_dark">@android:color/white</color>
|
||||
|
||||
<color name="datepicker_default_disabled_text_color_material_light">#80999999</color>
|
||||
<color name="datepicker_default_disabled_text_color_material_dark">#80999999</color>
|
||||
|
||||
<color name="datepicker_default_selected_text_color_material_light">#33b5e5</color>
|
||||
<color name="datepicker_default_selected_text_color_material_dark">#33b5e5</color>
|
||||
|
||||
<color name="datepicker_default_pressed_text_color_material_light">#0099cc</color>
|
||||
<color name="datepicker_default_pressed_text_color_material_dark">#0099cc</color>
|
||||
|
||||
<color name="datepicker_default_circle_background_color_material_light">@android:color/holo_blue_light</color>
|
||||
<color name="datepicker_default_circle_background_color_material_dark">@android:color/holo_blue_light</color>
|
||||
|
||||
<color name="datepicker_default_view_animator_color_material_light">#f2f2f2</color>
|
||||
<color name="datepicker_default_view_animator_color_material_dark">#ff303030</color>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -564,6 +564,12 @@
|
||||
<item>5</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Vibrator pattern for feedback when selecting a day/month/year date of a Calendar -->
|
||||
<integer-array name="config_calendarDateVibePattern">
|
||||
<item>125</item>
|
||||
<item>5</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Vibrator pattern for feedback about booting with safe mode disabled -->
|
||||
<integer-array name="config_safeModeDisabledVibePattern">
|
||||
<item>0</item>
|
||||
|
||||
@@ -362,6 +362,24 @@
|
||||
<dimen name="timepicker_minimum_margin_top_bottom">24dip</dimen>
|
||||
<dimen name="timepicker_radial_picker_dimen">270dip</dimen>
|
||||
|
||||
<dimen name="datepicker_done_label_size">14sp</dimen>
|
||||
<dimen name="datepicker_day_number_size">16sp</dimen>
|
||||
<dimen name="datepicker_month_label_size">16sp</dimen>
|
||||
<dimen name="datepicker_month_day_label_text_size">10sp</dimen>
|
||||
<dimen name="datepicker_day_number_select_circle_radius">16dp</dimen>
|
||||
<dimen name="datepicker_month_list_item_header_height">50dp</dimen>
|
||||
<dimen name="datepicker_view_animator_height">270dp</dimen>
|
||||
<dimen name="datepicker_year_picker_padding_top">8dp</dimen>
|
||||
<dimen name="datepicker_year_label_height">64dp</dimen>
|
||||
<dimen name="datepicker_year_label_text_size">22dp</dimen>
|
||||
<dimen name="datepicker_component_width">270dp</dimen>
|
||||
<dimen name="datepicker_selected_calendar_layout_height">155dp</dimen>
|
||||
<dimen name="datepicker_selected_date_day_size">75dp</dimen>
|
||||
<dimen name="datepicker_selected_date_month_size">30dp</dimen>
|
||||
<dimen name="datepicker_selected_date_year_size">30dp</dimen>
|
||||
<dimen name="datepicker_header_height">30dp</dimen>
|
||||
<dimen name="datepicker_header_text_size">14dp</dimen>
|
||||
|
||||
<!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
|
||||
<dimen name="immersive_mode_cling_width">-1px</dimen>
|
||||
|
||||
|
||||
@@ -2239,6 +2239,16 @@
|
||||
<public type="attr" name="launchTaskBehindBackgroundAnimation" />
|
||||
<public type="attr" name="launchTaskBehindSourceAnimation" />
|
||||
|
||||
<public type="attr" name="dateSelectorDayOfWeekBackgroundColor" />
|
||||
<public type="attr" name="dateSelectorDayOfWeekTextAppearance" />
|
||||
<public type="attr" name="dateSelectorBackgroundColor" />
|
||||
<public type="attr" name="dateSelectorMonthTextAppearance" />
|
||||
<public type="attr" name="dateSelectorDayOfMonthTextAppearance" />
|
||||
<public type="attr" name="dateSelectorYearTextAppearance" />
|
||||
<public type="attr" name="dateSelectorYearListItemTextAppearance" />
|
||||
<public type="attr" name="dateSelectorYearListSelectedCircleColor" />
|
||||
<public type="attr" name="calendarTextColor" />
|
||||
|
||||
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
|
||||
|
||||
<public-padding type="id" name="l_resource_pad" end="0x01020040" />
|
||||
|
||||
@@ -572,7 +572,7 @@ please see styles_device_defaults.xml.
|
||||
</style>
|
||||
|
||||
<style name="Widget.DatePicker">
|
||||
<item name="internalLayout">@layout/date_picker</item>
|
||||
<item name="legacyLayout">@android:layout/date_picker_legacy</item>
|
||||
<item name="calendarViewShown">false</item>
|
||||
</style>
|
||||
|
||||
@@ -1338,11 +1338,6 @@ please see styles_device_defaults.xml.
|
||||
<style name="TextAppearance.TimePicker.AmPmLabel" parent="TextAppearance">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.TimePicker.TimeLabel" parent="TextAppearance.Holo">
|
||||
<item name="textSize">@dimen/timepicker_time_label_size</item>
|
||||
<item name="textColor">@color/timepicker_default_text_color_holo_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.FastScroll">
|
||||
<item name="thumbDrawable">?attr/fastScrollThumbDrawable</item>
|
||||
<item name="trackDrawable">?attr/fastScrollTrackDrawable</item>
|
||||
@@ -1366,4 +1361,22 @@ please see styles_device_defaults.xml.
|
||||
<item name="spotShadowAlpha">0.1765</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.DayOfWeekLabel" parent="TextAppearance">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.Selector" parent="TextAppearance">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.Selector.MonthLabel" parent="TextAppearance.DatePicker.Selector">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.DatePicker.Selector">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.Selector.YearLabel" parent="TextAppearance.DatePicker.Selector">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DatePicker.List.YearLabel" parent="TextAppearance">
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -280,4 +280,29 @@ easier.
|
||||
<style name="DeviceDefault.Light.ButtonBar" parent="Widget.Material.Light.ButtonBar"/>
|
||||
<style name="DeviceDefault.Light.ButtonBar.AlertDialog" parent="Widget.Material.Light.ButtonBar.AlertDialog"/>
|
||||
<style name="DeviceDefault.Light.SegmentedButton" parent="Widget.Material.Light.SegmentedButton"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.Light.TimePicker.TimeLabel" parent="TextAppearance.Material.TimePicker.TimeLabel"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.TimePicker.AmPmLabel" parent="TextAppearance.Material.TimePicker.AmPmLabel"/>
|
||||
|
||||
<style name="Theme.DeviceDefault.Dialog.TimePicker" parent="Theme.Material.Dialog.TimePicker"/>
|
||||
<style name="Theme.DeviceDefault.Light.Dialog.TimePicker" parent="Theme.Material.Light.Dialog.TimePicker"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material.DatePicker.DayOfWeekLabel"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material.Light.DatePicker.DayOfWeekLabel"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.DatePicker.Selector" parent="TextAppearance.Material.DatePicker.Selector"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.DatePicker.Selector" parent="TextAppearance.Material.Light.DatePicker.Selector"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.DatePicker.Selector.MonthLabel" parent="TextAppearance.Material.DatePicker.Selector.MonthLabel"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.DatePicker.Selector.MonthLabel" parent="TextAppearance.Material.Light.DatePicker.Selector.MonthLabel"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Material.DatePicker.Selector.DayOfMonthLabel"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Material.Light.DatePicker.Selector.DayOfMonthLabel"/>
|
||||
|
||||
<style name="TextAppearance.DeviceDefault.DatePicker.Selector.YearLabel" parent="TextAppearance.Material.DatePicker.Selector.YearLabel"/>
|
||||
<style name="TextAppearance.DeviceDefault.Light.DatePicker.Selector.YearLabel" parent="TextAppearance.Material.Light.DatePicker.Selector.YearLabel"/>
|
||||
|
||||
<style name="Theme.DeviceDefault.Dialog.DatePicker" parent="Theme.Material.Dialog.DatePicker"/>
|
||||
<style name="Theme.DeviceDefault.Light.Dialog.DatePicker" parent="Theme.Material.Light.Dialog.DatePicker"/>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -477,8 +477,18 @@ please see styles_device_defaults.xml.
|
||||
</style>
|
||||
|
||||
<style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
|
||||
<item name="legacyLayout">@layout/date_picker_legacy_holo</item>
|
||||
<item name="internalLayout">@layout/date_picker_holo</item>
|
||||
<item name="calendarViewShown">true</item>
|
||||
<item name="dateSelectorDayOfWeekBackgroundColor">?attr/datePickerHeaderDayOfWeekLabelBackgroundColor</item>
|
||||
<item name="dateSelectorDayOfWeekTextAppearance">?attr/datePickerHeaderDayOfWeekLabelTextAppearance</item>
|
||||
<item name="dateSelectorBackgroundColor">?attr/datePickerHeaderSelectorBackgroundColor</item>
|
||||
<item name="dateSelectorMonthTextAppearance">?attr/datePickerHeaderSelectorMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorDayOfMonthTextAppearance">?attr/datePickerHeaderSelectorDayOfMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearTextAppearance">?attr/datePickerHeaderSelectorYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListItemTextAppearance">?attr/datePickerHeaderListYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListSelectedCircleColor">?attr/datePickerHeaderListYearLabelCircleBackgroundColor</item>
|
||||
<item name="calendarTextColor">@color/date_picker_calendar_holo_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Holo.ActivityChooserView" parent="Widget.ActivityChooserView" />
|
||||
@@ -884,7 +894,20 @@ please see styles_device_defaults.xml.
|
||||
<item name="numbersSelectorColor">@color/holo_blue_light</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker" />
|
||||
<style name="Widget.Holo.Light.DatePicker" parent="Widget.DatePicker">
|
||||
<item name="legacyLayout">@layout/date_picker_legacy_holo</item>
|
||||
<item name="internalLayout">@layout/date_picker_holo</item>
|
||||
<item name="calendarViewShown">true</item>
|
||||
<item name="dateSelectorDayOfWeekBackgroundColor">?attr/datePickerHeaderDayOfWeekLabelBackgroundColor</item>
|
||||
<item name="dateSelectorDayOfWeekTextAppearance">?attr/datePickerHeaderDayOfWeekLabelTextAppearance</item>
|
||||
<item name="dateSelectorBackgroundColor">?attr/datePickerHeaderSelectorBackgroundColor</item>
|
||||
<item name="dateSelectorMonthTextAppearance">?attr/datePickerHeaderSelectorMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorDayOfMonthTextAppearance">?attr/datePickerHeaderSelectorDayOfMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearTextAppearance">?attr/datePickerHeaderSelectorYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListItemTextAppearance">?attr/datePickerHeaderListYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListSelectedCircleColor">?attr/datePickerHeaderListYearLabelCircleBackgroundColor</item>
|
||||
<item name="calendarTextColor">@color/date_picker_calendar_holo_light</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Holo.Light.ActivityChooserView" parent="Widget.Holo.ActivityChooserView">
|
||||
<item name="background">@drawable/ab_share_pack_holo_light</item>
|
||||
@@ -1183,6 +1206,11 @@ please see styles_device_defaults.xml.
|
||||
<item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.TimePicker.TimeLabel" parent="TextAppearance.Holo">
|
||||
<item name="textSize">@dimen/timepicker_time_label_size</item>
|
||||
<item name="textColor">@color/timepicker_default_text_color_holo_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.TimePicker.AmPmLabel" parent="TextAppearance.Holo">
|
||||
<item name="textSize">@dimen/timepicker_ampm_label_size</item>
|
||||
<item name="textAllCaps">true</item>
|
||||
@@ -1202,6 +1230,62 @@ please see styles_device_defaults.xml.
|
||||
<item name="textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.DayOfWeekLabel" parent="TextAppearance.Holo">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/black</item>
|
||||
<item name="textSize">@dimen/datepicker_header_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.Selector" parent="TextAppearance.Holo">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/date_picker_selector_holo_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.Selector.MonthLabel" parent="TextAppearance.Holo.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_month_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Holo.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_day_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.Selector.YearLabel" parent="TextAppearance.Holo.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_year_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.DatePicker.List.YearLabel" parent="TextAppearance.Holo">
|
||||
<item name="textColor">@color/date_picker_year_selector_holo_dark</item>
|
||||
<item name="textSize">@dimen/datepicker_year_label_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.DayOfWeekLabel" parent="TextAppearance.Holo">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/white</item>
|
||||
<item name="textSize">@dimen/datepicker_header_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.Selector" parent="TextAppearance.Holo">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/date_picker_selector_holo_light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.Selector.MonthLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_month_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_day_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.Selector.YearLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_year_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Holo.Light.DatePicker.List.YearLabel" parent="TextAppearance.Holo">
|
||||
<item name="textColor">@color/date_picker_year_selector_holo_light</item>
|
||||
<item name="textSize">@dimen/datepicker_year_label_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Holo.FastScroll" parent="Widget.FastScroll">
|
||||
<item name="thumbMinWidth">0dp</item>
|
||||
<item name="thumbMinHeight">0dp</item>
|
||||
|
||||
@@ -353,6 +353,62 @@ please see styles_device_defaults.xml.
|
||||
<item name="textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/black</item>
|
||||
<item name="textSize">@dimen/datepicker_header_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.Selector" parent="TextAppearance.Material">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/date_picker_selector_material_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.Selector.MonthLabel" parent="TextAppearance.Material.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_month_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Material.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_day_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.Selector.YearLabel" parent="TextAppearance.Material.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_year_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.DatePicker.List.YearLabel" parent="TextAppearance.Material">
|
||||
<item name="textColor">@color/date_picker_year_selector_material_dark</item>
|
||||
<item name="textSize">@dimen/datepicker_year_label_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/white</item>
|
||||
<item name="textSize">@dimen/datepicker_header_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.Selector" parent="TextAppearance.Material">
|
||||
<item name="includeFontPadding">false</item>
|
||||
<item name="textColor">@color/date_picker_selector_material_light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.Selector.MonthLabel" parent="TextAppearance.Material.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_month_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Material.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_day_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.Selector.YearLabel" parent="TextAppearance.Material.Light.DatePicker.Selector">
|
||||
<item name="textSize">@dimen/datepicker_selected_date_year_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Material.Light.DatePicker.List.YearLabel" parent="TextAppearance.Material">
|
||||
<item name="textColor">@color/date_picker_year_selector_material_light</item>
|
||||
<item name="textSize">@dimen/datepicker_year_label_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.StatusBar.Material" />
|
||||
|
||||
<style name="TextAppearance.StatusBar.Material.EventContent">
|
||||
@@ -575,8 +631,18 @@ please see styles_device_defaults.xml.
|
||||
</style>
|
||||
|
||||
<style name="Widget.Material.DatePicker" parent="Widget.DatePicker">
|
||||
<item name="legacyLayout">@layout/date_picker_legacy_holo</item>
|
||||
<item name="internalLayout">@layout/date_picker_holo</item>
|
||||
<item name="calendarViewShown">true</item>
|
||||
<item name="dateSelectorDayOfWeekBackgroundColor">?attr/datePickerHeaderDayOfWeekLabelBackgroundColor</item>
|
||||
<item name="dateSelectorDayOfWeekTextAppearance">?attr/datePickerHeaderDayOfWeekLabelTextAppearance</item>
|
||||
<item name="dateSelectorBackgroundColor">?attr/datePickerHeaderSelectorBackgroundColor</item>
|
||||
<item name="dateSelectorMonthTextAppearance">?attr/datePickerHeaderSelectorMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorDayOfMonthTextAppearance">?attr/datePickerHeaderSelectorDayOfMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearTextAppearance">?attr/datePickerHeaderSelectorYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListItemTextAppearance">?attr/datePickerHeaderListYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListSelectedCircleColor">?attr/datePickerHeaderListYearLabelCircleBackgroundColor</item>
|
||||
<item name="calendarTextColor">@color/date_picker_calendar_holo_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Material.ActivityChooserView" parent="Widget.ActivityChooserView">
|
||||
@@ -897,7 +963,21 @@ please see styles_device_defaults.xml.
|
||||
<item name="disabledColor">@color/bright_foreground_disabled_material_light</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Material.Light.DatePicker" parent="Widget.Material.DatePicker"/>
|
||||
<style name="Widget.Material.Light.DatePicker" parent="Widget.DatePicker">
|
||||
<item name="legacyLayout">@layout/date_picker_legacy_holo</item>
|
||||
<item name="internalLayout">@layout/date_picker_holo</item>
|
||||
<item name="calendarViewShown">true</item>
|
||||
<item name="dateSelectorDayOfWeekBackgroundColor">?attr/datePickerHeaderDayOfWeekLabelBackgroundColor</item>
|
||||
<item name="dateSelectorDayOfWeekTextAppearance">?attr/datePickerHeaderDayOfWeekLabelTextAppearance</item>
|
||||
<item name="dateSelectorBackgroundColor">?attr/datePickerHeaderSelectorBackgroundColor</item>
|
||||
<item name="dateSelectorMonthTextAppearance">?attr/datePickerHeaderSelectorMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorDayOfMonthTextAppearance">?attr/datePickerHeaderSelectorDayOfMonthLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearTextAppearance">?attr/datePickerHeaderSelectorYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListItemTextAppearance">?attr/datePickerHeaderListYearLabelTextAppearance</item>
|
||||
<item name="dateSelectorYearListSelectedCircleColor">?attr/datePickerHeaderListYearLabelCircleBackgroundColor</item>
|
||||
<item name="calendarTextColor">@color/date_picker_calendar_holo_light</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Material.Light.ActivityChooserView" parent="Widget.Material.ActivityChooserView" />
|
||||
<style name="Widget.Material.Light.ImageWell" parent="Widget.Material.ImageWell"/>
|
||||
<style name="Widget.Material.Light.ListView" parent="Widget.Material.ListView"/>
|
||||
|
||||
@@ -1182,7 +1182,7 @@
|
||||
<java-symbol type="layout" name="calendar_view" />
|
||||
<java-symbol type="layout" name="character_picker" />
|
||||
<java-symbol type="layout" name="character_picker_button" />
|
||||
<java-symbol type="layout" name="date_picker" />
|
||||
<java-symbol type="layout" name="date_picker_legacy" />
|
||||
<java-symbol type="layout" name="date_picker_dialog" />
|
||||
<java-symbol type="layout" name="expanded_menu_layout" />
|
||||
<java-symbol type="layout" name="fragment_bread_crumb_item" />
|
||||
@@ -1840,9 +1840,10 @@
|
||||
<java-symbol type="dimen" name="subtitle_shadow_offset" />
|
||||
<java-symbol type="dimen" name="subtitle_outline_width" />
|
||||
|
||||
<!-- From the new TimePicker -->
|
||||
<java-symbol type="attr" name="timePickerHeaderBackgroundColor" />
|
||||
<!-- From the new TimePicker and DatePicker -->
|
||||
<java-symbol type="attr" name="timePickerDialogTheme" />
|
||||
<java-symbol type="attr" name="timePickerHeaderTimeLabelTextAppearance" />
|
||||
<java-symbol type="attr" name="timePickerHeaderBackgroundColor" />
|
||||
<java-symbol type="attr" name="headerSelectedTextColor" />
|
||||
<java-symbol type="attr" name="headerUnselectedTextColor" />
|
||||
<java-symbol type="attr" name="numbersTextColor" />
|
||||
@@ -1853,9 +1854,18 @@
|
||||
<java-symbol type="attr" name="numbersSelectorColor" />
|
||||
<java-symbol type="attr" name="timePickerHeaderTimeLabelTextAppearance" />
|
||||
<java-symbol type="attr" name="nestedScrollingEnabled" />
|
||||
<java-symbol type="attr" name="datePickerDialogTheme" />
|
||||
<java-symbol type="attr" name="datePickerHeaderSelectorBackgroundColor" />
|
||||
<java-symbol type="attr" name="datePickerHeaderListYearLabelCircleBackgroundColor" />
|
||||
<java-symbol type="attr" name="calendarTextColor" />
|
||||
|
||||
<java-symbol type="style" name="TextAppearance.Holo.TimePicker.TimeLabel" />
|
||||
|
||||
<java-symbol type="layout" name="time_picker_holo" />
|
||||
<java-symbol type="layout" name="time_header_label" />
|
||||
<java-symbol type="layout" name="year_label_text_view" />
|
||||
<java-symbol type="layout" name="date_picker_holo" />
|
||||
|
||||
<java-symbol type="id" name="time_header" />
|
||||
<java-symbol type="id" name="hours" />
|
||||
<java-symbol type="id" name="minutes" />
|
||||
@@ -1864,6 +1874,15 @@
|
||||
<java-symbol type="id" name="separator" />
|
||||
<java-symbol type="id" name="layout_buttons" />
|
||||
<java-symbol type="id" name="done_button" />
|
||||
<java-symbol type="id" name="date_picker_header" />
|
||||
<java-symbol type="id" name="date_picker_month_and_day_layout" />
|
||||
<java-symbol type="id" name="day_picker_selector_layout" />
|
||||
<java-symbol type="id" name="date_picker_month" />
|
||||
<java-symbol type="id" name="date_picker_day" />
|
||||
<java-symbol type="id" name="date_picker_year" />
|
||||
<java-symbol type="id" name="animator" />
|
||||
<java-symbol type="id" name="done" />
|
||||
|
||||
<java-symbol type="string" name="done_label" />
|
||||
<java-symbol type="string" name="hour_picker_description" />
|
||||
<java-symbol type="string" name="minute_picker_description" />
|
||||
@@ -1885,7 +1904,42 @@
|
||||
<java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
|
||||
<java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
|
||||
<java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
|
||||
|
||||
<java-symbol type="string" name="item_is_selected" />
|
||||
<java-symbol type="string" name="day_of_week_label_typeface" />
|
||||
<java-symbol type="string" name="select_day" />
|
||||
<java-symbol type="string" name="day_picker_description" />
|
||||
<java-symbol type="string" name="select_year" />
|
||||
<java-symbol type="string" name="year_picker_description" />
|
||||
|
||||
<java-symbol type="dimen" name="datepicker_day_number_size" />
|
||||
<java-symbol type="dimen" name="datepicker_month_label_size" />
|
||||
<java-symbol type="dimen" name="datepicker_month_day_label_text_size" />
|
||||
<java-symbol type="dimen" name="datepicker_month_list_item_header_height" />
|
||||
<java-symbol type="dimen" name="datepicker_day_number_select_circle_radius" />
|
||||
<java-symbol type="dimen" name="datepicker_view_animator_height" />
|
||||
<java-symbol type="dimen" name="datepicker_year_label_height" />
|
||||
<java-symbol type="dimen" name="datepicker_year_picker_padding_top" />
|
||||
|
||||
<java-symbol type="color" name="timepicker_default_text_color_holo_light" />
|
||||
<java-symbol type="color" name="timepicker_default_disabled_color_holo_light" />
|
||||
<java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_holo_light" />
|
||||
<java-symbol type="color" name="timepicker_default_ampm_selected_background_color_holo_light" />
|
||||
|
||||
<java-symbol type="color" name="datepicker_default_normal_text_color_holo_light" />
|
||||
<java-symbol type="color" name="datepicker_default_disabled_text_color_holo_light" />
|
||||
<java-symbol type="color" name="datepicker_default_circle_background_color_holo_light" />
|
||||
<java-symbol type="color" name="datepicker_default_header_dayofweek_background_color_holo_light" />
|
||||
<java-symbol type="color" name="datepicker_default_header_selector_background_holo_light" />
|
||||
|
||||
<java-symbol type="color" name="datepicker_default_normal_text_color_material_light" />
|
||||
<java-symbol type="color" name="datepicker_default_disabled_text_color_material_light" />
|
||||
<java-symbol type="color" name="datepicker_default_circle_background_color_material_light" />
|
||||
<java-symbol type="color" name="datepicker_default_header_dayofweek_background_color_material_light" />
|
||||
<java-symbol type="color" name="datepicker_default_header_selector_background_material_light" />
|
||||
|
||||
<java-symbol type="array" name="config_clockTickVibePattern" />
|
||||
<java-symbol type="array" name="config_calendarDateVibePattern" />
|
||||
|
||||
<!-- From various Material changes -->
|
||||
<java-symbol type="attr" name="toolbarStyle" />
|
||||
|
||||
@@ -409,7 +409,34 @@ please see themes_device_defaults.xml.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.DatePicker</item>
|
||||
|
||||
<item name="fastScrollThumbDrawable">@drawable/scrollbar_handle_accelerated_anim2</item>
|
||||
<!-- DatePicker Header day of week label background color -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelBackgroundColor">@android:color/darker_gray</item>
|
||||
|
||||
<!-- DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector background color -->
|
||||
<item name="datePickerHeaderSelectorBackgroundColor">@android:color/darker_gray</item>
|
||||
|
||||
<!-- DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label text appearance -->
|
||||
<item name="datePickerHeaderListYearLabelTextAppearance">@style/TextAppearance.DatePicker.List.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<item name="datePickerHeaderListYearLabelCircleBackgroundColor">@android:color/darker_gray</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.Dialog.DatePicker</item>
|
||||
|
||||
<item name="fastScrollThumbDrawable">@android:drawable/scrollbar_handle_accelerated_anim2</item>
|
||||
<item name="fastScrollTrackDrawable">@null</item>
|
||||
<item name="fastScrollPreviewBackgroundRight">@drawable/menu_submenu_background</item>
|
||||
<item name="fastScrollPreviewBackgroundLeft">@drawable/menu_submenu_background</item>
|
||||
@@ -731,6 +758,14 @@ please see themes_device_defaults.xml.
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Default heme for the DatePicker dialog windows, which is used by the
|
||||
{@link android.app.DatePickerDialog} class. -->
|
||||
<style name="Theme.Dialog.DatePicker">
|
||||
<item name="windowBackground">@android:color/transparent</item>
|
||||
<item name="windowTitleStyle">@android:style/DialogWindowTitle</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Default dark theme for panel windows (on API level 10 and lower). This removes all
|
||||
extraneous window decorations, so you basically have an empty rectangle in which
|
||||
to place your content. It makes the window floating, with a transparent
|
||||
|
||||
@@ -207,7 +207,23 @@ easier.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
|
||||
|
||||
<!-- The DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.DeviceDefault.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.DeviceDefault.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.DeviceDefault.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.DeviceDefault.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.DeviceDefault.Dialog.DatePicker</item>
|
||||
|
||||
<item name="mediaRouteButtonStyle">@style/Widget.DeviceDefault.MediaRouteButton</item>
|
||||
|
||||
</style>
|
||||
|
||||
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar -->
|
||||
@@ -466,7 +482,23 @@ easier.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
|
||||
|
||||
<!-- The DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- The DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.DatePicker</item>
|
||||
|
||||
<item name="mediaRouteButtonStyle">@style/Widget.DeviceDefault.Light.MediaRouteButton</item>
|
||||
|
||||
</style>
|
||||
|
||||
<!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
|
||||
|
||||
@@ -389,6 +389,33 @@ please see themes_device_defaults.xml.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
|
||||
|
||||
<!-- DatePicker Header day of week label background color -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelBackgroundColor">@android:color/datepicker_default_header_dayofweek_background_color_holo_dark</item>
|
||||
|
||||
<!-- DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.Holo.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector background color -->
|
||||
<item name="datePickerHeaderSelectorBackgroundColor">@android:color/datepicker_default_header_selector_background_holo_dark</item>
|
||||
|
||||
<!-- DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label text appearance -->
|
||||
<item name="datePickerHeaderListYearLabelTextAppearance">@style/TextAppearance.Holo.DatePicker.List.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<item name="datePickerHeaderListYearLabelCircleBackgroundColor">@android:color/datepicker_default_circle_background_color_holo_dark</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.Holo.Dialog.DatePicker</item>
|
||||
|
||||
<item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
|
||||
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
|
||||
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
|
||||
@@ -728,6 +755,33 @@ please see themes_device_defaults.xml.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
|
||||
|
||||
<!-- DatePicker Header day of week label background color -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelBackgroundColor">@android:color/datepicker_default_header_dayofweek_background_color_holo_light</item>
|
||||
|
||||
<!-- DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector background color -->
|
||||
<item name="datePickerHeaderSelectorBackgroundColor">@android:color/datepicker_default_header_selector_background_holo_light</item>
|
||||
|
||||
<!-- DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label text appearance -->
|
||||
<item name="datePickerHeaderListYearLabelTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.List.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<item name="datePickerHeaderListYearLabelCircleBackgroundColor">@android:color/datepicker_default_circle_background_color_holo_light</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.Holo.Light.Dialog.DatePicker</item>
|
||||
|
||||
<item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
|
||||
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
|
||||
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
|
||||
@@ -944,6 +998,14 @@ please see themes_device_defaults.xml.
|
||||
{@link android.app.TimePickerDialog} class. -->
|
||||
<style name="Theme.Holo.Dialog.TimePicker" parent="Theme.Holo.Dialog.Alert" />
|
||||
|
||||
<!-- Holo theme for the DatePicker dialog windows, which is used by the
|
||||
{@link android.app.DatePickerDialog} class. -->
|
||||
<style name="Theme.Holo.Dialog.DatePicker">
|
||||
<item name="windowBackground">@color/transparent</item>
|
||||
<item name="windowTitleStyle">@style/DialogWindowTitle.Holo</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Theme for a window that will be displayed either full-screen on
|
||||
smaller screens (small, normal) or as a dialog on larger screens
|
||||
(large, xlarge). -->
|
||||
@@ -1059,6 +1121,14 @@ please see themes_device_defaults.xml.
|
||||
{@link android.app.TimePickerDialog} class. -->
|
||||
<style name="Theme.Holo.Light.Dialog.TimePicker" parent="Theme.Holo.Light.Dialog.Alert" />
|
||||
|
||||
<!-- Holo Light theme for the DatePicker dialog windows, which is used by the
|
||||
{@link android.app.DatePickerDialog} class. -->
|
||||
<style name="Theme.Holo.Light.Dialog.DatePicker">
|
||||
<item name="windowBackground">@android:color/transparent</item>
|
||||
<item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Theme for a presentation window on a secondary display. -->
|
||||
<style name="Theme.Holo.Light.Dialog.Presentation" parent="Theme.Holo.Light.NoActionBar.Fullscreen" />
|
||||
|
||||
|
||||
@@ -367,6 +367,33 @@ please see themes_device_defaults.xml.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.Material.DatePicker</item>
|
||||
|
||||
<!-- DatePicker Header day of week label background color -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelBackgroundColor">@android:color/datepicker_default_header_dayofweek_background_color_material_dark</item>
|
||||
|
||||
<!-- DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.Material.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector background color -->
|
||||
<item name="datePickerHeaderSelectorBackgroundColor">@android:color/datepicker_default_header_selector_background_material_dark</item>
|
||||
|
||||
<!-- DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.Material.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.Material.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.Material.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label text appearance -->
|
||||
<item name="datePickerHeaderListYearLabelTextAppearance">@style/TextAppearance.Material.DatePicker.List.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<item name="datePickerHeaderListYearLabelCircleBackgroundColor">@android:color/datepicker_default_circle_background_color_material_dark</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.Material.Dialog.DatePicker</item>
|
||||
|
||||
<!-- TODO: This belongs in a FastScroll style -->
|
||||
<item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_material</item>
|
||||
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
|
||||
@@ -715,6 +742,33 @@ please see themes_device_defaults.xml.
|
||||
<!-- DatePicker style -->
|
||||
<item name="datePickerStyle">@style/Widget.Material.Light.DatePicker</item>
|
||||
|
||||
<!-- DatePicker Header day of week label background color -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelBackgroundColor">@android:color/datepicker_default_header_dayofweek_background_color_material_light</item>
|
||||
|
||||
<!-- DatePicker Header day of week label text appearance -->
|
||||
<item name="datePickerHeaderDayOfWeekLabelTextAppearance">@style/TextAppearance.Material.Light.DatePicker.DayOfWeekLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector background color -->
|
||||
<item name="datePickerHeaderSelectorBackgroundColor">@android:color/datepicker_default_header_selector_background_material_light</item>
|
||||
|
||||
<!-- DatePicker Header selector month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorMonthLabelTextAppearance">@style/TextAppearance.Material.Light.DatePicker.Selector.MonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector day of month label text appearance -->
|
||||
<item name="datePickerHeaderSelectorDayOfMonthLabelTextAppearance">@style/TextAppearance.Material.Light.DatePicker.Selector.DayOfMonthLabel</item>
|
||||
|
||||
<!-- DatePicker Header selector year label text appearance -->
|
||||
<item name="datePickerHeaderSelectorYearLabelTextAppearance">@style/TextAppearance.Material.Light.DatePicker.Selector.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label text appearance -->
|
||||
<item name="datePickerHeaderListYearLabelTextAppearance">@style/TextAppearance.Material.Light.DatePicker.List.YearLabel</item>
|
||||
|
||||
<!-- DatePicker list year label circle background color -->
|
||||
<item name="datePickerHeaderListYearLabelCircleBackgroundColor">@android:color/datepicker_default_circle_background_color_material_light</item>
|
||||
|
||||
<!-- DatePicker dialog theme -->
|
||||
<item name="datePickerDialogTheme">@android:style/Theme.Material.Light.Dialog.DatePicker</item>
|
||||
|
||||
<item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_material</item>
|
||||
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
|
||||
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
|
||||
@@ -1110,6 +1164,16 @@ please see themes_device_defaults.xml.
|
||||
{@link android.app.TimePickerDialog} class. -->
|
||||
<style name="Theme.Material.Dialog.TimePicker" parent="Theme.Material.Dialog.BaseTimePicker"/>
|
||||
|
||||
<style name="Theme.Material.Dialog.BaseDatePicker">
|
||||
<item name="windowBackground">@color/transparent</item>
|
||||
<item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Material theme for the DatePicker dialog windows, which is used by the
|
||||
{@link android.app.DatePickerDialog} class. -->
|
||||
<style name="Theme.Material.Dialog.DatePicker" parent="Theme.Material.Dialog.BaseDatePicker"/>
|
||||
|
||||
<!-- Theme for a window that will be displayed either full-screen on
|
||||
smaller screens (small, normal) or as a dialog on larger screens
|
||||
(large, xlarge). -->
|
||||
@@ -1222,12 +1286,23 @@ please see themes_device_defaults.xml.
|
||||
<item name="windowBackground">@color/transparent</item>
|
||||
<item name="windowElevation">0dp</item>
|
||||
<item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Material Light theme for the TimePicker dialog windows, which is used by the
|
||||
{@link android.app.TimePickerDialog} class. -->
|
||||
<style name="Theme.Material.Light.Dialog.TimePicker" parent="Theme.Material.Light.Dialog.BaseTimePicker"/>
|
||||
|
||||
<style name="Theme.Material.Light.Dialog.BaseDatePicker">
|
||||
<item name="windowBackground">@color/transparent</item>
|
||||
<item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
|
||||
<item name="windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Material Light theme for the DatePicker dialog windows, which is used by the
|
||||
{@link android.app.DatePickerDialog} class. -->
|
||||
<style name="Theme.Material.Light.Dialog.DatePicker" parent="Theme.Material.Light.Dialog.BaseDatePicker"/>
|
||||
|
||||
<!-- Theme for a presentation window on a secondary display. -->
|
||||
<style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" />
|
||||
|
||||
|
||||
@@ -250,6 +250,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
// Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
|
||||
long[] mClockTickVibePattern;
|
||||
|
||||
// Vibrator pattern for a short vibration when tapping on a day/month/year date of a Calendar.
|
||||
long[] mCalendarDateVibePattern;
|
||||
|
||||
// Vibrator pattern for haptic feedback during boot when safe mode is disabled.
|
||||
long[] mSafeModeDisabledVibePattern;
|
||||
|
||||
@@ -1071,6 +1074,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
com.android.internal.R.array.config_keyboardTapVibePattern);
|
||||
mClockTickVibePattern = getLongIntArray(mContext.getResources(),
|
||||
com.android.internal.R.array.config_clockTickVibePattern);
|
||||
mCalendarDateVibePattern = getLongIntArray(mContext.getResources(),
|
||||
com.android.internal.R.array.config_calendarDateVibePattern);
|
||||
mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
|
||||
com.android.internal.R.array.config_safeModeDisabledVibePattern);
|
||||
mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
|
||||
@@ -5406,6 +5411,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
case HapticFeedbackConstants.CLOCK_TICK:
|
||||
pattern = mClockTickVibePattern;
|
||||
break;
|
||||
case HapticFeedbackConstants.CALENDAR_DATE:
|
||||
pattern = mCalendarDateVibePattern;
|
||||
break;
|
||||
case HapticFeedbackConstants.SAFE_MODE_DISABLED:
|
||||
pattern = mSafeModeDisabledVibePattern;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user