Skip to content

Commit

Permalink
Force the calender height to match the current month's height in vert…
Browse files Browse the repository at this point in the history
…ical, paged mode.
  • Loading branch information
kizitonwose committed Apr 11, 2020
1 parent dd2b05a commit 4e38659
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 9 deletions.
3 changes: 2 additions & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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'
Expand Down
13 changes: 13 additions & 0 deletions library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() +
Expand All @@ -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
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions library/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,11 @@
<enum name="continuous" value="0" />
<enum name="paged" value="1" />
</attr>

<!-- The duration in milliseconds of the animation used to adjust the CalendarView's
height when `scrollMode` is `paged` and the CalendarView 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. -->
<attr name="cv_wrappedPageHeightAnimationDuration" format="integer" />
</declare-styleable>
</resources>

0 comments on commit 4e38659

Please sign in to comment.