Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When endOfRow outDateStyle is used, once 6th row disappears, it never shows again #7

Closed
gajicm93 opened this issue Jun 4, 2019 · 12 comments

Comments

@gajicm93
Copy link

gajicm93 commented Jun 4, 2019

For example, if I'm in June, it has 6th row, and it shows, but once I move to July which only has 5 rows, and come back to June, June still only shows 5 rows, and final June days are obviously missing.

@gajicm93
Copy link
Author

gajicm93 commented Jun 4, 2019

Hmm it shows up again after I click on a day.

@kizitonwose
Copy link
Owner

Can you share the calendar setup which reproduces this issue? The calendar config in XML and initialization code should be sufficient.

@gajicm93
Copy link
Author

gajicm93 commented Jun 5, 2019

XML:

<com.kizitonwose.calendarview.CalendarView
android:id="@+id/calendar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calendar_month_year_text"
android:layout_marginTop="6dp"
app:cv_dayViewResource="@layout/item_calendar_day"
app:cv_monthHeaderResource="@layout/item_calendar_header"
app:cv_orientation="horizontal"
app:cv_outDateStyle="endOfRow"
app:cv_scrollMode="paged"/>

Kotlin:

`private var selectedDate: LocalDate? = null
private val monthTitleFormatter = DateTimeFormatter.ofPattern("MMMM")
private val cal by bind(R.id.calendar)
private val monthYear by bind(R.id.calendar_month_year_text)
private val back by bind(R.id.calendar_previous)
private val next by bind(R.id.calendar_next)

override fun bindView(itemView: View) {
    super.bindView(itemView)
    val daysOfWeek = daysOfWeekFromLocale()

    val currentMonth = YearMonth.now()
    cal.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first())
    cal.scrollToMonth(currentMonth)
    cal.dayBinder = this
    cal.monthScrollListener = this
    back.setOnClickListener(this)
    next.setOnClickListener(this)

    cal.monthHeaderBinder = object : MonthHeaderFooterBinder<MonthViewContainer> {
        override fun create(view: View) = MonthViewContainer(view)
        override fun bind(container: MonthViewContainer, month: CalendarMonth) {
            // Setup each header day text if we have not done that already.
            if (container.legendLayout.tag == null) {
                container.legendLayout.tag = month.yearMonth
                container.legendLayout.children.map { it as TextView }.forEachIndexed { index, tv ->
                    tv.text = daysOfWeek[index].name.take(1)
                }
            }
        }
    }
}

override fun create(view: View): DayViewContainer = DayViewContainer(view)

override fun bind(container: DayViewContainer, day: CalendarDay) {
    container.day = day
    container.view.text_calendar_day.text = day.date.dayOfMonth.toString()

    if (day.owner == DayOwner.THIS_MONTH) {
        container.view.text_calendar_day.setTextColorRes(R.color.silver_c8)
        container.view.layout_calendar_day.setBackgroundResource(if (selectedDate == day.date) R.drawable.background_circle else 0)
        container.view.dot_calendar_day.imageTintList = ColorStateList.valueOf(view.context.getColorCompat(R.color.silver_c8))
    } else {
        container.view.text_calendar_day.setTextColorRes(R.color.silver_c8_o35)
        container.view.layout_calendar_day.background = null
        container.view.dot_calendar_day.imageTintList = ColorStateList.valueOf(view.context.getColorCompat(R.color.silver_c8_o35))
    }
}

override fun invoke(month: CalendarMonth) {
    val title = "${monthTitleFormatter.format(month.yearMonth)} ${month.yearMonth.year}"
    monthYear.text = title

    selectedDate?.let {
        // Clear selection if we scroll to a new month.
        selectedDate = null
        cal.notifyDateChanged(it)
    }
}

override fun onClick(v: View) {
    when (v.id) {
        R.id.calendar_previous -> (cal.findFirstCompletelyVisibleMonth() ?: cal.findFirstVisibleMonth())?.let { cal.smoothScrollToMonth(it.previous.yearMonth) }
        R.id.calendar_next -> (cal.findFirstCompletelyVisibleMonth() ?: cal.findFirstVisibleMonth())?.let { cal.smoothScrollToMonth(it.next.yearMonth) }
    }
}

inner class MonthViewContainer(view: View) : ViewContainer(view) {
    val legendLayout = view.legendLayout
}

inner class DayViewContainer(view: View) : ViewContainer(view), View.OnClickListener {

    lateinit var day: CalendarDay // Will be set when this container is bound.

    init {
        view.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        if (day.owner == DayOwner.THIS_MONTH) {
            if (selectedDate != day.date) {
                val oldDate = selectedDate
                selectedDate = day.date
                cal.notifyDateChanged(day.date)
                oldDate?.let { cal.notifyDateChanged(it) }
            }
        }
    }
}`

@gajicm93
Copy link
Author

gajicm93 commented Jun 5, 2019

And as I said, click on a date makes it reappear, probably because of notifyDateChanged call.

@kizitonwose
Copy link
Owner

Could you please share @layout/item_calendar_day and @layout/item_calendar_header?

@gajicm93
Copy link
Author

gajicm93 commented Jun 7, 2019

item_calendar_day:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/layout_calendar_day"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_margin="1dp">

    <TextView
            android:id="@+id/text_calendar_day"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_gravity="center"
            tools:text="24"
            android:textSize="16sp"
            android:textColor="@color/silver_c8"
            android:letterSpacing="-0.01"/>

    <ImageView
            android:id="@+id/dot_calendar_day"
            android:src="@drawable/background_white_round"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="8dp"
            android:layout_width="4dp"
            android:layout_height="4dp"/>

</FrameLayout>

item_calendar_header:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/legendLayout"
              android:layout_width="match_parent"
              android:layout_height="20dp"
              android:gravity="center"
              android:background="#0cffffff"
              android:orientation="horizontal"
              tools:ignore="HardcodedText">

    <TextView
            android:id="@+id/legendText1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:includeFontPadding="false"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

    <TextView
            android:id="@+id/legendText7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="12sp"
            android:textColor="@color/silver_c8"/>

</LinearLayout>

@ghost
Copy link

ghost commented Jun 7, 2019

Same issue here

@kizitonwose
Copy link
Owner

This is now fixed in version 0.1.2
This was happening because ViewGroups clip their children by default, hence the last row which is outside the CalendarView's bounds is not drawn when the calendar moves from a month with 5 rows to one with 6 rows.

@ghost
Copy link

ghost commented Jun 9, 2019

@kizitonwose Thanks you for your fix!!
But now it takes time for the 6th row to appear in case we move from month with 5 rows.

@kizitonwose
Copy link
Owner

But now it takes time for the 6th row to appear in case we move from month with 5 rows.

This is because the CalendarView's height is set to wrap_content, hence, it has to adjust its height to match the current month when it moves to a new month. You should set the height to match_parent if you don't want this behavior.

@ghost
Copy link

ghost commented Jun 9, 2019

Maybe caching the last and next months will solve this issue?
@kizitonwose

@kizitonwose
Copy link
Owner

The months are cached. This is the expected behavior when a view wraps its content. If the calendar view does not resize, then months with 5 rows will show an empty last row.

See the screenshot below:

Screenshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants