From 4e3865936af30745c851722d6022c26bf1d52a2d Mon Sep 17 00:00:00 2001 From: Kizito Nwose Date: Sat, 11 Apr 2020 09:45:22 +0200 Subject: [PATCH] Force the calender height to match the current month's height in vertical, paged mode. --- library/build.gradle | 3 ++- .../kizitonwose/calendarview/CalendarView.kt | 13 ++++++++++ .../calendarview/ui/CalendarAdapter.kt | 24 ++++++++++++------- library/src/main/res/values/attrs.xml | 6 +++++ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index af7acb9c..69ca09ee 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -33,6 +33,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin_lang" + implementation "androidx.core:core-ktx:$versions.androidx_core_ktx" // Expose ThreeTenABP so library users can use it directly. api "com.jakewharton.threetenabp:threetenabp:$versions.threetenabp" @@ -50,7 +51,7 @@ dependencies { api "androidx.recyclerview:recyclerview:$versions.recyclerview" testImplementation "junit:junit:$versions.junit" - testImplementation('org.threeten:threetenbp:1.3.7') { + testImplementation('org.threeten:threetenbp:1.4.2') { // Use threetenBP library for tests as context will // not be available to initialise threetenABP exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' diff --git a/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt b/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt index a9385e19..cd0cbfdc 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt @@ -197,6 +197,15 @@ open class CalendarView : RecyclerView { } } + /** + * The duration in milliseconds of the animation used to adjust the CalendarView's + * height when [scrollMode] is [ScrollMode.PAGED] and the CalendarView's height is + * set to `wrap_content`. The height change happens when the CalendarView scrolls to + * a month which has less or more rows than the previous one. Default value is 200. + * To disable the animation, set this value to zero. + */ + var wrappedPageHeightAnimationDuration = 200 + private var startMonth: YearMonth? = null private var endMonth: YearMonth? = null private var firstDayOfWeek: DayOfWeek? = null @@ -233,6 +242,10 @@ open class CalendarView : RecyclerView { maxRowCount = a.getInt(R.styleable.CalendarView_cv_maxRowCount, maxRowCount) monthViewClass = a.getString(R.styleable.CalendarView_cv_monthViewClass) hasBoundaries = a.getBoolean(R.styleable.CalendarView_cv_hasBoundaries, hasBoundaries) + wrappedPageHeightAnimationDuration = a.getInt( + R.styleable.CalendarView_cv_wrappedPageHeightAnimationDuration, + wrappedPageHeightAnimationDuration + ) a.recycle() } diff --git a/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt b/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt index 78513d80..90e6e04b 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt @@ -1,5 +1,6 @@ package com.kizitonwose.calendarview.ui +import android.animation.ValueAnimator import android.content.Context import android.graphics.Rect import android.os.Build @@ -8,6 +9,7 @@ import android.view.ViewGroup import android.widget.LinearLayout import androidx.annotation.LayoutRes import androidx.core.view.ViewCompat +import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.RecyclerView import com.kizitonwose.calendarview.CalendarView import com.kizitonwose.calendarview.model.* @@ -164,6 +166,7 @@ internal class CalendarAdapter( private var visibleMonth: CalendarMonth? = null private var calWrapsHeight: Boolean? = null + private var initialLayout = true fun notifyMonthScrollListenerIfNeeded() { // Guard for cv.post() calls and other callbacks which use this method. if (!isAttached) return @@ -194,12 +197,14 @@ internal class CalendarAdapter( // calculating height and uses the tallest one of the three meaning that the current index's // view will end up having a blank space at the bottom unless the immediate previous and next // indices are also missing the last row. I think there should be a better way to fix this. - if (calView.isHorizontal && calView.scrollMode == ScrollMode.PAGED) { + // New: Also fixes issue where the calendar does not wrap each month's height when in vertical, + // paged mode and just matches parent's height instead. + if (calView.scrollMode == ScrollMode.PAGED) { val calWrapsHeight = calWrapsHeight ?: (calView.layoutParams.height == LP.WRAP_CONTENT).also { // We modify the layoutParams so we save the initial value set by the user. calWrapsHeight = it } - if (calWrapsHeight.not()) return // Bug only happens when the CalenderView wraps its height. + if (!calWrapsHeight) return // Bug only happens when the CalenderView wraps its height. val visibleVH = calView.findViewHolderForAdapterPosition(visibleItemPos) as? MonthViewHolder ?: return val newHeight = visibleVH.headerView?.height.orZero() + @@ -208,13 +213,16 @@ internal class CalendarAdapter( // by checking the number of visible(non-empty) rows. visibleMonth.weekDays.size * calView.dayHeight + visibleVH.footerView?.height.orZero() - if (calView.layoutParams.height != newHeight) { - calView.layoutParams = calView.layoutParams.apply { - this.height = newHeight - } - visibleVH.itemView.layoutParams = visibleVH.itemView.layoutParams.apply { - this.height = newHeight + if (calView.height != newHeight) { + ValueAnimator.ofInt(calView.height, newHeight).apply { + duration = if (initialLayout) 0 else calView.wrappedPageHeightAnimationDuration.toLong() + addUpdateListener { + calView.updateLayoutParams { height = it.animatedValue as Int } + visibleVH.itemView.requestLayout() + } + start() } + if (initialLayout) initialLayout = false } } } diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 91a4d929..79704cec 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -70,5 +70,11 @@ + + + \ No newline at end of file