diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/CollapseCalendarView.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/CollapseCalendarView.java index 9e0d6ae..c4aaad8 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/CollapseCalendarView.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/CollapseCalendarView.java @@ -1,11 +1,12 @@ package com.wefika.calendar; +import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; +import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; -import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -44,7 +45,7 @@ public class CollapseCalendarView extends LinearLayout implements View.OnClickLi @NonNull private ImageButton mNext; @NonNull private LinearLayout mWeeksView; - @NonNull private final LayoutInflater mInflater; + @NonNull private LayoutInflater mInflater; @NonNull private final RecycleBin mRecycleBin = new RecycleBin(); @Nullable private OnDateSelect mListener; @@ -67,27 +68,27 @@ public CollapseCalendarView(Context context, AttributeSet attrs) { public CollapseCalendarView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mInflater = LayoutInflater.from(context); + construct(context); - mResizeManager = new ResizeManager(this); + } - inflate(context, R.layout.calendar_layout, this); + @TargetApi(VERSION_CODES.LOLLIPOP) + public CollapseCalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + construct(context); - setOrientation(VERTICAL); } public void init(@NonNull CalendarManager manager) { - if (manager != null) { - - mManager = manager; - - populateLayout(); + mManager = manager; - if (mListener != null) { - mListener.onDateSelected(mManager.getSelectedDay()); - } + populateLayout(); + if (mListener != null) { + mListener.onDateSelected(mManager.getSelectedDay()); } + } @Nullable @@ -97,7 +98,6 @@ public CalendarManager getManager() { @Override public void onClick(View v) { - Log.d(TAG, "On click"); if (mManager != null) { int id = v.getId(); if (id == R.id.prev) { @@ -105,9 +105,7 @@ public void onClick(View v) { populateLayout(); } } else if (id == R.id.next) { - Log.d(TAG, "next"); if (mManager.next()) { - Log.d(TAG, "populate"); populateLayout(); } } @@ -115,6 +113,20 @@ public void onClick(View v) { } } + public void selectDate(@NonNull LocalDate date) { + + boolean period = mManager.selectPeriod(date); + boolean day = mManager.selectDay(date); + + if (period || day) { + populateLayout(); + } + + if (day && mListener != null) { + mListener.onDateSelected(date); + } + } + @Override protected void dispatchDraw(@NonNull Canvas canvas) { mResizeManager.onDraw(); @@ -149,6 +161,10 @@ public void setTitle(@Nullable String text) { } } + public void toggle() { + mResizeManager.toggle(); + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mResizeManager.onInterceptTouchEvent(ev); @@ -179,6 +195,18 @@ protected void onFinishInflate() { populateLayout(); } + private void construct(@NonNull Context context) { + + mInflater = LayoutInflater.from(context); + + mResizeManager = new ResizeManager(this); + + inflate(context, R.layout.calendar_layout, this); + + setOrientation(VERTICAL); + + } + private void populateDays() { if (!initialized) { diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarManager.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarManager.java index 897aeed..943f5f3 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarManager.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarManager.java @@ -39,8 +39,20 @@ public CalendarManager(@NonNull LocalDate selected, @NonNull State state, @Nulla init(selected, minDate, maxDate); } + public boolean selectPeriod(@NonNull LocalDate date) { + + if (!mUnit.isIn(date) && mUnit.setPeriod(date)) { + mUnit.select(mSelected); + setActiveMonth(mUnit.getFrom()); + return true; + } else { + return false; + } + + } + public boolean selectDay(@NonNull LocalDate date) { - if (!mSelected.isEqual(date)) { + if (!mSelected.isEqual(date) && mUnit.hasDate(date)) { mUnit.deselect(mSelected); mSelected = date; mUnit.select(mSelected); @@ -74,22 +86,27 @@ public boolean hasPrev() { public boolean next() { - boolean next = mUnit.next(); - mUnit.select(mSelected); - - setActiveMonth(mUnit.getFrom()); + if (mUnit.next()) { + mUnit.select(mSelected); - return next; + setActiveMonth(mUnit.getFrom()); + return true; + } else { + return false; + } } public boolean prev() { - boolean prev = mUnit.prev(); - mUnit.select(mSelected); + if (mUnit.prev()) { + mUnit.select(mSelected); - setActiveMonth(mUnit.getTo()); + setActiveMonth(mUnit.getTo()); + return true; + } else { + return false; + } - return prev; } /** diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarUnit.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarUnit.java index 28fb034..b04c856 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarUnit.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/CalendarUnit.java @@ -60,10 +60,14 @@ public boolean isSelected() { return mSelected; } + public abstract boolean hasDate(@NonNull LocalDate date); + public abstract boolean hasNext(); public abstract boolean hasPrev(); + public abstract boolean setPeriod(@NonNull LocalDate date); + public abstract boolean next(); public abstract boolean prev(); diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Month.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Month.java index e4d5936..060d940 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Month.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Month.java @@ -71,6 +71,19 @@ public boolean hasPrev() { } } + @Override public boolean setPeriod(@NonNull LocalDate date) { + + if (hasDate(date)) { + setFrom(date.withDayOfMonth(1)); + setTo(getFrom().withDayOfMonth(getFrom().dayOfMonth().getMaximumValue())); + + build(); + return true; + } else { + return false; + } + } + @Override public boolean next() { diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManager.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManager.java index 1844cbe..e9bee1e 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManager.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManager.java @@ -22,6 +22,8 @@ public abstract class ProgressManager { protected SizeViewHolder mCalendarHolder; protected SizeViewHolder mWeeksHolder; + private OnInitListener listener; + final int mActiveIndex; private boolean mInitialized = false; @@ -57,12 +59,20 @@ public void apply(float progress) { } + public void setListener(OnInitListener listener) { + this.listener = listener; + } + public boolean isInitialized() { return mInitialized; } void setInitialized(boolean initialized) { mInitialized = initialized; + + if (listener != null && initialized) { + listener.onInit(); + } } public int getCurrentHeight() { @@ -97,4 +107,8 @@ private int getDeltaInBounds(float delta) { } + interface OnInitListener { + void onInit(); + } + } diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManagerImpl.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManagerImpl.java index 821e8ab..ed24eb5 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManagerImpl.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ProgressManagerImpl.java @@ -78,6 +78,7 @@ public boolean onPreDraw() { initializeChildren(); setInitialized(true); + apply(0); return false; } @@ -110,6 +111,7 @@ public boolean onPreDraw() { mWeeksView.getLayoutParams().height = mCalendarHolder.getMaxHeight(); setInitialized(true); + apply(1); return false; } diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/RangeUnit.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/RangeUnit.java index 5b1ec62..8fdcc09 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/RangeUnit.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/RangeUnit.java @@ -36,6 +36,25 @@ public LocalDate getMaxDate() { return mMaxDate; } + @Override public boolean hasDate(@NonNull LocalDate date) { + + boolean min = true; + boolean max = true; + + LocalDate maxDate = getMaxDate(); + if (maxDate != null) { + max = !date.isAfter(maxDate); + } + + LocalDate minDate = getMinDate(); + if (minDate != null) { + min = !date.isBefore(minDate); + } + + return min && max; + + } + /** * * diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ResizeManager.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ResizeManager.java index b3893c3..f1b07b3 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ResizeManager.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/ResizeManager.java @@ -9,6 +9,7 @@ import android.widget.Scroller; import com.wefika.calendar.CollapseCalendarView; +import com.wefika.calendar.manager.ProgressManager.OnInitListener; /** * Created by Blaz Solar on 17/04/14. @@ -146,39 +147,45 @@ public boolean checkForResizing(MotionEvent ev) { // FIXME this method should on final int yDIff = calculateDistance(ev); - CalendarManager manager = mCalendarView.getManager(); - CalendarManager.State state = manager.getState(); - if (Math.abs(yDIff) > mTouchSlop) { // FIXME this should happen only if dragging int right direction mState = State.DRAGGING; mDragStartY = ev.getY(); - if (mProgressManager == null) { + startResizing(); - int weekOfMonth = manager.getWeekOfMonth(); + return true; + } - if (state == CalendarManager.State.WEEK) { // always animate in month view - manager.toggleView(); - mCalendarView.populateLayout(); - } + return false; + } - mProgressManager = new ProgressManagerImpl(mCalendarView, weekOfMonth, - state == CalendarManager.State.MONTH); + private void startResizing() { + + if (mProgressManager == null) { + + CalendarManager manager = mCalendarView.getManager(); + CalendarManager.State state = manager.getState(); + + int weekOfMonth = manager.getWeekOfMonth(); + + if (state == CalendarManager.State.WEEK) { // always animate in month view + manager.toggleView(); + mCalendarView.populateLayout(); } - return true; + mProgressManager = new ProgressManagerImpl(mCalendarView, weekOfMonth, + state == CalendarManager.State.MONTH); } - return false; } private void finishMotionEvent() { if (mProgressManager != null && mProgressManager.isInitialized()) { - startScolling(); + startScrolling(); } } - private void startScolling() { + private void startScrolling() { mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity); int velocity = (int) mVelocityTracker.getYVelocity(); @@ -239,6 +246,52 @@ public void onDraw() { } + public void toggle() { + + if (mProgressManager == null) { + startResizing(); + } + + if (!mScroller.isFinished()) { + mScroller.forceFinished(true); + } + + if (!mProgressManager.isInitialized()) { + mProgressManager.setListener(new OnInitListener() { + @Override public void onInit() { + testFinish(); + mProgressManager.setListener(null); + } + }); + } else { + testFinish(); + } + + + + } + + private void testFinish() { + + if (!mScroller.isFinished()) { + mScroller.forceFinished(true); + } + + int progress = mProgressManager.getCurrentHeight(); + int end = 0; + int endSize = mProgressManager.getEndSize(); + if (endSize / 2 > progress) { + end += endSize; + } + end -= progress; + + mScroller.startScroll(0, progress, 0, end); + mCalendarView.postInvalidate(); + + mState = State.SETTLING; + + } + private enum State { IDLE, DRAGGING, diff --git a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Week.java b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Week.java index 4752f27..74dae7c 100644 --- a/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Week.java +++ b/CollapseCalendarView/src/main/java/com/wefika/calendar/manager/Week.java @@ -48,6 +48,17 @@ public boolean hasPrev() { } } + @Override public boolean setPeriod(@NonNull LocalDate date) { + if (hasDate(date)) { + setFrom(date.withDayOfWeek(1)); + setTo(date.withDayOfWeek(7)); + build(); + return true; + } else { + return false; + } + } + @Override public boolean next() { if (hasNext()) { diff --git a/CollapseCalendarViewExample/src/main/java/com/wefika/calendar/example/MainActivity.java b/CollapseCalendarViewExample/src/main/java/com/wefika/calendar/example/MainActivity.java index 8776bb3..a48d944 100644 --- a/CollapseCalendarViewExample/src/main/java/com/wefika/calendar/example/MainActivity.java +++ b/CollapseCalendarViewExample/src/main/java/com/wefika/calendar/example/MainActivity.java @@ -2,13 +2,15 @@ import android.app.Activity; import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; import com.wefika.calendar.CollapseCalendarView; import com.wefika.calendar.manager.CalendarManager; import org.joda.time.LocalDate; -public class MainActivity extends Activity { +public class MainActivity extends Activity implements OnClickListener { private CollapseCalendarView mCalendarView; @@ -21,5 +23,24 @@ protected void onCreate(Bundle savedInstanceState) { mCalendarView = (CollapseCalendarView) findViewById(R.id.calendar); mCalendarView.init(manager); + + findViewById(R.id.next_month).setOnClickListener(this); + findViewById(R.id.toggle).setOnClickListener(this); + } + + @Override public void onClick(View v) { + switch (v.getId()) { + case R.id.next_month: + nextMonth(); + break; + case R.id.toggle: + mCalendarView.toggle(); + break; + } + } + + private void nextMonth() { + LocalDate nextMonth = mCalendarView.getManager().getSelectedDay().plusMonths(1); + mCalendarView.selectDate(nextMonth); } } diff --git a/CollapseCalendarViewExample/src/main/res/layout/activity_main.xml b/CollapseCalendarViewExample/src/main/res/layout/activity_main.xml index 348bc0e..50f428b 100644 --- a/CollapseCalendarViewExample/src/main/res/layout/activity_main.xml +++ b/CollapseCalendarViewExample/src/main/res/layout/activity_main.xml @@ -1,7 +1,8 @@ - - +