Java tutorial
/* * Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com> * WebSite https://github.com/MiracleTimes-Dev * 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.gitstudy.rili.liarbry; import android.annotation.SuppressLint; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import java.lang.reflect.Constructor; import java.util.List; /** * ViewPager?? * ????52+1?? * WeekViewPager?CalendarView?: */ public final class WeekViewPager extends ViewPager { private boolean isUpdateWeekView; private int mWeekCount; private CalendarViewDelegate mDelegate; /** * ? */ CalendarLayout mParentLayout; /** * ?? */ private boolean isUsingScrollToCalendar = false; public WeekViewPager(Context context) { this(context, null); } public WeekViewPager(Context context, AttributeSet attrs) { super(context, attrs); } void setup(CalendarViewDelegate delegate) { this.mDelegate = delegate; init(); } private void init() { mWeekCount = CalendarUtil.getWeekCountBetweenBothCalendar(mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), mDelegate.getMaxYear(), mDelegate.getMaxYearMonth(), mDelegate.getMaxYearDay(), mDelegate.getWeekStart()); setAdapter(new WeekViewPagerAdapter()); addOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //?4 if (getVisibility() != VISIBLE) { isUsingScrollToCalendar = false; return; } if (isUsingScrollToCalendar) { isUsingScrollToCalendar = false; return; } BaseWeekView view = (BaseWeekView) findViewWithTag(position); if (view != null) { view.performClickCalendar(mDelegate.getSelectMode() != CalendarViewDelegate.SELECT_MODE_DEFAULT ? mDelegate.mIndexCalendar : mDelegate.mSelectedCalendar, !isUsingScrollToCalendar); if (mDelegate.mWeekChangeListener != null) { mDelegate.mWeekChangeListener.onWeekChange(getCurrentWeekCalendars()); } } isUsingScrollToCalendar = false; } @Override public void onPageScrollStateChanged(int state) { } }); } /** * ??? * * @return ??? */ List<Calendar> getCurrentWeekCalendars() { List<Calendar> calendars = CalendarUtil.getWeekCalendars(mDelegate.mIndexCalendar, mDelegate); mDelegate.addSchemesFromMap(calendars); return calendars; } /** * */ void notifyDataSetChanged() { mWeekCount = CalendarUtil.getWeekCountBetweenBothCalendar(mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), mDelegate.getMaxYear(), mDelegate.getMaxYearMonth(), mDelegate.getMaxYearDay(), mDelegate.getWeekStart()); getAdapter().notifyDataSetChanged(); } /** * */ void updateWeekViewClass() { isUpdateWeekView = true; getAdapter().notifyDataSetChanged(); isUpdateWeekView = false; } /** * */ void updateRange() { isUpdateWeekView = true; notifyDataSetChanged(); isUpdateWeekView = false; if (getVisibility() != VISIBLE) { return; } isUsingScrollToCalendar = true; Calendar calendar = mDelegate.mSelectedCalendar; updateSelected(calendar, false); if (mDelegate.mInnerListener != null) { mDelegate.mInnerListener.onWeekDateSelected(calendar, false); } if (mDelegate.mCalendarSelectListener != null) { mDelegate.mCalendarSelectListener.onCalendarSelect(calendar, false); } int i = CalendarUtil.getWeekFromDayInMonth(calendar, mDelegate.getWeekStart()); mParentLayout.updateSelectWeek(i); } /** * * * @param year * @param month * @param day */ void scrollToCalendar(int year, int month, int day, boolean smoothScroll) { isUsingScrollToCalendar = true; Calendar calendar = new Calendar(); calendar.setYear(year); calendar.setMonth(month); calendar.setDay(day); calendar.setCurrentDay(calendar.equals(mDelegate.getCurrentDay())); LunarCalendar.setupLunarCalendar(calendar); mDelegate.mIndexCalendar = calendar; mDelegate.mSelectedCalendar = calendar; mDelegate.updateSelectCalendarScheme(); updateSelected(calendar, smoothScroll); if (mDelegate.mInnerListener != null) { mDelegate.mInnerListener.onWeekDateSelected(calendar, false); } if (mDelegate.mCalendarSelectListener != null) { mDelegate.mCalendarSelectListener.onCalendarSelect(calendar, false); } int i = CalendarUtil.getWeekFromDayInMonth(calendar, mDelegate.getWeekStart()); mParentLayout.updateSelectWeek(i); } /** * ? */ void scrollToCurrent(boolean smoothScroll) { isUsingScrollToCalendar = true; int position = CalendarUtil.getWeekFromCalendarStartWithMinCalendar(mDelegate.getCurrentDay(), mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), mDelegate.getWeekStart()) - 1; int curItem = getCurrentItem(); if (curItem == position) { isUsingScrollToCalendar = false; } setCurrentItem(position, smoothScroll); BaseWeekView view = (BaseWeekView) findViewWithTag(position); if (view != null) { view.performClickCalendar(mDelegate.getCurrentDay(), false); view.setSelectedCalendar(mDelegate.getCurrentDay()); view.invalidate(); } if (mDelegate.mCalendarSelectListener != null && getVisibility() == VISIBLE) { mDelegate.mCalendarSelectListener.onCalendarSelect(mDelegate.mSelectedCalendar, false); } if (getVisibility() == VISIBLE) { mDelegate.mInnerListener.onWeekDateSelected(mDelegate.getCurrentDay(), false); } int i = CalendarUtil.getWeekFromDayInMonth(mDelegate.getCurrentDay(), mDelegate.getWeekStart()); mParentLayout.updateSelectWeek(i); } /** * ? */ void updateSelected(Calendar calendar, boolean smoothScroll) { int position = CalendarUtil.getWeekFromCalendarStartWithMinCalendar(calendar, mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), mDelegate.getWeekStart()) - 1; int curItem = getCurrentItem(); isUsingScrollToCalendar = curItem != position; setCurrentItem(position, smoothScroll); BaseWeekView view = (BaseWeekView) findViewWithTag(position); if (view != null) { view.setSelectedCalendar(calendar); view.invalidate(); } } /** * ?? */ void updateSingleSelect() { if (mDelegate.getSelectMode() == CalendarViewDelegate.SELECT_MODE_DEFAULT) { return; } for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.updateSingleSelect(); } } /** * ? */ void updateDefaultSelect() { BaseWeekView view = (BaseWeekView) findViewWithTag(getCurrentItem()); if (view != null) { view.setSelectedCalendar(mDelegate.mSelectedCalendar); view.invalidate(); } } /** * */ void updateSelected() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.setSelectedCalendar(mDelegate.mSelectedCalendar); view.invalidate(); } } /** * */ void updateScheme() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.update(); } } /** * ??? */ void updateCurrentDate() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.updateCurrentDate(); } } /** * ? */ void updateShowMode() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.updateShowMode(); } } /** * */ void updateWeekStart() { int count = getAdapter().getCount(); mWeekCount = CalendarUtil.getWeekCountBetweenBothCalendar(mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), mDelegate.getMaxYear(), mDelegate.getMaxYearMonth(), mDelegate.getMaxYearDay(), mDelegate.getWeekStart()); /* * count???????notifyDataSetChanged() * ? */ if (count != mWeekCount) { isUpdateWeekView = true; getAdapter().notifyDataSetChanged(); } for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.updateWeekStart(); } isUpdateWeekView = false; updateSelected(mDelegate.mSelectedCalendar, false); } /** * */ final void updateItemHeight() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.updateItemHeight(); view.requestLayout(); } } /** * */ final void clearSelectRange() { for (int i = 0; i < getChildCount(); i++) { BaseWeekView view = (BaseWeekView) getChildAt(i); view.invalidate(); } } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent ev) { return mDelegate.isWeekViewScrollable() && super.onTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mDelegate.isWeekViewScrollable() && super.onInterceptTouchEvent(ev); } /** * */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { heightMeasureSpec = MeasureSpec.makeMeasureSpec(mDelegate.getCalendarItemHeight(), MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * ? */ private class WeekViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return mWeekCount; } @Override public int getItemPosition(Object object) { return isUpdateWeekView ? POSITION_NONE : super.getItemPosition(object); } @Override public boolean isViewFromObject(View view, Object object) { return view.equals(object); } @Override public Object instantiateItem(ViewGroup container, int position) { Calendar calendar = CalendarUtil.getFirstCalendarStartWithMinCalendar(mDelegate.getMinYear(), mDelegate.getMinYearMonth(), mDelegate.getMinYearDay(), position + 1, mDelegate.getWeekStart()); BaseWeekView view; try { Constructor constructor = mDelegate.getWeekViewClass().getConstructor(Context.class); view = (BaseWeekView) constructor.newInstance(getContext()); } catch (Exception e) { e.printStackTrace(); return null; } view.mParentLayout = mParentLayout; view.setup(mDelegate); view.setup(calendar); view.setTag(position); view.setSelectedCalendar(mDelegate.mSelectedCalendar); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { BaseWeekView view = (BaseWeekView) object; if (view == null) { return; } view.onDestroy(); container.removeView(view); } } }