From 058255c8e583e420c4a6fd9ba1dfebe9cffba79a Mon Sep 17 00:00:00 2001 From: Kizito Nwose Date: Sun, 7 Jun 2020 13:19:00 +0200 Subject: [PATCH 1/4] Update dependencies. --- build.gradle | 18 +++++++++--------- gradle/wrapper/gradle-wrapper.properties | 4 ++-- library/build.gradle | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 506ba472..24c736ea 100644 --- a/build.gradle +++ b/build.gradle @@ -6,20 +6,20 @@ buildscript { 'compile_sdk' : 28, 'version_code' : 1, 'version_name' : '0.3.1', - 'kotlin_lang' : '1.3.71', - 'material_library' : '1.1.0', + 'kotlin_lang' : '1.3.72', + 'material_library' : '1.2.0-beta01', 'androidx_appcompat' : '1.2.0-beta01', 'androidx_legacy' : '1.0.0', 'androidx_core_ktx' : '1.3.0-beta01', - 'constraint_layout' : '2.0.0-beta4', + 'constraint_layout' : '2.0.0-beta6', 'cardview' : '1.0.0', 'recyclerview' : '1.1.0', - 'threetenabp' : '1.2.3', + 'threetenabp' : '1.2.4', 'junit' : '4.12', - 'espresso' : '3.1.1', - 'androidx_test_runner': '1.1.1', - 'androidx_test_rules' : '1.1.1', - 'androidx_test_junit' : '1.1.0' + 'espresso' : '3.2.0', + 'androidx_test_runner': '1.2.0', + 'androidx_test_rules' : '1.2.0', + 'androidx_test_junit' : '1.1.1' ] repositories { google() @@ -27,7 +27,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.6.2' + classpath 'com.android.tools.build:gradle:4.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin_lang" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3f2df9aa..974d9d2a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Apr 05 08:20:22 CEST 2020 +#Sun Jun 07 13:13:35 CEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/library/build.gradle b/library/build.gradle index 69ca09ee..15c62315 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -51,7 +51,7 @@ dependencies { api "androidx.recyclerview:recyclerview:$versions.recyclerview" testImplementation "junit:junit:$versions.junit" - testImplementation('org.threeten:threetenbp:1.4.2') { + testImplementation('org.threeten:threetenbp:1.4.4') { // Use threetenBP library for tests as context will // not be available to initialise threetenABP exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' From c5741ef8fc11754cf5de5c9f29fa3330b587c3c4 Mon Sep 17 00:00:00 2001 From: Kizito Nwose Date: Sun, 7 Jun 2020 14:31:44 +0200 Subject: [PATCH 2/4] Replace kotlinx synthetic with ViewBinding in the example project. --- sample/build.gradle | 9 +- .../calenderviewsample/CalenderViewTests.kt | 32 +++-- .../calendarviewsample/BaseFragment.kt | 14 ++- .../calendarviewsample/CalendarViewApp.kt | 5 +- .../calendarviewsample/Example1Fragment.kt | 85 ++++++------- .../calendarviewsample/Example2Fragment.kt | 49 ++++---- .../calendarviewsample/Example3Fragment.kt | 89 +++++++------- .../calendarviewsample/Example4Fragment.kt | 115 +++++++++--------- .../calendarviewsample/Example5Fragment.kt | 101 ++++++++------- .../calendarviewsample/Example6Fragment.kt | 65 +++++----- .../calendarviewsample/Example7Fragment.kt | 61 ++++------ .../calendarviewsample/Extensions.kt | 11 +- .../calendarviewsample/HomeActivity.kt | 18 +-- .../calendarviewsample/HomeOptionsAdapter.kt | 33 ++--- .../kizitonwose/calendarviewsample/Utils.kt | 2 +- .../main/res/layout/example_1_fragment.xml | 1 + .../main/res/layout/example_2_fragment.xml | 1 + .../res/layout/example_3_calendar_header.xml | 4 +- .../main/res/layout/example_4_fragment.xml | 1 + .../res/layout/example_5_calendar_header.xml | 1 + .../res/layout/example_5_event_item_view.xml | 4 +- .../main/res/layout/example_5_fragment.xml | 4 +- .../res/layout/example_6_calendar_header.xml | 18 +-- 23 files changed, 351 insertions(+), 372 deletions(-) diff --git a/sample/build.gradle b/sample/build.gradle index 22af1cd2..3bef53f9 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,9 +1,6 @@ apply plugin: 'com.android.application' - apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' - android { compileSdkVersion versions.compile_sdk defaultConfig { @@ -14,6 +11,9 @@ android { versionName versions.version_name testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures { + viewBinding = true + } buildTypes { release { minifyEnabled false @@ -27,9 +27,6 @@ android { kotlinOptions { jvmTarget = "1.8" } - androidExtensions { - experimental true - } } dependencies { diff --git a/sample/src/androidTest/java/com/kizitonwose/calenderviewsample/CalenderViewTests.kt b/sample/src/androidTest/java/com/kizitonwose/calenderviewsample/CalenderViewTests.kt index 4939bfbb..30cc5535 100644 --- a/sample/src/androidTest/java/com/kizitonwose/calenderviewsample/CalenderViewTests.kt +++ b/sample/src/androidTest/java/com/kizitonwose/calenderviewsample/CalenderViewTests.kt @@ -2,6 +2,7 @@ package com.kizitonwose.calenderviewsample import android.graphics.Rect import android.view.View +import androidx.annotation.IdRes import androidx.fragment.app.Fragment import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView @@ -11,6 +12,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import androidx.test.rule.ActivityTestRule +import com.kizitonwose.calendarview.CalendarView import com.kizitonwose.calendarview.model.CalendarDay import com.kizitonwose.calendarview.model.CalendarMonth import com.kizitonwose.calendarview.model.DayOwner @@ -19,10 +21,6 @@ import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer import com.kizitonwose.calendarview.utils.yearMonth import com.kizitonwose.calendarviewsample.* -import kotlinx.android.synthetic.main.example_1_fragment.* -import kotlinx.android.synthetic.main.example_2_fragment.* -import kotlinx.android.synthetic.main.example_5_fragment.* -import kotlinx.android.synthetic.main.example_6_fragment.* import org.junit.After import org.junit.Assert.assertTrue import org.junit.Before @@ -53,7 +51,6 @@ class CalenderViewTests { @After fun teardown() { - } @Test @@ -62,7 +59,7 @@ class CalenderViewTests { class DayViewContainer(view: View) : ViewContainer(view) - val calendarView = findFragment(Example1Fragment::class.java).exOneCalendar + val calendarView = findFragment().findViewById(R.id.exOneCalendar) var boundDay: CalendarDay? = null @@ -97,7 +94,7 @@ class CalenderViewTests { class TestViewContainer(view: View) : ViewContainer(view) - val calendarView = findFragment(Example2Fragment::class.java).exTwoCalendar + val calendarView = findFragment().findViewById(R.id.exTwoCalendar) val boundDays = mutableSetOf() var boundHeaderMonth: CalendarMonth? = null @@ -137,7 +134,7 @@ class CalenderViewTests { fun programmaticScrollWorksAsExpected() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(4, click())) - val calendarView = findFragment(Example5Fragment::class.java).exFiveCalendar + val calendarView = findFragment().findViewById(R.id.exFiveCalendar) assertTrue(calendarView.findViewById(currentMonth.atDay(1).hashCode()) != null) @@ -153,12 +150,11 @@ class CalenderViewTests { assertTrue(calendarView.findViewById(nextFourMonths.atDay(1).hashCode()) != null) } - @Test fun scrollToDateWorksOnVerticalOrientation() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(1, click())) - val calendarView = findFragment(Example2Fragment::class.java).exTwoCalendar + val calendarView = findFragment().findViewById(R.id.exTwoCalendar) val targetDate = currentMonth.plusMonths(4).atDay(20) @@ -183,7 +179,7 @@ class CalenderViewTests { fun scrollToDateWorksOnHorizontalOrientation() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(5, click())) - val calendarView = findFragment(Example6Fragment::class.java).exSixCalendar + val calendarView = findFragment().findViewById(R.id.exSixCalendar) val targetDate = currentMonth.plusMonths(3).atDay(18) @@ -208,7 +204,7 @@ class CalenderViewTests { fun monthScrollListenerIsCalledWhenScrolled() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(0, click())) - val calendarView = findFragment(Example1Fragment::class.java).exOneCalendar + val calendarView = findFragment().findViewById(R.id.exOneCalendar) val targetMonth = currentMonth.plusMonths(2) @@ -230,7 +226,7 @@ class CalenderViewTests { fun findVisibleDaysAndMonthsWorksOnVerticalOrientation() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(1, click())) - val calendarView = findFragment(Example2Fragment::class.java).exTwoCalendar + val calendarView = findFragment().findViewById(R.id.exTwoCalendar) homeScreenRule.runOnUiThread { // Scroll to a random date @@ -256,7 +252,7 @@ class CalenderViewTests { fun findVisibleDaysAndMonthsWorksOnHorizontalOrientation() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(5, click())) - val calendarView = findFragment(Example6Fragment::class.java).exSixCalendar + val calendarView = findFragment().findViewById(R.id.exSixCalendar) homeScreenRule.runOnUiThread { // Scroll to a random date @@ -284,7 +280,7 @@ class CalenderViewTests { fun multipleSetupCallsRetainPositionIfCalendarHasBoundaries() { onView(withId(R.id.examplesRv)).perform(actionOnItemAtPosition(0, click())) - val calendarView = findFragment(Example1Fragment::class.java).exOneCalendar + val calendarView = findFragment().findViewById(R.id.exOneCalendar) val targetVisibleMonth = currentMonth.plusMonths(2) @@ -312,8 +308,10 @@ class CalenderViewTests { assertTrue(calendarView.findFirstVisibleMonth() == targetVisibleCalMonth) } - private fun findFragment(clazz: Class): T { + private inline fun findFragment(): T { return homeScreenRule.activity.supportFragmentManager - .findFragmentByTag(clazz.simpleName) as T + .findFragmentByTag(T::class.java.simpleName) as T } + + private fun Fragment.findViewById(@IdRes id: Int): T = requireView().findViewById(id) } diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/BaseFragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/BaseFragment.kt index e1a2500a..6e6ce9dd 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/BaseFragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/BaseFragment.kt @@ -1,10 +1,9 @@ package com.kizitonwose.calendarviewsample - +import androidx.annotation.LayoutRes import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.home_activity.* interface HasToolbar { val toolbar: Toolbar? // Return null to hide the toolbar @@ -12,12 +11,15 @@ interface HasToolbar { interface HasBackButton -abstract class BaseFragment : Fragment() { +abstract class BaseFragment(@LayoutRes layoutRes: Int) : Fragment(layoutRes) { + + val homeActivityToolbar: Toolbar + get() = (requireActivity() as HomeActivity).binding.homeToolbar override fun onStart() { super.onStart() if (this is HasToolbar) { - requireActivity().homeToolbar.makeGone() + homeActivityToolbar.makeGone() (requireActivity() as AppCompatActivity).setSupportActionBar(toolbar) } @@ -31,8 +33,8 @@ abstract class BaseFragment : Fragment() { override fun onStop() { super.onStop() if (this is HasToolbar) { - requireActivity().homeToolbar.makeVisible() - (requireActivity() as AppCompatActivity).setSupportActionBar(requireActivity().homeToolbar) + homeActivityToolbar.makeVisible() + (requireActivity() as AppCompatActivity).setSupportActionBar(homeActivityToolbar) } if (this is HasBackButton) { diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/CalendarViewApp.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/CalendarViewApp.kt index db1fba09..3a0f66dc 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/CalendarViewApp.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/CalendarViewApp.kt @@ -3,14 +3,11 @@ package com.kizitonwose.calendarviewsample import android.app.Application import com.jakewharton.threetenabp.AndroidThreeTen - class CalendarViewApp : Application() { override fun onCreate() { super.onCreate() - // Initialize ThreeTenABP library AndroidThreeTen.init(this) } - -} \ No newline at end of file +} diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example1Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example1Fragment.kt index a0685105..62d7fb3f 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example1Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example1Fragment.kt @@ -1,16 +1,14 @@ package com.kizitonwose.calendarviewsample - import android.animation.ValueAnimator import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.widget.Toolbar import androidx.core.animation.doOnEnd import androidx.core.animation.doOnStart import androidx.core.view.children +import androidx.core.view.updateLayoutParams import com.kizitonwose.calendarview.model.CalendarDay import com.kizitonwose.calendarview.model.DayOwner import com.kizitonwose.calendarview.model.InDateStyle @@ -18,26 +16,22 @@ import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.ViewContainer import com.kizitonwose.calendarview.utils.next import com.kizitonwose.calendarview.utils.yearMonth -import kotlinx.android.synthetic.main.calendar_day_legend.* -import kotlinx.android.synthetic.main.example_1_calendar_day.view.* -import kotlinx.android.synthetic.main.example_1_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example1CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example1FragmentBinding import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter import org.threeten.bp.format.TextStyle import java.util.* - -class Example1Fragment : BaseFragment(), HasToolbar { +class Example1Fragment : BaseFragment(R.layout.example_1_fragment), HasToolbar { override val toolbar: Toolbar? get() = null override val titleRes: Int = R.string.example_1_title - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.example_1_fragment, container, false) - } + private lateinit var binding: Example1FragmentBinding private val selectedDates = mutableSetOf() private val today = LocalDate.now() @@ -45,10 +39,9 @@ class Example1Fragment : BaseFragment(), HasToolbar { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - + binding = Example1FragmentBinding.bind(view) val daysOfWeek = daysOfWeekFromLocale() - legendLayout.children.forEachIndexed { index, view -> + binding.legendLayout.root.children.forEachIndexed { index, view -> (view as TextView).apply { text = daysOfWeek[index].getDisplayName(TextStyle.SHORT, Locale.ENGLISH).toUpperCase(Locale.ENGLISH) setTextColorRes(R.color.example_1_white_light) @@ -58,13 +51,13 @@ class Example1Fragment : BaseFragment(), HasToolbar { val currentMonth = YearMonth.now() val startMonth = currentMonth.minusMonths(10) val endMonth = currentMonth.plusMonths(10) - exOneCalendar.setup(startMonth, endMonth, daysOfWeek.first()) - exOneCalendar.scrollToMonth(currentMonth) + binding.exOneCalendar.setup(startMonth, endMonth, daysOfWeek.first()) + binding.exOneCalendar.scrollToMonth(currentMonth) class DayViewContainer(view: View) : ViewContainer(view) { // Will be set when this container is bound. See the dayBinder. lateinit var day: CalendarDay - val textView = view.exOneDayText + val textView = Example1CalendarDayBinding.bind(view).exOneDayText init { view.setOnClickListener { @@ -74,13 +67,13 @@ class Example1Fragment : BaseFragment(), HasToolbar { } else { selectedDates.add(day.date) } - exOneCalendar.notifyDayChanged(day) + binding.exOneCalendar.notifyDayChanged(day) } } } } - exOneCalendar.dayBinder = object : DayBinder { + binding.exOneCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { container.day = day @@ -91,7 +84,6 @@ class Example1Fragment : BaseFragment(), HasToolbar { selectedDates.contains(day.date) -> { textView.setTextColorRes(R.color.example_1_bg) textView.setBackgroundResource(R.drawable.example_1_selected_bg) - } today == day.date -> { textView.setTextColorRes(R.color.example_1_white) @@ -109,10 +101,10 @@ class Example1Fragment : BaseFragment(), HasToolbar { } } - exOneCalendar.monthScrollListener = { - if (exOneCalendar.maxRowCount == 6) { - exOneYearText.text = it.yearMonth.year.toString() - exOneMonthText.text = monthTitleFormatter.format(it.yearMonth) + binding.exOneCalendar.monthScrollListener = { + if (binding.exOneCalendar.maxRowCount == 6) { + binding.exOneYearText.text = it.yearMonth.year.toString() + binding.exOneMonthText.text = monthTitleFormatter.format(it.yearMonth) } else { // In week mode, we show the header a bit differently. // We show indices with dates from different months since @@ -121,26 +113,25 @@ class Example1Fragment : BaseFragment(), HasToolbar { val firstDate = it.weekDays.first().first().date val lastDate = it.weekDays.last().last().date if (firstDate.yearMonth == lastDate.yearMonth) { - exOneYearText.text = firstDate.yearMonth.year.toString() - exOneMonthText.text = monthTitleFormatter.format(firstDate) + binding.exOneYearText.text = firstDate.yearMonth.year.toString() + binding.exOneMonthText.text = monthTitleFormatter.format(firstDate) } else { - exOneMonthText.text = + binding.exOneMonthText.text = "${monthTitleFormatter.format(firstDate)} - ${monthTitleFormatter.format(lastDate)}" if (firstDate.year == lastDate.year) { - exOneYearText.text = firstDate.yearMonth.year.toString() + binding.exOneYearText.text = firstDate.yearMonth.year.toString() } else { - exOneYearText.text = "${firstDate.yearMonth.year} - ${lastDate.yearMonth.year}" + binding.exOneYearText.text = "${firstDate.yearMonth.year} - ${lastDate.yearMonth.year}" } } } - } - weekModeCheckBox.setOnCheckedChangeListener { _, monthToWeek -> - val firstDate = exOneCalendar.findFirstVisibleDay()?.date ?: return@setOnCheckedChangeListener - val lastDate = exOneCalendar.findLastVisibleDay()?.date ?: return@setOnCheckedChangeListener + binding.weekModeCheckBox.setOnCheckedChangeListener { _, monthToWeek -> + val firstDate = binding.exOneCalendar.findFirstVisibleDay()?.date ?: return@setOnCheckedChangeListener + val lastDate = binding.exOneCalendar.findLastVisibleDay()?.date ?: return@setOnCheckedChangeListener - val oneWeekHeight = exOneCalendar.dayHeight + val oneWeekHeight = binding.exOneCalendar.dayHeight val oneMonthHeight = oneWeekHeight * 6 val oldHeight = if (monthToWeek) oneMonthHeight else oneWeekHeight @@ -149,7 +140,7 @@ class Example1Fragment : BaseFragment(), HasToolbar { // Animate calendar height changes. val animator = ValueAnimator.ofInt(oldHeight, newHeight) animator.addUpdateListener { animator -> - exOneCalendar.layoutParams = exOneCalendar.layoutParams.apply { + binding.exOneCalendar.updateLayoutParams { height = animator.animatedValue as Int } } @@ -162,39 +153,42 @@ class Example1Fragment : BaseFragment(), HasToolbar { animator.doOnStart { if (!monthToWeek) { - exOneCalendar.inDateStyle = InDateStyle.ALL_MONTHS - exOneCalendar.maxRowCount = 6 - exOneCalendar.hasBoundaries = true + binding.exOneCalendar.apply { + inDateStyle = InDateStyle.ALL_MONTHS + maxRowCount = 6 + hasBoundaries = true + } } } animator.doOnEnd { if (monthToWeek) { - exOneCalendar.inDateStyle = InDateStyle.FIRST_MONTH - exOneCalendar.maxRowCount = 1 - exOneCalendar.hasBoundaries = false + binding.exOneCalendar.apply { + inDateStyle = InDateStyle.FIRST_MONTH + maxRowCount = 1 + hasBoundaries = false + } } if (monthToWeek) { // We want the first visible day to remain // visible when we change to week mode. - exOneCalendar.scrollToDate(firstDate) + binding.exOneCalendar.scrollToDate(firstDate) } else { // When changing to month mode, we choose current // month if it is the only one in the current frame. // if we have multiple months in one frame, we prefer // the second one unless it's an outDate in the last index. if (firstDate.yearMonth == lastDate.yearMonth) { - exOneCalendar.scrollToMonth(firstDate.yearMonth) + binding.exOneCalendar.scrollToMonth(firstDate.yearMonth) } else { // We compare the next with the last month on the calendar so we don't go over. - exOneCalendar.scrollToMonth(minOf(firstDate.yearMonth.next, endMonth)) + binding.exOneCalendar.scrollToMonth(minOf(firstDate.yearMonth.next, endMonth)) } } } animator.duration = 250 animator.start() } - } override fun onStart() { @@ -206,5 +200,4 @@ class Example1Fragment : BaseFragment(), HasToolbar { super.onStop() requireActivity().window.statusBarColor = requireContext().getColorCompat(R.color.colorPrimaryDark) } - } diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example2Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example2Fragment.kt index 9535606e..60a051ae 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example2Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example2Fragment.kt @@ -1,9 +1,11 @@ package com.kizitonwose.calendarviewsample - import android.annotation.SuppressLint import android.os.Bundle -import android.view.* +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View import android.widget.TextView import androidx.appcompat.widget.Toolbar import androidx.core.view.children @@ -14,66 +16,63 @@ import com.kizitonwose.calendarview.model.DayOwner import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer -import kotlinx.android.synthetic.main.calendar_day_legend.* -import kotlinx.android.synthetic.main.example_2_calendar_header.view.* -import kotlinx.android.synthetic.main.example_2_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example2CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example2CalendarHeaderBinding +import com.kizitonwose.calendarviewsample.databinding.Example2FragmentBinding import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter - -class Example2Fragment : BaseFragment(), HasToolbar, HasBackButton { +class Example2Fragment : BaseFragment(R.layout.example_2_fragment), HasToolbar, HasBackButton { override val toolbar: Toolbar? - get() = exTwoToolbar + get() = binding.exTwoToolbar override val titleRes: Int = R.string.example_2_title - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - setHasOptionsMenu(true) - return inflater.inflate(R.layout.example_2_fragment, container, false) - } + private lateinit var binding: Example2FragmentBinding private var selectedDate: LocalDate? = null private val today = LocalDate.now() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setHasOptionsMenu(true) + binding = Example2FragmentBinding.bind(view) val daysOfWeek = daysOfWeekFromLocale() - legendLayout.children.forEachIndexed { index, view -> + binding.legendLayout.root.children.forEachIndexed { index, view -> (view as TextView).apply { text = daysOfWeek[index].name.first().toString() setTextColorRes(R.color.example_2_white) } } - exTwoCalendar.setup(YearMonth.now(), YearMonth.now().plusMonths(10), daysOfWeek.first()) + binding.exTwoCalendar.setup(YearMonth.now(), YearMonth.now().plusMonths(10), daysOfWeek.first()) class DayViewContainer(view: View) : ViewContainer(view) { // Will be set when this container is bound. See the dayBinder. lateinit var day: CalendarDay + val textView = Example2CalendarDayBinding.bind(view).exTwoDayText - val textView = with(view) { - setOnClickListener { + init { + textView.setOnClickListener { if (day.owner == DayOwner.THIS_MONTH) { if (selectedDate == day.date) { selectedDate = null - exTwoCalendar.notifyDayChanged(day) + binding.exTwoCalendar.notifyDayChanged(day) } else { val oldDate = selectedDate selectedDate = day.date - exTwoCalendar.notifyDateChanged(day.date) - oldDate?.let { exTwoCalendar.notifyDateChanged(oldDate) } + binding.exTwoCalendar.notifyDateChanged(day.date) + oldDate?.let { binding.exTwoCalendar.notifyDateChanged(oldDate) } } menuItem.isVisible = selectedDate != null } } - return@with this as TextView } - } - exTwoCalendar.dayBinder = object : DayBinder { + + binding.exTwoCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { container.day = day @@ -103,9 +102,9 @@ class Example2Fragment : BaseFragment(), HasToolbar, HasBackButton { } class MonthViewContainer(view: View) : ViewContainer(view) { - val textView = view.exTwoHeaderText + val textView = Example2CalendarHeaderBinding.bind(view).exTwoHeaderText } - exTwoCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { + binding.exTwoCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { override fun create(view: View) = MonthViewContainer(view) override fun bind(container: MonthViewContainer, month: CalendarMonth) { @SuppressLint("SetTextI18n") // Concatenation warning for `setText` call. diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example3Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example3Fragment.kt index a0233264..e06eab42 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example3Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example3Fragment.kt @@ -1,9 +1,6 @@ package com.kizitonwose.calendarviewsample - -import android.content.Context import android.os.Bundle -import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT @@ -13,7 +10,6 @@ import android.widget.FrameLayout import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.AppCompatEditText import androidx.core.view.children import androidx.core.view.isVisible @@ -26,20 +22,15 @@ import com.kizitonwose.calendarview.model.DayOwner import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.calendar_day_legend.view.* -import kotlinx.android.synthetic.main.example_3_calendar_day.view.* -import kotlinx.android.synthetic.main.example_3_event_item_view.* -import kotlinx.android.synthetic.main.example_3_fragment.* -import kotlinx.android.synthetic.main.home_activity.* +import com.kizitonwose.calendarviewsample.databinding.Example3CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example3CalendarHeaderBinding +import com.kizitonwose.calendarviewsample.databinding.Example3EventItemViewBinding +import com.kizitonwose.calendarviewsample.databinding.Example3FragmentBinding import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter import java.util.* -private val Context.inputMethodManager - get() = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - data class Event(val id: String, val text: String, val date: LocalDate) class Example3EventsAdapter(val onClick: (Event) -> Unit) : @@ -48,7 +39,9 @@ class Example3EventsAdapter(val onClick: (Event) -> Unit) : val events = mutableListOf() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Example3EventsViewHolder { - return Example3EventsViewHolder(parent.inflate(R.layout.example_3_event_item_view)) + return Example3EventsViewHolder( + Example3EventItemViewBinding.inflate(parent.context.layoutInflater, parent, false) + ) } override fun onBindViewHolder(viewHolder: Example3EventsViewHolder, position: Int) { @@ -57,8 +50,8 @@ class Example3EventsAdapter(val onClick: (Event) -> Unit) : override fun getItemCount(): Int = events.size - inner class Example3EventsViewHolder(override val containerView: View) : - RecyclerView.ViewHolder(containerView), LayoutContainer { + inner class Example3EventsViewHolder(private val binding: Example3EventItemViewBinding) : + RecyclerView.ViewHolder(binding.root) { init { itemView.setOnClickListener { @@ -67,13 +60,12 @@ class Example3EventsAdapter(val onClick: (Event) -> Unit) : } fun bind(event: Event) { - itemEventText.text = event.text + binding.itemEventText.text = event.text } } - } -class Example3Fragment : BaseFragment(), HasBackButton { +class Example3Fragment : BaseFragment(R.layout.example_3_fragment), HasBackButton { private val eventsAdapter = Example3EventsAdapter { AlertDialog.Builder(requireContext()) @@ -127,24 +119,26 @@ class Example3Fragment : BaseFragment(), HasBackButton { private val selectionFormatter = DateTimeFormatter.ofPattern("d MMM yyyy") private val events = mutableMapOf>() - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.example_3_fragment, container, false) - } + private lateinit var binding: Example3FragmentBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - exThreeRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) - exThreeRv.adapter = eventsAdapter - exThreeRv.addItemDecoration(DividerItemDecoration(requireContext(), RecyclerView.VERTICAL)) + binding = Example3FragmentBinding.bind(view) + binding.exThreeRv.apply { + layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) + adapter = eventsAdapter + addItemDecoration(DividerItemDecoration(requireContext(), RecyclerView.VERTICAL)) + } val daysOfWeek = daysOfWeekFromLocale() val currentMonth = YearMonth.now() - exThreeCalendar.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first()) - exThreeCalendar.scrollToMonth(currentMonth) + binding.exThreeCalendar.apply { + setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first()) + scrollToMonth(currentMonth) + } if (savedInstanceState == null) { - exThreeCalendar.post { + binding.exThreeCalendar.post { // Show today's events initially. selectDate(today) } @@ -152,8 +146,7 @@ class Example3Fragment : BaseFragment(), HasBackButton { class DayViewContainer(view: View) : ViewContainer(view) { lateinit var day: CalendarDay // Will be set when this container is bound. - val textView = view.exThreeDayText - val dotView = view.exThreeDotView + val binding = Example3CalendarDayBinding.bind(view) init { view.setOnClickListener { @@ -163,12 +156,12 @@ class Example3Fragment : BaseFragment(), HasBackButton { } } } - exThreeCalendar.dayBinder = object : DayBinder { + binding.exThreeCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { container.day = day - val textView = container.textView - val dotView = container.dotView + val textView = container.binding.exThreeDayText + val dotView = container.binding.exThreeDotView textView.text = day.date.dayOfMonth.toString() @@ -198,8 +191,8 @@ class Example3Fragment : BaseFragment(), HasBackButton { } } - exThreeCalendar.monthScrollListener = { - requireActivity().homeToolbar.title = if (it.year == today.year) { + binding.exThreeCalendar.monthScrollListener = { + homeActivityToolbar.title = if (it.year == today.year) { titleSameYearFormatter.format(it.yearMonth) } else { titleFormatter.format(it.yearMonth) @@ -211,9 +204,9 @@ class Example3Fragment : BaseFragment(), HasBackButton { } class MonthViewContainer(view: View) : ViewContainer(view) { - val legendLayout = view.legendLayout + val legendLayout = Example3CalendarHeaderBinding.bind(view).legendLayout.root } - exThreeCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { + binding.exThreeCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { 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. @@ -227,7 +220,7 @@ class Example3Fragment : BaseFragment(), HasBackButton { } } - exThreeAddButton.setOnClickListener { + binding.exThreeAddButton.setOnClickListener { inputDialog.show() } } @@ -236,8 +229,8 @@ class Example3Fragment : BaseFragment(), HasBackButton { if (selectedDate != date) { val oldDate = selectedDate selectedDate = date - oldDate?.let { exThreeCalendar.notifyDateChanged(it) } - exThreeCalendar.notifyDateChanged(date) + oldDate?.let { binding.exThreeCalendar.notifyDateChanged(it) } + binding.exThreeCalendar.notifyDateChanged(date) updateAdapterForDate(date) } } @@ -260,21 +253,23 @@ class Example3Fragment : BaseFragment(), HasBackButton { } private fun updateAdapterForDate(date: LocalDate) { - eventsAdapter.events.clear() - eventsAdapter.events.addAll(events[date].orEmpty()) - eventsAdapter.notifyDataSetChanged() - exThreeSelectedDateText.text = selectionFormatter.format(date) + eventsAdapter.apply { + events.clear() + events.addAll(this@Example3Fragment.events[date].orEmpty()) + notifyDataSetChanged() + } + binding.exThreeSelectedDateText.text = selectionFormatter.format(date) } override fun onStart() { super.onStart() - (activity as AppCompatActivity).homeToolbar.setBackgroundColor(requireContext().getColorCompat(R.color.example_3_toolbar_color)) + homeActivityToolbar.setBackgroundColor(requireContext().getColorCompat(R.color.example_3_toolbar_color)) requireActivity().window.statusBarColor = requireContext().getColorCompat(R.color.example_3_statusbar_color) } override fun onStop() { super.onStop() - (activity as AppCompatActivity).homeToolbar.setBackgroundColor(requireContext().getColorCompat(R.color.colorPrimary)) + homeActivityToolbar.setBackgroundColor(requireContext().getColorCompat(R.color.colorPrimary)) requireActivity().window.statusBarColor = requireContext().getColorCompat(R.color.colorPrimaryDark) } } diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example4Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example4Fragment.kt index 1e448ab5..22f22638 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example4Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example4Fragment.kt @@ -1,13 +1,14 @@ package com.kizitonwose.calendarviewsample - import android.graphics.Color import android.graphics.PorterDuff import android.graphics.drawable.GradientDrawable import android.os.Build import android.os.Bundle import android.util.TypedValue -import android.view.* +import android.view.Menu +import android.view.MenuInflater +import android.view.View import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -19,20 +20,19 @@ import com.kizitonwose.calendarview.model.DayOwner import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer -import kotlinx.android.synthetic.main.calendar_day_legend.* -import kotlinx.android.synthetic.main.example_4_calendar_day.view.* -import kotlinx.android.synthetic.main.example_4_calendar_header.view.* -import kotlinx.android.synthetic.main.example_4_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example4CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example4CalendarHeaderBinding +import com.kizitonwose.calendarviewsample.databinding.Example4FragmentBinding import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter import org.threeten.bp.format.TextStyle import java.util.* -class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { +class Example4Fragment : BaseFragment(R.layout.example_4_fragment), HasToolbar, HasBackButton { override val toolbar: Toolbar? - get() = exFourToolbar + get() = binding.exFourToolbar override val titleRes: Int? = null @@ -51,26 +51,24 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { requireContext().getDrawableCompat(R.drawable.example_4_continuous_selected_bg_end) as GradientDrawable } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - setHasOptionsMenu(true) - return inflater.inflate(R.layout.example_4_fragment, container, false) - } + private lateinit var binding: Example4FragmentBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setHasOptionsMenu(true) + binding = Example4FragmentBinding.bind(view) // We set the radius of the continuous selection background drawable dynamically // since the view size is `match parent` hence we cannot determine the appropriate // radius value which would equal half of the view's size beforehand. - exFourCalendar.post { - val radius = ((exFourCalendar.width / 7) / 2).toFloat() + binding.exFourCalendar.post { + val radius = ((binding.exFourCalendar.width / 7) / 2).toFloat() startBackground.setCornerRadius(topLeft = radius, bottomLeft = radius) endBackground.setCornerRadius(topRight = radius, bottomRight = radius) } // Set the First day of week depending on Locale val daysOfWeek = daysOfWeekFromLocale() - legendLayout.children.forEachIndexed { index, view -> + binding.legendLayout.root.children.forEachIndexed { index, view -> (view as TextView).apply { text = daysOfWeek[index].getDisplayName(TextStyle.SHORT, Locale.ENGLISH) setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f) @@ -79,13 +77,12 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { } val currentMonth = YearMonth.now() - exFourCalendar.setup(currentMonth, currentMonth.plusMonths(12), daysOfWeek.first()) - exFourCalendar.scrollToMonth(currentMonth) + binding.exFourCalendar.setup(currentMonth, currentMonth.plusMonths(12), daysOfWeek.first()) + binding.exFourCalendar.scrollToMonth(currentMonth) class DayViewContainer(view: View) : ViewContainer(view) { lateinit var day: CalendarDay // Will be set when this container is bound. - val textView = view.exFourDayText - val roundBgView = view.exFourRoundBgView + val binding = Example4CalendarDayBinding.bind(view) init { view.setOnClickListener { @@ -101,18 +98,19 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { } else { startDate = date } - exFourCalendar.notifyCalendarChanged() + this@Example4Fragment.binding.exFourCalendar.notifyCalendarChanged() bindSummaryViews() } } } } - exFourCalendar.dayBinder = object : DayBinder { + + binding.exFourCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { container.day = day - val textView = container.textView - val roundBgView = container.roundBgView + val textView = container.binding.exFourDayText + val roundBgView = container.binding.exFourRoundBgView textView.text = null textView.background = null @@ -162,21 +160,21 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { // Mimic selection of inDates that are less than the startDate. // Example: When 26 Feb 2019 is startDate and 5 Mar 2019 is endDate, // this makes the inDates in Mar 2019 for 24 & 25 Feb 2019 look selected. - if ((day.owner == DayOwner.PREVIOUS_MONTH - && startDate.monthValue == day.date.monthValue - && endDate.monthValue != day.date.monthValue) || + if ((day.owner == DayOwner.PREVIOUS_MONTH && + startDate.monthValue == day.date.monthValue && + endDate.monthValue != day.date.monthValue) || // Mimic selection of outDates that are greater than the endDate. // Example: When 25 Apr 2019 is startDate and 2 May 2019 is endDate, // this makes the outDates in Apr 2019 for 3 & 4 May 2019 look selected. - (day.owner == DayOwner.NEXT_MONTH - && startDate.monthValue != day.date.monthValue - && endDate.monthValue == day.date.monthValue) || + (day.owner == DayOwner.NEXT_MONTH && + startDate.monthValue != day.date.monthValue && + endDate.monthValue == day.date.monthValue) || // Mimic selection of in and out dates of intermediate // months if the selection spans across multiple months. - (startDate < day.date && endDate > day.date - && startDate.monthValue != day.date.monthValue - && endDate.monthValue != day.date.monthValue) + (startDate < day.date && endDate > day.date && + startDate.monthValue != day.date.monthValue && + endDate.monthValue != day.date.monthValue) ) { textView.setBackgroundResource(R.drawable.example_4_continuous_selected_bg_middle) } @@ -186,9 +184,9 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { } class MonthViewContainer(view: View) : ViewContainer(view) { - val textView = view.exFourHeaderText + val textView = Example4CalendarHeaderBinding.bind(view).exFourHeaderText } - exFourCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { + binding.exFourCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { override fun create(view: View) = MonthViewContainer(view) override fun bind(container: MonthViewContainer, month: CalendarMonth) { val monthTitle = "${month.yearMonth.month.name.toLowerCase().capitalize()} ${month.year}" @@ -196,7 +194,7 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { } } - exFourSaveButton.setOnClickListener click@{ + binding.exFourSaveButton.setOnClickListener click@{ val startDate = startDate val endDate = endDate if (startDate != null && endDate != null) { @@ -214,46 +212,47 @@ class Example4Fragment : BaseFragment(), HasToolbar, HasBackButton { } private fun bindSummaryViews() { - if (startDate != null) { - exFourStartDateText.text = headerDateFormatter.format(startDate) - exFourStartDateText.setTextColorRes(R.color.example_4_grey) - } else { - exFourStartDateText.text = getString(R.string.start_date) - exFourStartDateText.setTextColor(Color.GRAY) + binding.exFourStartDateText.apply { + if (startDate != null) { + text = headerDateFormatter.format(startDate) + setTextColorRes(R.color.example_4_grey) + } else { + text = getString(R.string.start_date) + setTextColor(Color.GRAY) + } } - if (endDate != null) { - exFourEndDateText.text = headerDateFormatter.format(endDate) - exFourEndDateText.setTextColorRes(R.color.example_4_grey) - } else { - exFourEndDateText.text = getString(R.string.end_date) - exFourEndDateText.setTextColor(Color.GRAY) + + binding.exFourEndDateText.apply { + if (endDate != null) { + text = headerDateFormatter.format(endDate) + setTextColorRes(R.color.example_4_grey) + } else { + text = getString(R.string.end_date) + setTextColor(Color.GRAY) + } } // Enable save button if a range is selected or no date is selected at all, Airbnb style. - exFourSaveButton.isEnabled = endDate != null || (startDate == null && endDate == null) + binding.exFourSaveButton.isEnabled = endDate != null || (startDate == null && endDate == null) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.example_4_menu, menu) - exFourToolbar.post { + binding.exFourToolbar.post { // Configure menu text to match what is in the Airbnb app. - exFourToolbar.findViewById(R.id.menuItemClear).apply { + binding.exFourToolbar.findViewById(R.id.menuItemClear).apply { setTextColor(requireContext().getColorCompat(R.color.example_4_grey)) setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f) isAllCaps = false } } - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == R.id.menuItemClear) { + menu.findItem(R.id.menuItemClear).setOnMenuItemClickListener { startDate = null endDate = null - exFourCalendar.notifyCalendarChanged() + binding.exFourCalendar.notifyCalendarChanged() bindSummaryViews() - return true + true } - return super.onOptionsItemSelected(item) } override fun onStart() { diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example5Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example5Fragment.kt index bb75fa41..31cb17b6 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example5Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example5Fragment.kt @@ -1,9 +1,7 @@ package com.kizitonwose.calendarviewsample - import android.os.Bundle import android.util.TypedValue -import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView @@ -21,11 +19,10 @@ import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer import com.kizitonwose.calendarview.utils.next import com.kizitonwose.calendarview.utils.previous -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.calendar_day_legend.view.* -import kotlinx.android.synthetic.main.example_5_calendar_day.view.* -import kotlinx.android.synthetic.main.example_5_event_item_view.* -import kotlinx.android.synthetic.main.example_5_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example5CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example5CalendarHeaderBinding +import com.kizitonwose.calendarviewsample.databinding.Example5EventItemViewBinding +import com.kizitonwose.calendarviewsample.databinding.Example5FragmentBinding import org.threeten.bp.LocalDate import org.threeten.bp.LocalDateTime import org.threeten.bp.YearMonth @@ -33,7 +30,6 @@ import org.threeten.bp.format.DateTimeFormatter import org.threeten.bp.format.TextStyle import java.util.* - data class Flight(val time: LocalDateTime, val departure: Airport, val destination: Airport, @ColorRes val color: Int) { data class Airport(val city: String, val code: String) } @@ -45,7 +41,9 @@ class Example5FlightsAdapter : RecyclerView.Adapter { + binding.exFiveCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { container.day = day - val textView = container.textView - val layout = container.layout + val textView = container.binding.exFiveDayText + val layout = container.binding.exFiveDayLayout textView.text = day.date.dayOfMonth.toString() - val flightTopView = container.flightTopView - val flightBottomView = container.flightBottomView - + val flightTopView = container.binding.exFiveDayFlightTop + val flightBottomView = container.binding.exFiveDayFlightBottom flightTopView.background = null flightBottomView.background = null @@ -158,9 +154,9 @@ class Example5Fragment : BaseFragment(), HasToolbar { } class MonthViewContainer(view: View) : ViewContainer(view) { - val legendLayout = view.legendLayout + val legendLayout = Example5CalendarHeaderBinding.bind(view).legendLayout.root } - exFiveCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { + binding.exFiveCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { 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. @@ -177,27 +173,27 @@ class Example5Fragment : BaseFragment(), HasToolbar { } } - exFiveCalendar.monthScrollListener = { month -> + binding.exFiveCalendar.monthScrollListener = { month -> val title = "${monthTitleFormatter.format(month.yearMonth)} ${month.yearMonth.year}" - exFiveMonthYearText.text = title + binding.exFiveMonthYearText.text = title selectedDate?.let { // Clear selection if we scroll to a new month. selectedDate = null - exFiveCalendar.notifyDateChanged(it) + binding.exFiveCalendar.notifyDateChanged(it) updateAdapterForDate(null) } } - exFiveNextMonthImage.setOnClickListener { - exFiveCalendar.findFirstVisibleMonth()?.let { - exFiveCalendar.smoothScrollToMonth(it.yearMonth.next) + binding.exFiveNextMonthImage.setOnClickListener { + binding.exFiveCalendar.findFirstVisibleMonth()?.let { + binding.exFiveCalendar.smoothScrollToMonth(it.yearMonth.next) } } - exFivePreviousMonthImage.setOnClickListener { - exFiveCalendar.findFirstVisibleMonth()?.let { - exFiveCalendar.smoothScrollToMonth(it.yearMonth.previous) + binding.exFivePreviousMonthImage.setOnClickListener { + binding.exFiveCalendar.findFirstVisibleMonth()?.let { + binding.exFiveCalendar.smoothScrollToMonth(it.yearMonth.previous) } } } @@ -217,5 +213,4 @@ class Example5Fragment : BaseFragment(), HasToolbar { flightsAdapter.flights.addAll(flights[date].orEmpty()) flightsAdapter.notifyDataSetChanged() } - } diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example6Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example6Fragment.kt index e47b9f60..88a96624 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example6Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example6Fragment.kt @@ -1,13 +1,10 @@ package com.kizitonwose.calendarviewsample - import android.content.Context import android.os.Bundle import android.util.DisplayMetrics import android.util.TypedValue -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.view.WindowManager import android.widget.TextView import androidx.cardview.widget.CardView @@ -18,10 +15,9 @@ import com.kizitonwose.calendarview.model.DayOwner import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.MonthHeaderFooterBinder import com.kizitonwose.calendarview.ui.ViewContainer -import kotlinx.android.synthetic.main.calendar_day_legend.view.* -import kotlinx.android.synthetic.main.example_6_calendar_day.view.* -import kotlinx.android.synthetic.main.example_6_calendar_header.view.* -import kotlinx.android.synthetic.main.example_6_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example6CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example6CalendarHeaderBinding +import com.kizitonwose.calendarviewsample.databinding.Example6FragmentBinding import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter @@ -36,46 +32,42 @@ class Example6MonthView(context: Context) : CardView(context) { } } - -class Example6Fragment : BaseFragment(), HasBackButton { +class Example6Fragment : BaseFragment(R.layout.example_6_fragment), HasBackButton { override val titleRes: Int = R.string.example_6_title private val titleFormatter = DateTimeFormatter.ofPattern("MMM yyyy") - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.example_6_fragment, container, false) - } + private lateinit var binding: Example6FragmentBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + binding = Example6FragmentBinding.bind(view) // Setup custom day size to fit two months on the screen. val dm = DisplayMetrics() val wm = requireContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager wm.defaultDisplay.getMetrics(dm) - // We want the immediately following/previous month to be - // partially visible so we multiply the total width by 0.73 - val monthWidth = (dm.widthPixels * 0.73).toInt() - val dayWidth = monthWidth / 7 - exSixCalendar.dayWidth = dayWidth - - // We don't want a square calendar. - exSixCalendar.dayHeight = (dayWidth * 1.73).toInt() - - // Add margins around our card view. - val horizontalMargin = dpToPx(8, requireContext()) - val verticalMargin = dpToPx(14, requireContext()) - exSixCalendar.monthMarginStart = horizontalMargin - exSixCalendar.monthMarginEnd = horizontalMargin - exSixCalendar.monthMarginTop = verticalMargin - exSixCalendar.monthMarginBottom = verticalMargin + binding.exSixCalendar.apply { + // We want the immediately following/previous month to be + // partially visible so we multiply the total width by 0.73 + val monthWidth = (dm.widthPixels * 0.73).toInt() + dayWidth = monthWidth / 7 + dayHeight = (dayWidth * 1.73).toInt() // We don't want a square calendar. + + // Add margins around our card view. + val horizontalMargin = dpToPx(8, requireContext()) + val verticalMargin = dpToPx(14, requireContext()) + monthMarginStart = horizontalMargin + monthMarginEnd = horizontalMargin + monthMarginTop = verticalMargin + monthMarginBottom = verticalMargin + } class DayViewContainer(view: View) : ViewContainer(view) { - val textView = view.exSixDayText + val textView = Example6CalendarDayBinding.bind(view).exSixDayText } - exSixCalendar.dayBinder = object : DayBinder { + binding.exSixCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) { val textView = container.textView @@ -91,14 +83,15 @@ class Example6Fragment : BaseFragment(), HasBackButton { val daysOfWeek = daysOfWeekFromLocale() val currentMonth = YearMonth.now() - exSixCalendar.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first()) - exSixCalendar.scrollToMonth(currentMonth) + binding.exSixCalendar.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first()) + binding.exSixCalendar.scrollToMonth(currentMonth) class MonthViewContainer(view: View) : ViewContainer(view) { - val textView = view.exSixMonthText - val legendLayout = view.legendLayout + val binding = Example6CalendarHeaderBinding.bind(view) + val textView = binding.exSixMonthText + val legendLayout = binding.legendLayout.root } - exSixCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { + binding.exSixCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder { override fun create(view: View) = MonthViewContainer(view) override fun bind(container: MonthViewContainer, month: CalendarMonth) { container.textView.text = titleFormatter.format(month.yearMonth) diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example7Fragment.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example7Fragment.kt index af181dd3..1cf19861 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Example7Fragment.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Example7Fragment.kt @@ -1,77 +1,68 @@ package com.kizitonwose.calendarviewsample - import android.content.Context import android.os.Bundle import android.util.DisplayMetrics -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.view.WindowManager import androidx.appcompat.widget.Toolbar import androidx.core.view.isVisible import com.kizitonwose.calendarview.model.CalendarDay import com.kizitonwose.calendarview.ui.DayBinder import com.kizitonwose.calendarview.ui.ViewContainer -import kotlinx.android.synthetic.main.example_7_calendar_day.view.* -import kotlinx.android.synthetic.main.example_7_fragment.* +import com.kizitonwose.calendarviewsample.databinding.Example7CalendarDayBinding +import com.kizitonwose.calendarviewsample.databinding.Example7FragmentBinding import org.threeten.bp.DayOfWeek import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import org.threeten.bp.format.DateTimeFormatter - -class Example7Fragment : BaseFragment(), HasToolbar, HasBackButton { +class Example7Fragment : BaseFragment(R.layout.example_7_fragment), HasToolbar, HasBackButton { override val titleRes: Int = R.string.example_7_title override val toolbar: Toolbar? - get() = exSevenToolbar + get() = binding.exSevenToolbar - private var selectedDate: LocalDate? = null + private var selectedDate = LocalDate.now() private val dateFormatter = DateTimeFormatter.ofPattern("dd") private val dayFormatter = DateTimeFormatter.ofPattern("EEE") private val monthFormatter = DateTimeFormatter.ofPattern("MMM") - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.example_7_fragment, container, false) - } + private lateinit var binding: Example7FragmentBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding = Example7FragmentBinding.bind(view) val dm = DisplayMetrics() val wm = requireContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager wm.defaultDisplay.getMetrics(dm) - - exSevenCalendar.dayWidth = dm.widthPixels / 5 - - exSevenCalendar.dayHeight = (exSevenCalendar.dayWidth * 1.25).toInt() + binding.exSevenCalendar.apply { + dayWidth = dm.widthPixels / 5 + dayHeight = (dayWidth * 1.25).toInt() + } class DayViewContainer(view: View) : ViewContainer(view) { - val dayText = view.exSevenDayText - val dateText = view.exSevenDateText - val monthText = view.exSevenMonthText - val selectedView = view.exSevenSelectedView - + val bind = Example7CalendarDayBinding.bind(view) lateinit var day: CalendarDay init { view.setOnClickListener { - val firstDay = exSevenCalendar.findFirstVisibleDay() - val lastDay = exSevenCalendar.findLastVisibleDay() + val firstDay = binding.exSevenCalendar.findFirstVisibleDay() + val lastDay = binding.exSevenCalendar.findLastVisibleDay() if (firstDay == day) { // If the first date on screen was clicked, we scroll to the date to ensure // it is fully visible if it was partially off the screen when clicked. - exSevenCalendar.smoothScrollToDate(day.date) + binding.exSevenCalendar.smoothScrollToDate(day.date) } else if (lastDay == day) { // If the last date was clicked, we scroll to 4 days ago, this forces the // clicked date to be fully visible if it was partially off the screen. // We scroll to 4 days ago because we show max of five days on the screen // so scrolling to 4 days ago brings the clicked date into full visibility // at the end of the calendar view. - exSevenCalendar.smoothScrollToDate(day.date.minusDays(4)) + binding.exSevenCalendar.smoothScrollToDate(day.date.minusDays(4)) } // Example: If you want the clicked date to always be centered on the screen, @@ -80,31 +71,31 @@ class Example7Fragment : BaseFragment(), HasToolbar, HasBackButton { if (selectedDate != day.date) { val oldDate = selectedDate selectedDate = day.date - exSevenCalendar.notifyDateChanged(day.date) - oldDate?.let { exSevenCalendar.notifyDateChanged(it) } + binding.exSevenCalendar.notifyDateChanged(day.date) + oldDate?.let { binding.exSevenCalendar.notifyDateChanged(it) } } } } fun bind(day: CalendarDay) { this.day = day - dateText.text = dateFormatter.format(day.date) - dayText.text = dayFormatter.format(day.date) - monthText.text = monthFormatter.format(day.date) + bind.exSevenDateText.text = dateFormatter.format(day.date) + bind.exSevenDayText.text = dayFormatter.format(day.date) + bind.exSevenMonthText.text = monthFormatter.format(day.date) - dateText.setTextColor(view.context.getColorCompat(if (day.date == selectedDate) R.color.example_7_yellow else R.color.example_7_white)) - selectedView.isVisible = day.date == selectedDate + bind.exSevenDateText.setTextColor(view.context.getColorCompat(if (day.date == selectedDate) R.color.example_7_yellow else R.color.example_7_white)) + bind.exSevenSelectedView.isVisible = day.date == selectedDate } } - exSevenCalendar.dayBinder = object : DayBinder { + binding.exSevenCalendar.dayBinder = object : DayBinder { override fun create(view: View) = DayViewContainer(view) override fun bind(container: DayViewContainer, day: CalendarDay) = container.bind(day) } val currentMonth = YearMonth.now() // Value for firstDayOfWeek does not matter since inDates and outDates are not generated. - exSevenCalendar.setup(currentMonth, currentMonth.plusMonths(3), DayOfWeek.values().random()) - exSevenCalendar.scrollToDate(LocalDate.now()) + binding.exSevenCalendar.setup(currentMonth, currentMonth.plusMonths(3), DayOfWeek.values().random()) + binding.exSevenCalendar.scrollToDate(LocalDate.now()) } } diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Extensions.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Extensions.kt index d5d2ec83..9a25d92f 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Extensions.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Extensions.kt @@ -6,6 +6,7 @@ import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.annotation.ColorRes import androidx.annotation.DrawableRes @@ -15,7 +16,6 @@ import org.threeten.bp.DayOfWeek import org.threeten.bp.temporal.WeekFields import java.util.* - fun View.makeVisible() { visibility = View.VISIBLE } @@ -35,9 +35,15 @@ fun dpToPx(dp: Int, context: Context): Int = ).toInt() internal fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View { - return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot) + return context.layoutInflater.inflate(layoutRes, this, attachToRoot) } +internal val Context.layoutInflater: LayoutInflater + get() = LayoutInflater.from(this) + +internal val Context.inputMethodManager + get() = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + internal inline fun Boolean?.orFalse(): Boolean = this ?: false internal fun Context.getDrawableCompat(@DrawableRes drawable: Int) = ContextCompat.getDrawable(this, drawable) @@ -50,6 +56,7 @@ fun daysOfWeekFromLocale(): Array { val firstDayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek var daysOfWeek = DayOfWeek.values() // Order `daysOfWeek` array so that firstDayOfWeek is at index 0. + // Only necessary if firstDayOfWeek != DayOfWeek.MONDAY which has ordinal 0. if (firstDayOfWeek != DayOfWeek.MONDAY) { val rhs = daysOfWeek.sliceArray(firstDayOfWeek.ordinal..daysOfWeek.indices.last) val lhs = daysOfWeek.sliceArray(0 until firstDayOfWeek.ordinal) diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeActivity.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeActivity.kt index e5eca1c2..cc232f27 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeActivity.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeActivity.kt @@ -6,11 +6,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.home_activity.* - +import com.kizitonwose.calendarviewsample.databinding.HomeActivityBinding class HomeActivity : AppCompatActivity() { + internal lateinit var binding: HomeActivityBinding + private val examplesAdapter = HomeOptionsAdapter { val fragment = it.createView() supportFragmentManager.beginTransaction() @@ -37,11 +38,14 @@ class HomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.home_activity) - setSupportActionBar(homeToolbar) - examplesRv.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) - examplesRv.adapter = examplesAdapter - examplesRv.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL)) + binding = HomeActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + setSupportActionBar(binding.homeToolbar) + binding.examplesRv.apply { + layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) + adapter = examplesAdapter + addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL)) + } } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeOptionsAdapter.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeOptionsAdapter.kt index dda765d3..45449fc4 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeOptionsAdapter.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/HomeOptionsAdapter.kt @@ -1,16 +1,16 @@ package com.kizitonwose.calendarviewsample -import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.annotation.StringRes import androidx.core.view.isVisible -import androidx.fragment.app.Fragment import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.home_options_item_view.* +import com.kizitonwose.calendarviewsample.databinding.HomeOptionsItemViewBinding -data class ExampleItem(@StringRes val titleRes: Int, @StringRes val subtitleRes: Int, val createView: () -> BaseFragment) +data class ExampleItem( + @StringRes val titleRes: Int, + @StringRes val subtitleRes: Int, + val createView: () -> BaseFragment +) class HomeOptionsAdapter(val onClick: (ExampleItem) -> Unit) : RecyclerView.Adapter() { @@ -27,7 +27,7 @@ class HomeOptionsAdapter(val onClick: (ExampleItem) -> Unit) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeOptionsViewHolder { return HomeOptionsViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.home_options_item_view, parent, false) + HomeOptionsItemViewBinding.inflate(parent.context.layoutInflater, parent, false) ) } @@ -37,8 +37,7 @@ class HomeOptionsAdapter(val onClick: (ExampleItem) -> Unit) : override fun getItemCount(): Int = examples.size - inner class HomeOptionsViewHolder(override val containerView: View) : - RecyclerView.ViewHolder(containerView), LayoutContainer { + inner class HomeOptionsViewHolder(private val binding: HomeOptionsItemViewBinding) : RecyclerView.ViewHolder(binding.root) { init { itemView.setOnClickListener { @@ -48,13 +47,15 @@ class HomeOptionsAdapter(val onClick: (ExampleItem) -> Unit) : fun bind(item: ExampleItem) { val context = itemView.context + binding.itemOptionTitle.apply { + text = if (item.titleRes != 0) context.getString(item.titleRes) else null + isVisible = text.isNotBlank() + } - itemOptionTitle.text = if (item.titleRes != 0) context.getString(item.titleRes) else null - itemOptionTitle.isVisible = itemOptionTitle.text.isNotBlank() - - itemOptionSubtitle.text = if (item.subtitleRes != 0) context.getString(item.subtitleRes) else null - itemOptionSubtitle.isVisible = itemOptionSubtitle.text.isNotBlank() + binding.itemOptionSubtitle.apply { + text = if (item.subtitleRes != 0) context.getString(item.subtitleRes) else null + isVisible = text.isNotBlank() + } } } - -} \ No newline at end of file +} diff --git a/sample/src/main/java/com/kizitonwose/calendarviewsample/Utils.kt b/sample/src/main/java/com/kizitonwose/calendarviewsample/Utils.kt index ecc1906b..3bd39f84 100644 --- a/sample/src/main/java/com/kizitonwose/calendarviewsample/Utils.kt +++ b/sample/src/main/java/com/kizitonwose/calendarviewsample/Utils.kt @@ -48,4 +48,4 @@ fun generateFlights(): List { ) return list -} \ No newline at end of file +} diff --git a/sample/src/main/res/layout/example_1_fragment.xml b/sample/src/main/res/layout/example_1_fragment.xml index d2bf480a..ac29247b 100644 --- a/sample/src/main/res/layout/example_1_fragment.xml +++ b/sample/src/main/res/layout/example_1_fragment.xml @@ -43,6 +43,7 @@ - + diff --git a/sample/src/main/res/layout/example_4_fragment.xml b/sample/src/main/res/layout/example_4_fragment.xml index ff60a9dc..f2fb81a8 100644 --- a/sample/src/main/res/layout/example_4_fragment.xml +++ b/sample/src/main/res/layout/example_4_fragment.xml @@ -78,6 +78,7 @@ @@ -103,7 +103,7 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center_vertical|end" - android:tint="@color/example_5_text_grey" + app:tint="@color/example_5_text_grey" app:srcCompat="@drawable/ic_airplane_landing" /> diff --git a/sample/src/main/res/layout/example_5_fragment.xml b/sample/src/main/res/layout/example_5_fragment.xml index 82a23167..4d7e4046 100644 --- a/sample/src/main/res/layout/example_5_fragment.xml +++ b/sample/src/main/res/layout/example_5_fragment.xml @@ -29,7 +29,7 @@ android:layout_height="36dp" android:layout_marginEnd="22dp" android:background="?attr/selectableItemBackgroundBorderless" - android:tint="@color/example_5_text_grey" + app:tint="@color/example_5_text_grey" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -53,7 +53,7 @@ android:layout_width="36dp" android:layout_height="36dp" android:background="?attr/selectableItemBackgroundBorderless" - android:tint="@color/example_5_text_grey" + app:tint="@color/example_5_text_grey" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/sample/src/main/res/layout/example_6_calendar_header.xml b/sample/src/main/res/layout/example_6_calendar_header.xml index 6597f4fc..71426e36 100644 --- a/sample/src/main/res/layout/example_6_calendar_header.xml +++ b/sample/src/main/res/layout/example_6_calendar_header.xml @@ -8,22 +8,24 @@ - + + android:layout_height="1dp" + android:layout_marginTop="10dp" + android:background="#eeeeee" /> From 52e5d03b1155df4a3cf9967958a355404ab222ac Mon Sep 17 00:00:00 2001 From: Kizito Nwose Date: Sun, 7 Jun 2020 17:39:45 +0200 Subject: [PATCH 3/4] Add ktlint. --- build.gradle | 12 ++++++++++-- .../com/kizitonwose/calendarview/CalendarView.kt | 2 -- .../kizitonwose/calendarview/model/CalendarDay.kt | 3 +-- .../calendarview/model/CalendarMonth.kt | 14 +++++++------- .../com/kizitonwose/calendarview/model/Enums.kt | 3 +-- .../kizitonwose/calendarview/model/MonthConfig.kt | 3 +-- .../kizitonwose/calendarview/ui/CalendarAdapter.kt | 4 +--- .../calendarview/ui/CalendarLayoutManager.kt | 3 +-- .../com/kizitonwose/calendarview/ui/DayHolder.kt | 1 - .../kizitonwose/calendarview/ui/MonthViewHolder.kt | 1 - .../java/com/kizitonwose/calendarview/ui/Types.kt | 2 +- .../kizitonwose/calendarview/utils/Extensions.kt | 2 +- 12 files changed, 24 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index 24c736ea..42651bf8 100644 --- a/build.gradle +++ b/build.gradle @@ -24,12 +24,13 @@ buildscript { repositories { google() jcenter() - + gradlePluginPortal() } dependencies { classpath 'com.android.tools.build:gradle:4.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin_lang" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + classpath 'org.jlleitschuh.gradle:ktlint-gradle:9.2.1' } } @@ -38,8 +39,15 @@ allprojects { google() jcenter() } + + apply plugin: 'org.jlleitschuh.gradle.ktlint' + + ktlint { + version = "0.36.0" + disabledRules = ["no-wildcard-imports"] + } } task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt b/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt index 4cbd517c..24a1b5ed 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/CalendarView.kt @@ -13,7 +13,6 @@ import org.threeten.bp.DayOfWeek import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth - open class CalendarView : RecyclerView { /** @@ -274,7 +273,6 @@ open class CalendarView : RecyclerView { super.onMeasure(widthMeasureSpec, heightMeasureSpec) } - /** * The width, in pixels for each day cell view. * Set this to [DAY_SIZE_SQUARE] to have a nice diff --git a/library/src/main/java/com/kizitonwose/calendarview/model/CalendarDay.kt b/library/src/main/java/com/kizitonwose/calendarview/model/CalendarDay.kt index c1d1f5ed..e00aedc3 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/model/CalendarDay.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/model/CalendarDay.kt @@ -7,7 +7,6 @@ import org.threeten.bp.LocalDate import org.threeten.bp.YearMonth import java.io.Serializable - data class CalendarDay internal constructor(val date: LocalDate, val owner: DayOwner) : Comparable, Serializable { @@ -28,7 +27,7 @@ data class CalendarDay internal constructor(val date: LocalDate, val owner: DayO override fun compareTo(other: CalendarDay): Int { throw UnsupportedOperationException( "Compare using the `date` parameter instead. " + - "Out and In dates can have the same date values as CalendarDay in another month." + "Out and In dates can have the same date values as CalendarDay in another month." ) } diff --git a/library/src/main/java/com/kizitonwose/calendarview/model/CalendarMonth.kt b/library/src/main/java/com/kizitonwose/calendarview/model/CalendarMonth.kt index 9d9b6c35..b29ca223 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/model/CalendarMonth.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/model/CalendarMonth.kt @@ -15,8 +15,8 @@ data class CalendarMonth( override fun hashCode(): Int { return 31 * yearMonth.hashCode() + - weekDays.first().first().hashCode() + - weekDays.last().last().hashCode() + weekDays.first().first().hashCode() + + weekDays.last().last().hashCode() } override fun equals(other: Any?): Boolean { @@ -24,9 +24,9 @@ data class CalendarMonth( if (javaClass != other?.javaClass) return false (other as CalendarMonth) - return yearMonth == other.yearMonth - && weekDays.first().first() == other.weekDays.first().first() - && weekDays.last().last() == other.weekDays.last().last() + return yearMonth == other.yearMonth && + weekDays.first().first() == other.weekDays.first().first() && + weekDays.last().last() == other.weekDays.last().last() } override fun compareTo(other: CalendarMonth): Int { @@ -39,6 +39,6 @@ data class CalendarMonth( override fun toString(): String { return "CalendarMonth { first = ${weekDays.first().first()}, last = ${weekDays.last().last()}} " + - "indexInSameMonth = $indexInSameMonth, numberOfSameMonth = $numberOfSameMonth" + "indexInSameMonth = $indexInSameMonth, numberOfSameMonth = $numberOfSameMonth" } -} \ No newline at end of file +} diff --git a/library/src/main/java/com/kizitonwose/calendarview/model/Enums.kt b/library/src/main/java/com/kizitonwose/calendarview/model/Enums.kt index 2e34dd30..77e425a4 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/model/Enums.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/model/Enums.kt @@ -70,7 +70,6 @@ enum class InDateStyle { NONE } - /** * The scrolling behavior of the calendar. */ @@ -85,4 +84,4 @@ enum class ScrollMode { * The calendar scrolls normally. */ PAGED -} \ No newline at end of file +} diff --git a/library/src/main/java/com/kizitonwose/calendarview/model/MonthConfig.kt b/library/src/main/java/com/kizitonwose/calendarview/model/MonthConfig.kt index 1eedb79d..f0e47cb3 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/model/MonthConfig.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/model/MonthConfig.kt @@ -109,7 +109,7 @@ internal data class MonthConfig( val calendarMonths = mutableListOf() val calMonthsCount = allDaysGroup.size roundDiv maxRowCount allDaysGroup.chunked(maxRowCount) { ephemeralMonthWeeks -> - val monthWeeks = ephemeralMonthWeeks.toMutableList() + val monthWeeks = ephemeralMonthWeeks.toMutableList() // Add the outDates for the last row if needed. if (monthWeeks.last().size < 7 && outDateStyle == OutDateStyle.END_OF_ROW || outDateStyle == OutDateStyle.END_OF_GRID) { @@ -213,7 +213,6 @@ internal data class MonthConfig( thisMonthDays.chunked(7).toMutableList() } - if (outDateStyle == OutDateStyle.END_OF_ROW || outDateStyle == OutDateStyle.END_OF_GRID) { // Add out-dates for the last row. if (weekDaysGroup.last().size < 7) { 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 1716d4ad..a9c2c65f 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarAdapter.kt @@ -301,9 +301,7 @@ internal class CalendarAdapter( visibleItemPos } } - } - return visibleItemPos } @@ -324,4 +322,4 @@ internal class CalendarAdapter( dayRect.intersect(monthRect) } } -} \ No newline at end of file +} diff --git a/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarLayoutManager.kt b/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarLayoutManager.kt index e0288190..011fe95c 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarLayoutManager.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/CalendarLayoutManager.kt @@ -13,7 +13,6 @@ import com.kizitonwose.calendarview.model.ScrollMode import com.kizitonwose.calendarview.utils.NO_INDEX import org.threeten.bp.YearMonth - internal class CalendarLayoutManager(private val calView: CalendarView, @RecyclerView.Orientation orientation: Int) : LinearLayoutManager(calView.context, orientation, false) { @@ -97,4 +96,4 @@ internal class CalendarLayoutManager(private val calView: CalendarView, @Recycle return dx - offset } } -} \ No newline at end of file +} diff --git a/library/src/main/java/com/kizitonwose/calendarview/ui/DayHolder.kt b/library/src/main/java/com/kizitonwose/calendarview/ui/DayHolder.kt index dd364057..c8f50516 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/DayHolder.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/DayHolder.kt @@ -67,5 +67,4 @@ internal class DayHolder(private val config: DayConfig) { fun reloadView() { bindDayView(day) } - } diff --git a/library/src/main/java/com/kizitonwose/calendarview/ui/MonthViewHolder.kt b/library/src/main/java/com/kizitonwose/calendarview/ui/MonthViewHolder.kt index a059121d..6856f7b6 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/MonthViewHolder.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/MonthViewHolder.kt @@ -55,5 +55,4 @@ internal class MonthViewHolder constructor( fun reloadDay(day: CalendarDay) { weekHolders.map { it.dayHolders }.flatten().firstOrNull { it.day == day }?.reloadView() } - } diff --git a/library/src/main/java/com/kizitonwose/calendarview/ui/Types.kt b/library/src/main/java/com/kizitonwose/calendarview/ui/Types.kt index 2fcd866a..e2e9337e 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/ui/Types.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/ui/Types.kt @@ -16,4 +16,4 @@ interface MonthHeaderFooterBinder { fun bind(container: T, month: CalendarMonth) } -typealias MonthScrollListener = (CalendarMonth) -> Unit \ No newline at end of file +typealias MonthScrollListener = (CalendarMonth) -> Unit diff --git a/library/src/main/java/com/kizitonwose/calendarview/utils/Extensions.kt b/library/src/main/java/com/kizitonwose/calendarview/utils/Extensions.kt index c1adc4ca..472033fe 100644 --- a/library/src/main/java/com/kizitonwose/calendarview/utils/Extensions.kt +++ b/library/src/main/java/com/kizitonwose/calendarview/utils/Extensions.kt @@ -28,4 +28,4 @@ val YearMonth.previous: YearMonth internal const val NO_INDEX = -1 internal val Rect.namedString: String - get() = "[L: $left, T: $top][R: $right, B: $bottom]" \ No newline at end of file + get() = "[L: $left, T: $top][R: $right, B: $bottom]" From 29c21872fcfb3e19de6de6267dfd3a08c862a484 Mon Sep 17 00:00:00 2001 From: Kizito Nwose Date: Sun, 7 Jun 2020 18:12:43 +0200 Subject: [PATCH 4/4] Replace Travis with GitHub Actions. --- .github/workflows/ci.yml | 52 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 33 ------------------------- README.md | 2 +- build.gradle | 2 +- 4 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..eb0f18b5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI +on: [push, pull_request] +jobs: + check: + name: Check + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 + - uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Check style + run: ./gradlew ktlintCheck + + unit-tests: + name: Unit tests + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 + - uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Unit tests + run: ./gradlew testDebugUnitTest + + instrumentation-tests: + name: Instrumentation tests + runs-on: macOS-latest + timeout-minutes: 20 + strategy: + fail-fast: true + matrix: + api-level: [22, 25, 29] + steps: + - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 + - uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Instrumentation tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + arch: x86 + script: ./gradlew connectedDebugAndroidTest \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8cb90702..00000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: android -jdk: oraclejdk8 -dist: trusty -android: - components: - - tools - - platform-tools - - build-tools-28.0.3 - - $ANDROID_TARGET - - extra-android-support - - extra-android-m2repository - - extra-google-m2repository - - sys-img-$ANDROID_ABI-$ANDROID_TARGET - licenses: - - '.+' -env: - global: - - ANDROID_TARGET=android-22 ANDROID_ABI=armeabi-v7a -before_install: -- yes | sdkmanager "platforms;android-28" -before_script: - - chmod +x gradlew - - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI - - emulator -avd test -no-skin -no-audio -no-window & - - android-wait-for-emulator - - adb shell input keyevent 82 & - - # sys-img-x86-android-xx emulators do not work because they require hardware acceleration which - # is not currently supported by Travis. Stick with sys-img-armeabi-v7-android-xx for now. - # - # Available sys-img-armeabi-v7a-android-xx images on Travis: 21, 22 and 24. - # sys-img-armeabi-v7a-android-24 fails with `qemu-system-armel: -audio: invalid option`, - # so currently using sys-img-armeabi-v7a-android-22. \ No newline at end of file diff --git a/README.md b/README.md index 7f967eb1..f23d2b78 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A highly customizable calendar library for Android, powered by RecyclerView. -[![Build Status](https://travis-ci.org/kizitonwose/CalendarView.svg?branch=master)](https://travis-ci.org/kizitonwose/CalendarView) +[![CI](https://github.com/kizitonwose/CalendarView/workflows/CI/badge.svg?branch=master)](https://github.com/kizitonwose/CalendarView/actions) [![JitPack](https://jitpack.io/v/kizitonwose/CalendarView.svg)](https://jitpack.io/#kizitonwose/CalendarView) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/kizitonwose/CalendarView/blob/master/LICENSE.md) [![Twitter](https://img.shields.io/badge/Twitter-@kizitonwose-9C27B0.svg)](https://twitter.com/kizitonwose) diff --git a/build.gradle b/build.gradle index 42651bf8..453088d5 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ allprojects { ktlint { version = "0.36.0" - disabledRules = ["no-wildcard-imports"] + disabledRules = ["no-wildcard-imports", "import-ordering"] } }