blob: 67fef13d23f26e4f06a076faa55c65b6f15758e7 [file] [log] [blame]
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -07001/*
Alan Viverette78bf1d32015-04-17 10:39:22 -07002 * Copyright (C) 2015 The Android Open Source Project
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget;
18
Alan Viverette78bf1d32015-04-17 10:39:22 -070019import android.annotation.Nullable;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070020import android.content.Context;
21import android.content.res.ColorStateList;
Alan Viverette0ef59ac2015-03-23 13:13:25 -070022import android.content.res.TypedArray;
Aurimas Liutikas99441c52016-10-11 16:48:32 -070023import android.graphics.Rect;
Alan Viverette68763be2016-05-25 11:42:42 -040024import android.icu.util.Calendar;
Alan Viverette0ef59ac2015-03-23 13:13:25 -070025import android.util.AttributeSet;
Alan Viverette50eb0252014-10-24 14:34:26 -070026import android.util.MathUtils;
Alan Viverette78bf1d32015-04-17 10:39:22 -070027import android.view.LayoutInflater;
Alan Viverette816aa142015-04-10 15:41:10 -070028import android.view.View;
Alan Viverette78bf1d32015-04-17 10:39:22 -070029import android.view.ViewGroup;
30import android.view.accessibility.AccessibilityManager;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070031
Aurimas Liutikas99441c52016-10-11 16:48:32 -070032import com.android.internal.R;
33import com.android.internal.widget.ViewPager;
34import com.android.internal.widget.ViewPager.OnPageChangeListener;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070035
Alan Viverette0ef59ac2015-03-23 13:13:25 -070036import libcore.icu.LocaleData;
37
Aurimas Liutikas99441c52016-10-11 16:48:32 -070038import java.util.Locale;
39
Alan Viverette78bf1d32015-04-17 10:39:22 -070040class DayPickerView extends ViewGroup {
41 private static final int DEFAULT_LAYOUT = R.layout.day_picker_content_material;
Alan Viverette0ef59ac2015-03-23 13:13:25 -070042 private static final int DEFAULT_START_YEAR = 1900;
43 private static final int DEFAULT_END_YEAR = 2100;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070044
Alan Viverette78bf1d32015-04-17 10:39:22 -070045 private static final int[] ATTRS_TEXT_COLOR = new int[] { R.attr.textColor };
46
Alan Viverette0ef59ac2015-03-23 13:13:25 -070047 private final Calendar mSelectedDay = Calendar.getInstance();
48 private final Calendar mMinDate = Calendar.getInstance();
49 private final Calendar mMaxDate = Calendar.getInstance();
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070050
Alan Viverette78bf1d32015-04-17 10:39:22 -070051 private final AccessibilityManager mAccessibilityManager;
Alan Viverette816aa142015-04-10 15:41:10 -070052
Alan Viverette78bf1d32015-04-17 10:39:22 -070053 private final ViewPager mViewPager;
54 private final ImageButton mPrevButton;
55 private final ImageButton mNextButton;
56
57 private final DayPickerPagerAdapter mAdapter;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070058
Alan Viverette0ef59ac2015-03-23 13:13:25 -070059 /** Temporary calendar used for date calculations. */
Alan Viverette46127402014-11-13 10:50:37 -080060 private Calendar mTempCalendar;
61
Alan Viverettee763c9b2014-11-06 15:22:31 -080062 private OnDaySelectedListener mOnDaySelectedListener;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070063
Alan Viverettee763c9b2014-11-06 15:22:31 -080064 public DayPickerView(Context context) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -070065 this(context, null);
66 }
67
Alan Viverette78bf1d32015-04-17 10:39:22 -070068 public DayPickerView(Context context, @Nullable AttributeSet attrs) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -070069 this(context, attrs, R.attr.calendarViewStyle);
70 }
71
Alan Viverette78bf1d32015-04-17 10:39:22 -070072 public DayPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -070073 this(context, attrs, defStyleAttr, 0);
74 }
75
Alan Viverette78bf1d32015-04-17 10:39:22 -070076 public DayPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
77 int defStyleRes) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -070078 super(context, attrs, defStyleAttr, defStyleRes);
79
Alan Viverette78bf1d32015-04-17 10:39:22 -070080 mAccessibilityManager = (AccessibilityManager) context.getSystemService(
81 Context.ACCESSIBILITY_SERVICE);
82
Alan Viverette0ef59ac2015-03-23 13:13:25 -070083 final TypedArray a = context.obtainStyledAttributes(attrs,
84 R.styleable.CalendarView, defStyleAttr, defStyleRes);
Aurimas Liutikasab324cf2019-02-07 16:46:38 -080085 saveAttributeDataForStyleable(context, R.styleable.CalendarView,
86 attrs, a, defStyleAttr, defStyleRes);
Alan Viverette0ef59ac2015-03-23 13:13:25 -070087
88 final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
89 LocaleData.get(Locale.getDefault()).firstDayOfWeek);
90
91 final String minDate = a.getString(R.styleable.CalendarView_minDate);
92 final String maxDate = a.getString(R.styleable.CalendarView_maxDate);
93
94 final int monthTextAppearanceResId = a.getResourceId(
95 R.styleable.CalendarView_monthTextAppearance,
96 R.style.TextAppearance_Material_Widget_Calendar_Month);
97 final int dayOfWeekTextAppearanceResId = a.getResourceId(
98 R.styleable.CalendarView_weekDayTextAppearance,
99 R.style.TextAppearance_Material_Widget_Calendar_DayOfWeek);
100 final int dayTextAppearanceResId = a.getResourceId(
101 R.styleable.CalendarView_dateTextAppearance,
102 R.style.TextAppearance_Material_Widget_Calendar_Day);
103
104 final ColorStateList daySelectorColor = a.getColorStateList(
105 R.styleable.CalendarView_daySelectorColor);
106
107 a.recycle();
108
109 // Set up adapter.
Alan Viverette78bf1d32015-04-17 10:39:22 -0700110 mAdapter = new DayPickerPagerAdapter(context,
Alan Viverette60b674e2015-03-25 13:00:42 -0700111 R.layout.date_picker_month_item_material, R.id.month_view);
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700112 mAdapter.setMonthTextAppearance(monthTextAppearanceResId);
113 mAdapter.setDayOfWeekTextAppearance(dayOfWeekTextAppearanceResId);
114 mAdapter.setDayTextAppearance(dayTextAppearanceResId);
115 mAdapter.setDaySelectorColor(daySelectorColor);
Alan Viverette50eb0252014-10-24 14:34:26 -0700116
Alan Viverette78bf1d32015-04-17 10:39:22 -0700117 final LayoutInflater inflater = LayoutInflater.from(context);
118 final ViewGroup content = (ViewGroup) inflater.inflate(DEFAULT_LAYOUT, this, false);
119
120 // Transfer all children from content to here.
121 while (content.getChildCount() > 0) {
122 final View child = content.getChildAt(0);
123 content.removeViewAt(0);
124 addView(child);
125 }
126
Alan Viverette51efddb2017-04-05 10:00:01 -0400127 mPrevButton = findViewById(R.id.prev);
Alan Viverette78bf1d32015-04-17 10:39:22 -0700128 mPrevButton.setOnClickListener(mOnClickListener);
129
Alan Viverette51efddb2017-04-05 10:00:01 -0400130 mNextButton = findViewById(R.id.next);
Alan Viverette78bf1d32015-04-17 10:39:22 -0700131 mNextButton.setOnClickListener(mOnClickListener);
132
Alan Viverette51efddb2017-04-05 10:00:01 -0400133 mViewPager = findViewById(R.id.day_picker_view_pager);
Alan Viverette78bf1d32015-04-17 10:39:22 -0700134 mViewPager.setAdapter(mAdapter);
135 mViewPager.setOnPageChangeListener(mOnPageChangedListener);
136
137 // Proxy the month text color into the previous and next buttons.
138 if (monthTextAppearanceResId != 0) {
139 final TypedArray ta = mContext.obtainStyledAttributes(null,
140 ATTRS_TEXT_COLOR, 0, monthTextAppearanceResId);
141 final ColorStateList monthColor = ta.getColorStateList(0);
142 if (monthColor != null) {
143 mPrevButton.setImageTintList(monthColor);
144 mNextButton.setImageTintList(monthColor);
145 }
146 ta.recycle();
147 }
Alan Viverettee763c9b2014-11-06 15:22:31 -0800148
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700149 // Set up min and max dates.
150 final Calendar tempDate = Calendar.getInstance();
151 if (!CalendarView.parseDate(minDate, tempDate)) {
152 tempDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
153 }
154 final long minDateMillis = tempDate.getTimeInMillis();
Alan Viverettee763c9b2014-11-06 15:22:31 -0800155
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700156 if (!CalendarView.parseDate(maxDate, tempDate)) {
157 tempDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
158 }
159 final long maxDateMillis = tempDate.getTimeInMillis();
160
161 if (maxDateMillis < minDateMillis) {
162 throw new IllegalArgumentException("maxDate must be >= minDate");
163 }
164
165 final long setDateMillis = MathUtils.constrain(
166 System.currentTimeMillis(), minDateMillis, maxDateMillis);
167
168 setFirstDayOfWeek(firstDayOfWeek);
169 setMinDate(minDateMillis);
170 setMaxDate(maxDateMillis);
171 setDate(setDateMillis, false);
172
173 // Proxy selection callbacks to our own listener.
Alan Viverette78bf1d32015-04-17 10:39:22 -0700174 mAdapter.setOnDaySelectedListener(new DayPickerPagerAdapter.OnDaySelectedListener() {
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700175 @Override
Alan Viverette78bf1d32015-04-17 10:39:22 -0700176 public void onDaySelected(DayPickerPagerAdapter adapter, Calendar day) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700177 if (mOnDaySelectedListener != null) {
178 mOnDaySelectedListener.onDaySelected(DayPickerView.this, day);
179 }
180 }
181 });
182 }
183
Alan Viverette5c339492015-04-28 14:07:36 -0700184 private void updateButtonVisibility(int position) {
185 final boolean hasPrev = position > 0;
186 final boolean hasNext = position < (mAdapter.getCount() - 1);
187 mPrevButton.setVisibility(hasPrev ? View.VISIBLE : View.INVISIBLE);
188 mNextButton.setVisibility(hasNext ? View.VISIBLE : View.INVISIBLE);
189 }
190
Alan Viverette816aa142015-04-10 15:41:10 -0700191 @Override
192 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Alan Viverette78bf1d32015-04-17 10:39:22 -0700193 final ViewPager viewPager = mViewPager;
194 measureChild(viewPager, widthMeasureSpec, heightMeasureSpec);
Alan Viverette816aa142015-04-10 15:41:10 -0700195
Alan Viverette78bf1d32015-04-17 10:39:22 -0700196 final int measuredWidthAndState = viewPager.getMeasuredWidthAndState();
197 final int measuredHeightAndState = viewPager.getMeasuredHeightAndState();
198 setMeasuredDimension(measuredWidthAndState, measuredHeightAndState);
Alan Viverette816aa142015-04-10 15:41:10 -0700199
Alan Viverette78bf1d32015-04-17 10:39:22 -0700200 final int pagerWidth = viewPager.getMeasuredWidth();
201 final int pagerHeight = viewPager.getMeasuredHeight();
202 final int buttonWidthSpec = MeasureSpec.makeMeasureSpec(pagerWidth, MeasureSpec.AT_MOST);
203 final int buttonHeightSpec = MeasureSpec.makeMeasureSpec(pagerHeight, MeasureSpec.AT_MOST);
204 mPrevButton.measure(buttonWidthSpec, buttonHeightSpec);
205 mNextButton.measure(buttonWidthSpec, buttonHeightSpec);
206 }
Alan Viverette816aa142015-04-10 15:41:10 -0700207
Alan Viverette78bf1d32015-04-17 10:39:22 -0700208 @Override
Alan Viveretteddf655c2015-04-22 13:43:31 -0700209 public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
210 super.onRtlPropertiesChanged(layoutDirection);
211
212 requestLayout();
213 }
214
215 @Override
Alan Viverette78bf1d32015-04-17 10:39:22 -0700216 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Alan Viveretteddf655c2015-04-22 13:43:31 -0700217 final ImageButton leftButton;
218 final ImageButton rightButton;
219 if (isLayoutRtl()) {
220 leftButton = mNextButton;
221 rightButton = mPrevButton;
222 } else {
223 leftButton = mPrevButton;
224 rightButton = mNextButton;
225 }
Alan Viverette816aa142015-04-10 15:41:10 -0700226
Alan Viverette78bf1d32015-04-17 10:39:22 -0700227 final int width = right - left;
228 final int height = bottom - top;
229 mViewPager.layout(0, 0, width, height);
230
Alan Viverette78bf1d32015-04-17 10:39:22 -0700231 final SimpleMonthView monthView = (SimpleMonthView) mViewPager.getChildAt(0);
232 final int monthHeight = monthView.getMonthHeight();
233 final int cellWidth = monthView.getCellWidth();
Alan Viverette816aa142015-04-10 15:41:10 -0700234
Alan Viverette78bf1d32015-04-17 10:39:22 -0700235 // Vertically center the previous/next buttons within the month
236 // header, horizontally center within the day cell.
237 final int leftDW = leftButton.getMeasuredWidth();
238 final int leftDH = leftButton.getMeasuredHeight();
239 final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2;
240 final int leftIconLeft = monthView.getPaddingLeft() + (cellWidth - leftDW) / 2;
241 leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH);
Alan Viverette816aa142015-04-10 15:41:10 -0700242
Alan Viverette78bf1d32015-04-17 10:39:22 -0700243 final int rightDW = rightButton.getMeasuredWidth();
244 final int rightDH = rightButton.getMeasuredHeight();
245 final int rightIconTop = monthView.getPaddingTop() + (monthHeight - rightDH) / 2;
246 final int rightIconRight = width - monthView.getPaddingRight() - (cellWidth - rightDW) / 2;
247 rightButton.layout(rightIconRight - rightDW, rightIconTop,
248 rightIconRight, rightIconTop + rightDH);
Alan Viverette816aa142015-04-10 15:41:10 -0700249 }
250
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700251 public void setDayOfWeekTextAppearance(int resId) {
252 mAdapter.setDayOfWeekTextAppearance(resId);
253 }
254
255 public int getDayOfWeekTextAppearance() {
256 return mAdapter.getDayOfWeekTextAppearance();
257 }
258
259 public void setDayTextAppearance(int resId) {
260 mAdapter.setDayTextAppearance(resId);
261 }
262
263 public int getDayTextAppearance() {
264 return mAdapter.getDayTextAppearance();
Alan Viverettee763c9b2014-11-06 15:22:31 -0800265 }
266
Alan Viverette46127402014-11-13 10:50:37 -0800267 /**
268 * Sets the currently selected date to the specified timestamp. Jumps
269 * immediately to the new date. To animate to the new date, use
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700270 * {@link #setDate(long, boolean)}.
Alan Viverette46127402014-11-13 10:50:37 -0800271 *
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700272 * @param timeInMillis the target day in milliseconds
Alan Viverette46127402014-11-13 10:50:37 -0800273 */
274 public void setDate(long timeInMillis) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700275 setDate(timeInMillis, false);
Alan Viverette46127402014-11-13 10:50:37 -0800276 }
277
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700278 /**
279 * Sets the currently selected date to the specified timestamp. Jumps
280 * immediately to the new date, optionally animating the transition.
281 *
282 * @param timeInMillis the target day in milliseconds
283 * @param animate whether to smooth scroll to the new position
284 */
285 public void setDate(long timeInMillis, boolean animate) {
286 setDate(timeInMillis, animate, true);
287 }
288
289 /**
290 * Moves to the month containing the specified day, optionally setting the
291 * day as selected.
292 *
293 * @param timeInMillis the target day in milliseconds
294 * @param animate whether to smooth scroll to the new position
295 * @param setSelected whether to set the specified day as selected
296 */
297 private void setDate(long timeInMillis, boolean animate, boolean setSelected) {
Andrei Stingaceanue565e522017-06-13 17:12:52 +0100298 boolean dateClamped = false;
299 // Clamp the target day in milliseconds to the min or max if outside the range.
300 if (timeInMillis < mMinDate.getTimeInMillis()) {
301 timeInMillis = mMinDate.getTimeInMillis();
302 dateClamped = true;
303 } else if (timeInMillis > mMaxDate.getTimeInMillis()) {
304 timeInMillis = mMaxDate.getTimeInMillis();
305 dateClamped = true;
306 }
307
Andrei Stingaceanu95331032016-06-28 15:56:44 +0100308 getTempCalendarForTime(timeInMillis);
309
Andrei Stingaceanue565e522017-06-13 17:12:52 +0100310 if (setSelected || dateClamped) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700311 mSelectedDay.setTimeInMillis(timeInMillis);
312 }
313
314 final int position = getPositionFromDay(timeInMillis);
Alan Viverette78bf1d32015-04-17 10:39:22 -0700315 if (position != mViewPager.getCurrentItem()) {
316 mViewPager.setCurrentItem(position, animate);
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700317 }
Alan Viverettef63757b2015-04-01 17:14:45 -0700318
Alan Viverettef63757b2015-04-01 17:14:45 -0700319 mAdapter.setSelectedDay(mTempCalendar);
Alan Viverette46127402014-11-13 10:50:37 -0800320 }
321
322 public long getDate() {
323 return mSelectedDay.getTimeInMillis();
Alan Viverettee763c9b2014-11-06 15:22:31 -0800324 }
325
Kirill Grouchnikov698b7512016-04-11 17:16:52 -0400326 public boolean getBoundsForDate(long timeInMillis, Rect outBounds) {
327 final int position = getPositionFromDay(timeInMillis);
328 if (position != mViewPager.getCurrentItem()) {
329 return false;
330 }
331
332 mTempCalendar.setTimeInMillis(timeInMillis);
333 return mAdapter.getBoundsForDate(mTempCalendar, outBounds);
334 }
335
Alan Viverettee763c9b2014-11-06 15:22:31 -0800336 public void setFirstDayOfWeek(int firstDayOfWeek) {
337 mAdapter.setFirstDayOfWeek(firstDayOfWeek);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700338 }
339
Alan Viverette46127402014-11-13 10:50:37 -0800340 public int getFirstDayOfWeek() {
341 return mAdapter.getFirstDayOfWeek();
342 }
Alan Viverette50eb0252014-10-24 14:34:26 -0700343
Alan Viverette46127402014-11-13 10:50:37 -0800344 public void setMinDate(long timeInMillis) {
345 mMinDate.setTimeInMillis(timeInMillis);
346 onRangeChanged();
347 }
348
349 public long getMinDate() {
350 return mMinDate.getTimeInMillis();
351 }
352
353 public void setMaxDate(long timeInMillis) {
354 mMaxDate.setTimeInMillis(timeInMillis);
355 onRangeChanged();
356 }
357
358 public long getMaxDate() {
359 return mMaxDate.getTimeInMillis();
360 }
361
362 /**
363 * Handles changes to date range.
364 */
365 public void onRangeChanged() {
Alan Viverette50eb0252014-10-24 14:34:26 -0700366 mAdapter.setRange(mMinDate, mMaxDate);
367
Alan Viverette5ecbfeb2014-11-03 18:31:36 -0800368 // Changing the min/max date changes the selection position since we
Alan Viverette46127402014-11-13 10:50:37 -0800369 // don't really have stable IDs. Jumps immediately to the new position.
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700370 setDate(mSelectedDay.getTimeInMillis(), false, false);
Alan Viverettebd51b4d2015-05-15 14:18:44 -0700371
372 updateButtonVisibility(mViewPager.getCurrentItem());
Alan Viverette50eb0252014-10-24 14:34:26 -0700373 }
374
375 /**
Alan Viverettee763c9b2014-11-06 15:22:31 -0800376 * Sets the listener to call when the user selects a day.
Alan Viverette50eb0252014-10-24 14:34:26 -0700377 *
Alan Viverettee763c9b2014-11-06 15:22:31 -0800378 * @param listener The listener to call.
Alan Viverette50eb0252014-10-24 14:34:26 -0700379 */
Alan Viverettee763c9b2014-11-06 15:22:31 -0800380 public void setOnDaySelectedListener(OnDaySelectedListener listener) {
381 mOnDaySelectedListener = listener;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700382 }
383
Alan Viverette50eb0252014-10-24 14:34:26 -0700384 private int getDiffMonths(Calendar start, Calendar end) {
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700385 final int diffYears = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700386 return end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700387 }
388
Alan Viverette46127402014-11-13 10:50:37 -0800389 private int getPositionFromDay(long timeInMillis) {
Alan Viverette50eb0252014-10-24 14:34:26 -0700390 final int diffMonthMax = getDiffMonths(mMinDate, mMaxDate);
Alan Viverette46127402014-11-13 10:50:37 -0800391 final int diffMonth = getDiffMonths(mMinDate, getTempCalendarForTime(timeInMillis));
Alan Viverette50eb0252014-10-24 14:34:26 -0700392 return MathUtils.constrain(diffMonth, 0, diffMonthMax);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700393 }
394
Alan Viverette46127402014-11-13 10:50:37 -0800395 private Calendar getTempCalendarForTime(long timeInMillis) {
396 if (mTempCalendar == null) {
397 mTempCalendar = Calendar.getInstance();
398 }
399 mTempCalendar.setTimeInMillis(timeInMillis);
400 return mTempCalendar;
401 }
402
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700403 /**
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700404 * Gets the position of the view that is most prominently displayed within the list view.
405 */
406 public int getMostVisiblePosition() {
Alan Viverette78bf1d32015-04-17 10:39:22 -0700407 return mViewPager.getCurrentItem();
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700408 }
Alan Viverettee763c9b2014-11-06 15:22:31 -0800409
Alan Viverette78bf1d32015-04-17 10:39:22 -0700410 public void setPosition(int position) {
411 mViewPager.setCurrentItem(position, false);
412 }
413
414 private final OnPageChangeListener mOnPageChangedListener = new OnPageChangeListener() {
415 @Override
416 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
417 final float alpha = Math.abs(0.5f - positionOffset) * 2.0f;
418 mPrevButton.setAlpha(alpha);
419 mNextButton.setAlpha(alpha);
420 }
421
422 @Override
423 public void onPageScrollStateChanged(int state) {}
424
425 @Override
426 public void onPageSelected(int position) {
Alan Viverette5c339492015-04-28 14:07:36 -0700427 updateButtonVisibility(position);
Alan Viverette78bf1d32015-04-17 10:39:22 -0700428 }
429 };
430
431 private final OnClickListener mOnClickListener = new OnClickListener() {
432 @Override
433 public void onClick(View v) {
434 final int direction;
435 if (v == mPrevButton) {
436 direction = -1;
437 } else if (v == mNextButton) {
438 direction = 1;
439 } else {
440 return;
441 }
442
443 // Animation is expensive for accessibility services since it sends
444 // lots of scroll and content change events.
445 final boolean animate = !mAccessibilityManager.isEnabled();
446
447 // ViewPager clamps input values, so we don't need to worry
448 // about passing invalid indices.
449 final int nextItem = mViewPager.getCurrentItem() + direction;
450 mViewPager.setCurrentItem(nextItem, animate);
451 }
452 };
453
Alan Viverettee763c9b2014-11-06 15:22:31 -0800454 public interface OnDaySelectedListener {
Alan Viverette78bf1d32015-04-17 10:39:22 -0700455 void onDaySelected(DayPickerView view, Calendar day);
Alan Viverettee763c9b2014-11-06 15:22:31 -0800456 }
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700457}