DayPickerView.java revision 95331038c3eea07af17cb8c64574b6516612548c
1bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/* 278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette * Copyright (C) 2015 The Android Open Source Project 3bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * 4bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 5bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * you may not use this file except in compliance with the License. 6bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * You may obtain a copy of the License at 7bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * 8bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 9bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * 10bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 11bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 12bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * See the License for the specific language governing permissions and 14bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * limitations under the License. 15bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */ 16bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 17bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Megliopackage android.widget; 18bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 1995331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanuimport static android.os.Build.VERSION_CODES.N_MR1; 2095331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu 21698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikovimport android.graphics.Rect; 220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport com.android.internal.R; 2378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport com.android.internal.widget.ViewPager; 2478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport com.android.internal.widget.ViewPager.OnPageChangeListener; 250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport android.annotation.Nullable; 27bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.Context; 28bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.ColorStateList; 290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.res.TypedArray; 3068763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar; 310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.util.AttributeSet; 3250eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viveretteimport android.util.MathUtils; 3378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport android.view.LayoutInflater; 34816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.view.View; 3578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport android.view.ViewGroup; 3678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteimport android.view.accessibility.AccessibilityManager; 37bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 38bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Locale; 39bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport libcore.icu.LocaleData; 410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 4278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteclass DayPickerView extends ViewGroup { 4378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private static final int DEFAULT_LAYOUT = R.layout.day_picker_content_material; 440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private static final int DEFAULT_START_YEAR = 1900; 450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private static final int DEFAULT_END_YEAR = 2100; 46bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 4778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private static final int[] ATTRS_TEXT_COLOR = new int[] { R.attr.textColor }; 4878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final Calendar mSelectedDay = Calendar.getInstance(); 500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final Calendar mMinDate = Calendar.getInstance(); 510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final Calendar mMaxDate = Calendar.getInstance(); 52bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 5378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final AccessibilityManager mAccessibilityManager; 5478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 5578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final ViewPager mViewPager; 5678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final ImageButton mPrevButton; 5778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final ImageButton mNextButton; 58816aa142023c75cf427401c21831193998bdf233Alan Viverette 5978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final DayPickerPagerAdapter mAdapter; 60bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** Temporary calendar used for date calculations. */ 620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private Calendar mTempCalendar; 63bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private OnDaySelectedListener mOnDaySelectedListener; 65e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public DayPickerView(Context context) { 670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette this(context, null); 680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 69bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 7078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public DayPickerView(Context context, @Nullable AttributeSet attrs) { 710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette this(context, attrs, R.attr.calendarViewStyle); 720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 73bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 7478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public DayPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette this(context, attrs, defStyleAttr, 0); 760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 7750eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 7878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public DayPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, 7978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette int defStyleRes) { 800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 814612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 8278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mAccessibilityManager = (AccessibilityManager) context.getSystemService( 8378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette Context.ACCESSIBILITY_SERVICE); 8478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final TypedArray a = context.obtainStyledAttributes(attrs, 860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.CalendarView, defStyleAttr, defStyleRes); 87bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek, 890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette LocaleData.get(Locale.getDefault()).firstDayOfWeek); 90bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String minDate = a.getString(R.styleable.CalendarView_minDate); 920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String maxDate = a.getString(R.styleable.CalendarView_maxDate); 93bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int monthTextAppearanceResId = a.getResourceId( 950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.CalendarView_monthTextAppearance, 960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.style.TextAppearance_Material_Widget_Calendar_Month); 970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int dayOfWeekTextAppearanceResId = a.getResourceId( 980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.CalendarView_weekDayTextAppearance, 990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.style.TextAppearance_Material_Widget_Calendar_DayOfWeek); 1000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int dayTextAppearanceResId = a.getResourceId( 1010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.CalendarView_dateTextAppearance, 1020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.style.TextAppearance_Material_Widget_Calendar_Day); 1030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final ColorStateList daySelectorColor = a.getColorStateList( 1050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.CalendarView_daySelectorColor); 1060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette a.recycle(); 1080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up adapter. 11078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mAdapter = new DayPickerPagerAdapter(context, 11160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette R.layout.date_picker_month_item_material, R.id.month_view); 1120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setMonthTextAppearance(monthTextAppearanceResId); 1130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setDayOfWeekTextAppearance(dayOfWeekTextAppearanceResId); 1140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setDayTextAppearance(dayTextAppearanceResId); 1150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setDaySelectorColor(daySelectorColor); 11650eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 11778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final LayoutInflater inflater = LayoutInflater.from(context); 11878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final ViewGroup content = (ViewGroup) inflater.inflate(DEFAULT_LAYOUT, this, false); 11978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 12078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // Transfer all children from content to here. 12178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette while (content.getChildCount() > 0) { 12278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final View child = content.getChildAt(0); 12378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette content.removeViewAt(0); 12478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette addView(child); 12578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 12678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 12778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mPrevButton = (ImageButton) findViewById(R.id.prev); 12878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mPrevButton.setOnClickListener(mOnClickListener); 12978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 13078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mNextButton = (ImageButton) findViewById(R.id.next); 13178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mNextButton.setOnClickListener(mOnClickListener); 13278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 13378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager = (ViewPager) findViewById(R.id.day_picker_view_pager); 13478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.setAdapter(mAdapter); 13578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.setOnPageChangeListener(mOnPageChangedListener); 13678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 13778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // Proxy the month text color into the previous and next buttons. 13878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette if (monthTextAppearanceResId != 0) { 13978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final TypedArray ta = mContext.obtainStyledAttributes(null, 14078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette ATTRS_TEXT_COLOR, 0, monthTextAppearanceResId); 14178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final ColorStateList monthColor = ta.getColorStateList(0); 14278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette if (monthColor != null) { 14378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mPrevButton.setImageTintList(monthColor); 14478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mNextButton.setImageTintList(monthColor); 14578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 14678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette ta.recycle(); 14778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 148e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 1490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up min and max dates. 1500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final Calendar tempDate = Calendar.getInstance(); 1510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (!CalendarView.parseDate(minDate, tempDate)) { 1520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette tempDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); 1530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final long minDateMillis = tempDate.getTimeInMillis(); 1550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (!CalendarView.parseDate(maxDate, tempDate)) { 1570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette tempDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); 1580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final long maxDateMillis = tempDate.getTimeInMillis(); 1600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (maxDateMillis < minDateMillis) { 1620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette throw new IllegalArgumentException("maxDate must be >= minDate"); 1630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final long setDateMillis = MathUtils.constrain( 1660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette System.currentTimeMillis(), minDateMillis, maxDateMillis); 167e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 1680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setFirstDayOfWeek(firstDayOfWeek); 1690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setMinDate(minDateMillis); 1700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setMaxDate(maxDateMillis); 1710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setDate(setDateMillis, false); 1720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Proxy selection callbacks to our own listener. 17478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mAdapter.setOnDaySelectedListener(new DayPickerPagerAdapter.OnDaySelectedListener() { 1750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 17678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onDaySelected(DayPickerPagerAdapter adapter, Calendar day) { 1770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mOnDaySelectedListener != null) { 1780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mOnDaySelectedListener.onDaySelected(DayPickerView.this, day); 1790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette }); 1820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1845c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette private void updateButtonVisibility(int position) { 1855c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette final boolean hasPrev = position > 0; 1865c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette final boolean hasNext = position < (mAdapter.getCount() - 1); 1875c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette mPrevButton.setVisibility(hasPrev ? View.VISIBLE : View.INVISIBLE); 1885c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette mNextButton.setVisibility(hasNext ? View.VISIBLE : View.INVISIBLE); 1895c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette } 1905c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette 191816aa142023c75cf427401c21831193998bdf233Alan Viverette @Override 192816aa142023c75cf427401c21831193998bdf233Alan Viverette protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 19378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final ViewPager viewPager = mViewPager; 19478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette measureChild(viewPager, widthMeasureSpec, heightMeasureSpec); 19578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 19678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int measuredWidthAndState = viewPager.getMeasuredWidthAndState(); 19778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int measuredHeightAndState = viewPager.getMeasuredHeightAndState(); 19878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette setMeasuredDimension(measuredWidthAndState, measuredHeightAndState); 19978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 20078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int pagerWidth = viewPager.getMeasuredWidth(); 20178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int pagerHeight = viewPager.getMeasuredHeight(); 20278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int buttonWidthSpec = MeasureSpec.makeMeasureSpec(pagerWidth, MeasureSpec.AT_MOST); 20378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int buttonHeightSpec = MeasureSpec.makeMeasureSpec(pagerHeight, MeasureSpec.AT_MOST); 20478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mPrevButton.measure(buttonWidthSpec, buttonHeightSpec); 20578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mNextButton.measure(buttonWidthSpec, buttonHeightSpec); 20678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 207816aa142023c75cf427401c21831193998bdf233Alan Viverette 20878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette @Override 209ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) { 210ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette super.onRtlPropertiesChanged(layoutDirection); 211ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette 212ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette requestLayout(); 213ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette } 214ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette 215ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette @Override 21678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 217ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette final ImageButton leftButton; 218ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette final ImageButton rightButton; 219ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette if (isLayoutRtl()) { 220ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette leftButton = mNextButton; 221ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette rightButton = mPrevButton; 222ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette } else { 223ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette leftButton = mPrevButton; 224ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette rightButton = mNextButton; 225ddf655c49f4173aa55c9ba1a2622cf75cf5bc2f2Alan Viverette } 22678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 22778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int width = right - left; 22878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int height = bottom - top; 22978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.layout(0, 0, width, height); 23078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 23178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final SimpleMonthView monthView = (SimpleMonthView) mViewPager.getChildAt(0); 23278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int monthHeight = monthView.getMonthHeight(); 23378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int cellWidth = monthView.getCellWidth(); 23478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 23578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // Vertically center the previous/next buttons within the month 23678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // header, horizontally center within the day cell. 23778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int leftDW = leftButton.getMeasuredWidth(); 23878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int leftDH = leftButton.getMeasuredHeight(); 23978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2; 24078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int leftIconLeft = monthView.getPaddingLeft() + (cellWidth - leftDW) / 2; 24178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH); 24278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 24378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int rightDW = rightButton.getMeasuredWidth(); 24478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int rightDH = rightButton.getMeasuredHeight(); 24578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int rightIconTop = monthView.getPaddingTop() + (monthHeight - rightDH) / 2; 24678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int rightIconRight = width - monthView.getPaddingRight() - (cellWidth - rightDW) / 2; 24778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette rightButton.layout(rightIconRight - rightDW, rightIconTop, 24878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette rightIconRight, rightIconTop + rightDH); 249816aa142023c75cf427401c21831193998bdf233Alan Viverette } 250816aa142023c75cf427401c21831193998bdf233Alan Viverette 2510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void setDayOfWeekTextAppearance(int resId) { 2520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setDayOfWeekTextAppearance(resId); 2530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public int getDayOfWeekTextAppearance() { 2560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mAdapter.getDayOfWeekTextAppearance(); 2570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void setDayTextAppearance(int resId) { 2600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAdapter.setDayTextAppearance(resId); 2610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public int getDayTextAppearance() { 2640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mAdapter.getDayTextAppearance(); 265e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette } 266e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 2674612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette /** 2684612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette * Sets the currently selected date to the specified timestamp. Jumps 2694612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette * immediately to the new date. To animate to the new date, use 2700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * {@link #setDate(long, boolean)}. 2714612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette * 2720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param timeInMillis the target day in milliseconds 2734612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette */ 2744612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public void setDate(long timeInMillis) { 2750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setDate(timeInMillis, false); 2764612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 2774612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 2780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 2790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Sets the currently selected date to the specified timestamp. Jumps 2800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * immediately to the new date, optionally animating the transition. 2810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 2820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param timeInMillis the target day in milliseconds 2830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param animate whether to smooth scroll to the new position 2840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 2850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void setDate(long timeInMillis, boolean animate) { 2860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setDate(timeInMillis, animate, true); 2870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 2900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Moves to the month containing the specified day, optionally setting the 2910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * day as selected. 2920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 2930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param timeInMillis the target day in milliseconds 2940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param animate whether to smooth scroll to the new position 2950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param setSelected whether to set the specified day as selected 29695331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu * 29795331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu * @throws IllegalArgumentException as of {@link android.os.Build.VERSION_CODES#N_MR1} if the 29895331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu * provided timeInMillis is before the range start or after the range end. 2990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 3000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private void setDate(long timeInMillis, boolean animate, boolean setSelected) { 30195331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu getTempCalendarForTime(timeInMillis); 30295331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu 30395331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; 30495331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu if (targetSdkVersion >= N_MR1) { 30595331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu if (mTempCalendar.before(mMinDate) || mTempCalendar.after(mMaxDate)) { 30695331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu throw new IllegalArgumentException("timeInMillis must be between the values of " 30795331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu + "getMinDate() and getMaxDate()"); 30895331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu } 30995331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu } 31095331038c3eea07af17cb8c64574b6516612548cAndrei Stingaceanu 3110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (setSelected) { 3120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mSelectedDay.setTimeInMillis(timeInMillis); 3130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 3150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int position = getPositionFromDay(timeInMillis); 31678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette if (position != mViewPager.getCurrentItem()) { 31778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.setCurrentItem(position, animate); 3180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 319f63757b7a6d06138860640f8e95326dc1ff47646Alan Viverette 320f63757b7a6d06138860640f8e95326dc1ff47646Alan Viverette mAdapter.setSelectedDay(mTempCalendar); 3214612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 3224612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 3234612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public long getDate() { 3244612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette return mSelectedDay.getTimeInMillis(); 325e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette } 326e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 327698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov public boolean getBoundsForDate(long timeInMillis, Rect outBounds) { 328698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov final int position = getPositionFromDay(timeInMillis); 329698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov if (position != mViewPager.getCurrentItem()) { 330698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov return false; 331698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov } 332698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov 333698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov mTempCalendar.setTimeInMillis(timeInMillis); 334698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov return mAdapter.getBoundsForDate(mTempCalendar, outBounds); 335698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov } 336698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov 337e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette public void setFirstDayOfWeek(int firstDayOfWeek) { 338e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette mAdapter.setFirstDayOfWeek(firstDayOfWeek); 339bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 340bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3414612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public int getFirstDayOfWeek() { 3424612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette return mAdapter.getFirstDayOfWeek(); 3434612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 3444612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 3454612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public void setMinDate(long timeInMillis) { 3464612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mMinDate.setTimeInMillis(timeInMillis); 3474612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette onRangeChanged(); 3484612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 3494612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 3504612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public long getMinDate() { 3514612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette return mMinDate.getTimeInMillis(); 3524612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 3534612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 3544612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public void setMaxDate(long timeInMillis) { 3554612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mMaxDate.setTimeInMillis(timeInMillis); 3564612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette onRangeChanged(); 3574612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 35850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 3594612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public long getMaxDate() { 3604612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette return mMaxDate.getTimeInMillis(); 3614612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 3624612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 3634612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette /** 3644612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette * Handles changes to date range. 3654612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette */ 3664612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette public void onRangeChanged() { 36750eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette mAdapter.setRange(mMinDate, mMaxDate); 36850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 3695ecbfeb38b6bdcfe8f3561f8cdcb4af9ba30c886Alan Viverette // Changing the min/max date changes the selection position since we 3704612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette // don't really have stable IDs. Jumps immediately to the new position. 3710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setDate(mSelectedDay.getTimeInMillis(), false, false); 372bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette 373bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette updateButtonVisibility(mViewPager.getCurrentItem()); 37450eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette } 37550eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 37650eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette /** 377e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette * Sets the listener to call when the user selects a day. 37850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette * 379e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette * @param listener The listener to call. 380bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */ 381e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette public void setOnDaySelectedListener(OnDaySelectedListener listener) { 382e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette mOnDaySelectedListener = listener; 383bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 384bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 38550eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette private int getDiffMonths(Calendar start, Calendar end) { 386bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final int diffYears = end.get(Calendar.YEAR) - start.get(Calendar.YEAR); 3870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears; 388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3904612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette private int getPositionFromDay(long timeInMillis) { 39150eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette final int diffMonthMax = getDiffMonths(mMinDate, mMaxDate); 3924612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette final int diffMonth = getDiffMonths(mMinDate, getTempCalendarForTime(timeInMillis)); 39350eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette return MathUtils.constrain(diffMonth, 0, diffMonthMax); 394bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 395bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3964612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette private Calendar getTempCalendarForTime(long timeInMillis) { 3974612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette if (mTempCalendar == null) { 3984612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mTempCalendar = Calendar.getInstance(); 3994612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 4004612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mTempCalendar.setTimeInMillis(timeInMillis); 4014612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette return mTempCalendar; 4024612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette } 4034612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette 404bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio /** 405bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Gets the position of the view that is most prominently displayed within the list view. 406bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */ 407bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public int getMostVisiblePosition() { 40878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette return mViewPager.getCurrentItem(); 409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 410e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 41178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void setPosition(int position) { 41278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.setCurrentItem(position, false); 41378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 41478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 41578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final OnPageChangeListener mOnPageChangedListener = new OnPageChangeListener() { 41678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette @Override 41778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 41878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final float alpha = Math.abs(0.5f - positionOffset) * 2.0f; 41978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mPrevButton.setAlpha(alpha); 42078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mNextButton.setAlpha(alpha); 42178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 42278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 42378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette @Override 42478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onPageScrollStateChanged(int state) {} 42578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 42678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette @Override 42778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onPageSelected(int position) { 4285c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette updateButtonVisibility(position); 42978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 43078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette }; 43178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 43278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette private final OnClickListener mOnClickListener = new OnClickListener() { 43378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette @Override 43478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onClick(View v) { 43578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int direction; 43678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette if (v == mPrevButton) { 43778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette direction = -1; 43878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } else if (v == mNextButton) { 43978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette direction = 1; 44078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } else { 44178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette return; 44278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 44378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 44478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // Animation is expensive for accessibility services since it sends 44578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // lots of scroll and content change events. 44678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final boolean animate = !mAccessibilityManager.isEnabled(); 44778bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 44878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // ViewPager clamps input values, so we don't need to worry 44978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette // about passing invalid indices. 45078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int nextItem = mViewPager.getCurrentItem() + direction; 45178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mViewPager.setCurrentItem(nextItem, animate); 45278bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette } 45378bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette }; 45478bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette 455e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette public interface OnDaySelectedListener { 45678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette void onDaySelected(DayPickerView view, Calendar day); 457e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette } 458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio} 459