How can i add month header to my calendar (kizitonwose)

620 Views Asked by At

I am using kizitonwose's CalendarView library and i made something with a guide on github. But now, i cant find a way to add a header to my calendar. My xml;

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Calendar">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent">

        <include
            android:id="@+id/monthHeaderContainer"
            layout="@layout/calendar_month_header_layout"/>

        <include
            android:id="@+id/titlesContainer"
            layout="@layout/calendar_day_titles_container" />

        <com.kizitonwose.calendar.view.CalendarView
            android:id="@+id/calendarView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cv_dayViewResource="@layout/calendar_day_layout"
            app:cv_monthHeaderResource="@layout/calendar_day_titles_container" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

As you see, i tried to add "calendar_month_header_layout" but i cant put it in app:cv_monthHeaderResource because i has added something different in it. This is my fragment file;

package com.ahmetkaan.kediy

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.children
import androidx.core.view.forEachIndexed
import com.ahmetkaan.kediy.databinding.CalendarDayLayoutBinding
import com.ahmetkaan.kediy.databinding.FragmentCalendarBinding
import com.kizitonwose.calendar.core.CalendarDay
import com.kizitonwose.calendar.core.CalendarMonth
import com.kizitonwose.calendar.core.DayPosition
import com.kizitonwose.calendar.view.MonthDayBinder
import com.kizitonwose.calendar.view.MonthHeaderFooterBinder
import com.kizitonwose.calendar.view.ViewContainer
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.YearMonth

class Calendar : Fragment() {

    private lateinit var binding: FragmentCalendarBinding
    private var selectedDate: LocalDate? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentCalendarBinding.inflate(layoutInflater, container, false)

        val currentMonth = YearMonth.now()
        val startMonth = currentMonth.minusMonths(100)
        val endMonth = currentMonth.plusMonths(100)
        val daysOfWeek = DayOfWeek.values()
        binding.calendarView.setup(startMonth, endMonth, daysOfWeek[0])
        binding.calendarView.scrollToMonth(currentMonth)

        class DayViewContainer(view: View) : ViewContainer(view) {
            val textView = CalendarDayLayoutBinding.bind(view).calendarDayText

            lateinit var day: CalendarDay

            init {
                view.setOnClickListener {
                    if (day.position == DayPosition.MonthDate) {
                        val currentSelection = selectedDate
                        if (currentSelection == day.date) {
                            selectedDate = null
                            binding.calendarView.notifyDateChanged(currentSelection)
                        } else {
                            selectedDate = day.date
                            binding.calendarView.notifyDateChanged(day.date)
                            if (currentSelection != null) {
                                binding.calendarView.notifyDateChanged(currentSelection)
                            }
                        }
                    }
                }
            }
        }

        binding.calendarView.dayBinder = object : MonthDayBinder<DayViewContainer> {
            override fun create(view: View) = DayViewContainer(view)
            override fun bind(container: DayViewContainer, data: CalendarDay) {
                container.day = data
                val day = data
                val textView = container.textView
                textView.text = day.date.dayOfMonth.toString()
                if (day.position == DayPosition.MonthDate) {
                    // Show the month dates. Remember that views are reused!
                    textView.visibility = View.VISIBLE
                    if (day.date == selectedDate) {
                        //textView.setTextColor(Color.WHITE)
                        textView.setBackgroundResource(R.drawable.selection_background)
                    } else {
                        //textView.setTextColor(Color.BLACK)
                        textView.background = null
                    }
                } else {
                    // Hide in and out dates
                    textView.visibility = View.INVISIBLE
                }
            }
        }

        class MonthViewContainer(view: View) : ViewContainer(view) {
            var titlesContianer = view as ViewGroup
        }

        binding.calendarView.monthHeaderBinder = object : MonthHeaderFooterBinder<MonthViewContainer> {
            override fun create(view: View) = MonthViewContainer(view)
            override fun bind(container: MonthViewContainer, data: CalendarMonth) {
                if (container.titlesContianer.tag == null) {
                    container.titlesContianer.tag = data.yearMonth
                    container.titlesContianer.children.map {it as TextView}.forEachIndexed { index, textView ->
                        val title = when (index) {
                            0 -> "Pzt"
                            1 -> "Sal"
                            2 -> "Çar"
                            3 -> "Per"
                            4 -> "Cum"
                            5 -> "Cmt"
                            6 -> "Paz"
                            else -> ""
                        }
                        textView.text = title
                    }
                }
            }
        }

        return binding.root
    }


}

As you see im using it to set weekdays's name compatible with my language. How can i add a month header (like April 2023 or in my language Nisan 2023) to my calendar view?

1

There are 1 best solutions below

0
Braian Silva On

Create a textView with the id of the month above <com.kizitonwose.calendar.view.CalendarView

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/monthText"
android:textStyle="bold"
android:paddingBottom="20dp"/>

and inside of binding.calendarView.dayBinder = object : MonthDayBinder<DayViewContainer> { do the binding

//bind month to textView
binding.monthText.text = data.date.month.toString()

data.date.month.toString() return the month and need bind to a text to show

The result will be like this below:

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/monthText"
android:textStyle="bold"
android:paddingBottom="20dp"/>    

<com.kizitonwose.calendar.view.WeekCalendarView
android:id="@+id/weekCalendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cv_dayViewResource="@layout/calendar_day_layout"
app:layout_constraintTop_toBottomOf="@id/day_date_picker"
app:cv_monthHeaderResource="@layout/calendar_month_header_layout"
app:cv_orientation="horizontal"
app:cv_outDateStyle="endOfRow"/>

enter image description here