Fields Summary |
---|
private static final String | TAG |
protected static final int | SCROLL_HYST_WEEKS |
protected static final int | GOTO_SCROLL_DURATION |
protected static final int | SCROLL_CHANGE_DELAY |
public static final int | DAYS_PER_WEEK |
public static int | LIST_TOP_OFFSET |
protected int | mNumWeeks |
protected boolean | mShowWeekNumber |
protected int | mDaysPerWeek |
private static SimpleDateFormat | YEAR_FORMAT |
protected float | mFriction |
protected android.content.Context | mContext |
protected android.os.Handler | mHandler |
protected com.android.datetimepicker.date.MonthAdapter.CalendarDay | mSelectedDay |
protected MonthAdapter | mAdapter |
protected com.android.datetimepicker.date.MonthAdapter.CalendarDay | mTempDay |
protected int | mFirstDayOfWeek |
protected CharSequence | mPrevMonthName |
protected int | mCurrentMonthDisplayed |
protected long | mPreviousScrollPosition |
protected int | mPreviousScrollState |
protected int | mCurrentScrollState |
private DatePickerController | mController |
private boolean | mPerformingScroll |
protected ScrollStateRunnable | mScrollStateChangedRunnable |
Methods Summary |
---|
public abstract MonthAdapter | createMonthAdapter(android.content.Context context, DatePickerController controller)
|
private com.android.datetimepicker.date.MonthAdapter.CalendarDay | findAccessibilityFocus()Attempts to return the date that has accessibility focus.
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child instanceof MonthView) {
final CalendarDay focus = ((MonthView) child).getAccessibilityFocus();
if (focus != null) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
// Clear focus to avoid ListView bug in Jelly Bean MR1.
((MonthView) child).clearAccessibilityFocus();
}
return focus;
}
}
}
return null;
|
private static java.lang.String | getMonthAndYearString(com.android.datetimepicker.date.MonthAdapter.CalendarDay day)
Calendar cal = Calendar.getInstance();
cal.set(day.year, day.month, day.day);
StringBuffer sbuf = new StringBuffer();
sbuf.append(cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
sbuf.append(" ");
sbuf.append(YEAR_FORMAT.format(cal.getTime()));
return sbuf.toString();
|
public int | getMostVisiblePosition()Gets the position of the view that is most prominently displayed within the list view.
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;
|
public boolean | goTo(com.android.datetimepicker.date.MonthAdapter.CalendarDay day, boolean animate, boolean setSelected, boolean forceScroll)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.
// Set the selected day
if (setSelected) {
mSelectedDay.set(day);
}
mTempDay.set(day);
final int position = (day.year - mController.getMinYear())
* MonthAdapter.MONTHS_IN_YEAR + day.month;
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();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "child at " + (i - 1) + " has top " + top);
}
} 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);
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "GoTo position " + position);
}
// 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 | init(android.content.Context context)
mHandler = new Handler();
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setDrawSelectorOnTop(false);
mContext = context;
setUpListView();
|
protected void | layoutChildren()
final CalendarDay focusedDay = findAccessibilityFocus();
super.layoutChildren();
if (mPerformingScroll) {
mPerformingScroll = false;
} else {
restoreAccessibilityFocus(focusedDay);
}
|
public void | onChange()
refreshAdapter();
|
public void | onDateChanged()
goTo(mController.getSelectedDay(), false, true, true);
|
public void | onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
super.onInitializeAccessibilityEvent(event);
event.setItemCount(-1);
|
public void | onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo info)Necessary for accessibility, to ensure we support "scrolling" forward and backward
in the month list.
super.onInitializeAccessibilityNodeInfo(info);
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
|
public void | onScroll(android.widget.AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)Updates the title and selected month if the view has moved to a new
month.
MonthView child = (MonthView) view.getChildAt(0);
if (child == null) {
return;
}
// Figure out where we are
long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
mPreviousScrollPosition = currScroll;
mPreviousScrollState = mCurrentScrollState;
|
public void | onScrollStateChanged(android.widget.AbsListView view, int scrollState)
// use a post to prevent re-entering onScrollStateChanged before it
// exits
mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
|
public boolean | performAccessibilityAction(int action, android.os.Bundle arguments)When scroll forward/backward events are received, announce the newly scrolled-to month.
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();
CalendarDay day = new CalendarDay(year, month, 1);
// Scroll either forward or backward one month.
if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
day.month++;
if (day.month == 12) {
day.month = 0;
day.year++;
}
} 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.month--;
if (day.month == -1) {
day.month = 11;
day.year--;
}
}
}
// Go to that month.
Utils.tryAccessibilityAnnounce(this, getMonthAndYearString(day));
goTo(day, true, false, true);
mPerformingScroll = true;
return true;
|
public void | postSetSelection(int position)
clearFocus();
post(new Runnable() {
@Override
public void run() {
setSelection(position);
}
});
onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE);
|
protected void | refreshAdapter()Creates a new adapter if necessary and sets up its parameters. Override
this method to provide a custom adapter.
if (mAdapter == null) {
mAdapter = createMonthAdapter(getContext(), mController);
} else {
mAdapter.setSelectedDay(mSelectedDay);
}
// refresh the view with the new parameters
setAdapter(mAdapter);
|
private boolean | restoreAccessibilityFocus(com.android.datetimepicker.date.MonthAdapter.CalendarDay day)Attempts to restore accessibility focus to a given date. No-op if
{@code day} is {@code null}.
if (day == null) {
return false;
}
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child instanceof MonthView) {
if (((MonthView) child).restoreAccessibilityFocus(day)) {
return true;
}
}
}
return false;
|
public void | setController(DatePickerController controller)
mController = controller;
mController.registerOnDateChangedListener(this);
refreshAdapter();
onDateChanged();
|
protected void | setMonthDisplayed(com.android.datetimepicker.date.MonthAdapter.CalendarDay date)Sets the month displayed at the top of this view based on time. Override
to add custom events when the title is changed.
mCurrentMonthDisplayed = date.month;
invalidateViews();
|
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);
|