diff --git a/README.md b/README.md
index 2ea3e65a0..1ca531084 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,49 @@
# Simple Calendar
-Simple Calendar 2023 is a highly customizable, offline monthly calendar app for Android. Have an agenda planner in your pocket, designed to do exactly what a personal tiny schedule planner should do in 2023. No complicated features, unnecessary permissions, or ads!
-***Supports syncing events via Google Calendar
+Note: this is a fork of Simple Mobile Tools's Simple Calendar Pro that has been modified to build
+on current Android SDKs. The original Calendar app relied upon a Duolingo component, rtl-viewpager, that
+modified ViewPager. Android subsequently released a ViewPager2 that eliminated the need for the Duolingo
+component, and the Duolingo component was deprecated and then discontinued. As a result, the basic
+repository no longer builds a working app.
+
+This fork replaces the ViewPager and Duolingo rtl-viewpager component dependencies with calls to ViewPager2,
+and so it will now build with current Android SDKs for current Android versions. These modifications
+were implemented using the Android SDK AI assistant harness together with the free version of Google's Gemma 3 Flash.
+
+** Summary of Changes: **
+1.
+Global Exclusion: The com.github.duolingo:rtl-viewpager library is already excluded from the Simple-Commons dependency in the implementation block of your app/build.gradle.kts. This ensures it is not included in any build type (debug, release, etc.) or flavor (core, fdroid, prepaid).
+2.
+Full Migration to ViewPager2: The codebase has been fully updated to use ViewPager2 and FragmentStateAdapter. I verified that all holders ( DayFragmentsHolder.kt, WeekFragmentsHolder.kt, etc.) and their respective adapters have been migrated.
+3.
+R8 Build Fix: Since the Simple-Commons library still contains internal references to RtlViewPager,
+R8 (the minifier) would previously fail when building release variants (like fdroidRelease) because
+the class was missing from the classpath. I fixed this by adding the following rule to your proguard-rules.pro:
+-dontwarn com.duolingo.open.rtlviewpager.RtlViewPager
+
+This tells R8 to ignore the missing class warnings, allowing the build to succeed while ensuring the
+unused library code is completely stripped out of the final APK.
+This project is now clean of the rtl-viewpager dependency across all variants.
+
+Original README resumes below.
+
+Simple Calendar is a highly customizable, offline monthly calendar app for Android. Have an agenda planner in your pocket, designed to do exactly what a personal tiny schedule planner should do. No complicated features, unnecessary permissions, or ads!
+*Supports syncing events via Google Calendar*
Download now!
Daily Digital Schedule App: Take Control of Your Time
-Whether you are looking for a work calendar for business, a day planner, an appointment scheduler, or organization and scheduling of single and recurring events like birthdays, anniversary, appointment reminder, or anything else, Simple Calendar 2023 makes it easy to stay organized. The calendar widget has an incredible variety of customization options: customize event reminders, notification appearance, tiny calendar reminders widget, and overall appearance.
+Whether you are looking for a work calendar for business, a day planner, an appointment scheduler, or organization and scheduling of single and recurring events like birthdays, anniversaries, appointment reminders, or anything else, Simple Calendar makes it easy to stay organized. The calendar widget has an incredible variety of customization options: customize event reminders, notification appearance, tiny calendar reminder widget, and overall appearance.
Schedule Planner: Plan Your Day
-Appointment scheduler, monthly planner, and family organizer in one! Check your upcoming agenda, schedule business meetings, and events & book appointments easily. Reminders will keep you on time and informed on your daily schedule app. This 2023 calendar widget is remarkably easy to use. You can even view everything as a simple list of events rather than in a monthly view, so you know exactly what’s coming up in your life and how to organize and plan your agenda.
+Appointment scheduler, monthly planner, and family organizer in one! Check your upcoming agenda, schedule business meetings, and events & book appointments easily. Reminders will keep you on time and informed on your daily schedule app. This calendar widget is remarkably easy to use. You can even view everything as a simple list of events rather than in a monthly view, so you know exactly what’s coming up in your life and how to organize and plan your agenda.
-Simple Calendar 2023 Features
+Simple Calendar Features
✔️ The Best User Experience
➕ No ads or annoying popups, truly great user experience!
-➕ No internet access is needed, giving you more privacy, security, and stability
+➕ No internet access is required by default, giving you more privacy, security, and stability
✔️ Flexibility for Your Productivity
➕ Calendar Widget supports exporting & importing events via .ics files
@@ -29,15 +56,15 @@ Simple Calendar 2023 Features
➕ Calendar widget - Colorful Calendars and customizable themes
➕ Open source tiny calendar, translated into 30+ languages
➕ Plan your day with others - ability to share events fast on social media, emails, etc
-➕ Family Organizer - with hasslefree event duplication, organization, and time management
+➕ Family Organizer - with hassle-free event duplication, organization, and time management
✔️ Organization and Time Management
➕ Day planner - the agenda planner will help you to organize your day
➕ Weekly planner - staying ahead of your busy weekly schedule has never been easier
➕ Itinerary manager - business calendar shared between teams at work
➕ Appointment scheduler - organize and maintain your agenda with ease
-➕ Planning app - easy to use personal event, appointment reminder, and schedule planner
-➕ Plan your day - manage your day with this android schedule planner, event & family organizer
+➕ Planning app - easy to use personal events, appointment reminders, and schedule planners
+➕ Plan your day - manage your day with this Android schedule planner, event & family organizer
✔️ #1 Calendar App
➕ Import holidays, contact birthdays, and anniversaries easily
@@ -46,7 +73,7 @@ Simple Calendar 2023 Features
➕ Quick business calendar, or personal digital agenda
➕ Quickly switch between daily, weekly, monthly, yearly & event views
-DOWNLOAD SIMPLE CALENDAR PLANNER – OFFLINE SCHEDULE AND AGENDA PLANNER WITH NO ADS! PLAN YOUR 2023 TIMETABLE!
+DOWNLOAD SIMPLE CALENDAR PLANNER – OFFLINE SCHEDULE AND AGENDA PLANNER WITH NO ADS! PLAN YOUR TIMETABLE!
Get it on F-Droid
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9762e9bbf..50ac43e5e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -61,6 +61,7 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
+ signingConfig = signingConfigs.getByName("debug")
if (keystorePropertiesFile.exists()) {
signingConfig = signingConfigs.getByName("release")
}
@@ -97,10 +98,13 @@ android {
}
dependencies {
- implementation(libs.simple.mobile.tools.commons)
+ implementation(libs.simple.mobile.tools.commons) {
+ exclude(group = "com.github.duolingo", module = "rtl-viewpager")
+ }
implementation(libs.androidx.multidex)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.swiperefreshlayout)
+ implementation(libs.androidx.viewpager2)
implementation(libs.androidx.print)
implementation(libs.bundles.room)
ksp(libs.androidx.room.compiler)
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index ad7d60487..995e79487 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -1 +1,3 @@
-keep class com.simplemobiletools.calendar.models.** { *; }
+
+-dontwarn com.duolingo.open.rtlviewpager.RtlViewPager
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt
index a1659a25e..03d66e056 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt
@@ -1,6 +1,5 @@
package com.simplemobiletools.calendar.pro.activities
-import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Intent
@@ -8,6 +7,7 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.net.Uri
+import android.os.Build
import android.os.Bundle
import android.provider.CalendarContract.Attendees
import android.provider.CalendarContract.Colors
@@ -21,6 +21,7 @@ import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.widget.ImageView
import android.widget.RelativeLayout
+import androidx.activity.result.contract.ActivityResultContracts
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.MaterialTimePicker.INPUT_MODE_CLOCK
import com.google.android.material.timepicker.TimeFormat
@@ -44,12 +45,12 @@ import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.MyAutoCompleteTextView
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
+import java.io.Serializable
import java.util.TimeZone
import java.util.regex.Pattern
class EventActivity : SimpleActivity() {
private val LAT_LON_PATTERN = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)([,;])\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)\$"
- private val SELECT_TIME_ZONE_INTENT = 1
private var mIsAllDayEvent = false
private var mReminder1Minutes = REMINDER_OFF
@@ -82,7 +83,14 @@ class EventActivity : SimpleActivity() {
private lateinit var mEventStartDateTime: DateTime
private lateinit var mEventEndDateTime: DateTime
private lateinit var mEvent: Event
-
+ private val selectTimeZoneLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == RESULT_OK) {
+ result.data?.getSerializableExtraCompat(TIME_ZONE)?.let { timeZone ->
+ mEvent.timeZone = timeZone.zoneName
+ updateTimeZoneText()
+ }
+ }
+ }
private val binding by viewBinding(ActivityEventBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
@@ -139,11 +147,17 @@ class EventActivity : SimpleActivity() {
if (it) {
saveCurrentEvent()
} else {
- super.onBackPressed()
+ //super.onBackPressed()
+ // Source - https://stackoverflow.com/a/73934895
+ // Posted by Jaydeep Khambhayta, modified by community. See post 'Timeline' for change history
+ // Retrieved 2026-09-18, License - CC BY-SA 4.0
+ onBackPressedDispatcher.onBackPressed()
+
}
}
} else {
- super.onBackPressed()
+ // super.onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
}
@@ -193,7 +207,7 @@ class EventActivity : SimpleActivity() {
}
savedInstanceState.apply {
- mEvent = getSerializable(EVENT) as Event
+ getSerializableCompat(EVENT)?.let { mEvent = it }
mEventStartDateTime = Formatter.getDateTimeFromTS(getLong(START_TS))
mEventEndDateTime = Formatter.getDateTimeFromTS(getLong(END_TS))
mEvent.timeZone = getString(TIME_ZONE) ?: TimeZone.getDefault().id
@@ -232,15 +246,6 @@ class EventActivity : SimpleActivity() {
updateActionBarTitle()
}
- override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
- if (requestCode == SELECT_TIME_ZONE_INTENT && resultCode == Activity.RESULT_OK && resultData?.hasExtra(TIME_ZONE) == true) {
- val timeZone = resultData.getSerializableExtra(TIME_ZONE) as MyTimeZone
- mEvent.timeZone = timeZone.zoneName
- updateTimeZoneText()
- }
- super.onActivityResult(requestCode, resultCode, resultData)
- }
-
private fun gotEvent(savedInstanceState: Bundle?, localEventType: EventType?, event: Event?) = binding.apply {
if (localEventType == null || localEventType.caldavCalendarId != 0) {
config.lastUsedLocalEventTypeId = REGULAR_EVENT_TYPE_ID
@@ -1600,7 +1605,7 @@ class EventActivity : SimpleActivity() {
hideKeyboard()
Intent(this, SelectTimeZoneActivity::class.java).apply {
putExtra(CURRENT_TIME_ZONE, mEvent.getTimeZoneString())
- startActivityForResult(this, SELECT_TIME_ZONE_INTENT)
+ selectTimeZoneLauncher.launch(this)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
index d8ba5db5e..5855bb95f 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
@@ -3,16 +3,21 @@ package com.simplemobiletools.calendar.pro.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ShortcutInfo
+import android.graphics.PorterDuff
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable
+import android.os.Build
import android.os.Bundle
-import android.os.Handler
import android.provider.ContactsContract.CommonDataKinds
import android.provider.ContactsContract.Contacts
import android.provider.ContactsContract.Data
import android.view.MenuItem
import android.widget.Toast
+import androidx.activity.OnBackPressedCallback
+import androidx.core.content.ContextCompat
+import androidx.core.content.res.ResourcesCompat
+import androidx.lifecycle.lifecycleScope
import com.simplemobiletools.calendar.pro.BuildConfig
import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.adapters.EventListAdapter
@@ -42,16 +47,19 @@ import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.commons.models.SimpleContact
import com.simplemobiletools.commons.views.MyLinearLayoutManager
import com.simplemobiletools.commons.views.MyRecyclerView
+import kotlinx.coroutines.*
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import java.text.SimpleDateFormat
import java.util.*
+import kotlin.time.Duration.Companion.milliseconds
class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private var showCalDAVRefreshToast = false
private var mShouldFilterBeVisible = false
private var mLatestSearchQuery = ""
+ private var searchJob: Job? = null
private var shouldGoToTodayBeVisible = false
private var goToTodayButton: MenuItem? = null
private var currentFragments = ArrayList()
@@ -85,6 +93,26 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
refreshMenuItems()
updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = false, useTopSearchMenu = true)
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ if (binding.mainMenu.isSearchOpen) {
+ closeSearch()
+ } else {
+ binding.swipeRefreshLayout.isRefreshing = false
+ checkSwipeRefreshAvailability()
+ when {
+ binding.fabExtendedOverlay.isVisible() -> hideExtendedFab()
+ currentFragments.size > 1 -> removeTopFragment()
+ else -> {
+ isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ isEnabled = true
+ }
+ }
+ }
+ }
+ })
+
checkWhatsNewDialog()
binding.calendarFab.beVisibleIf(config.storedView != YEARLY_VIEW && config.storedView != WEEKLY_VIEW)
binding.calendarFab.setOnClickListener {
@@ -92,7 +120,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
if (binding.fabExtendedOverlay.isVisible()) {
openNewEvent()
- Handler().postDelayed({
+ binding.calendarFab.postDelayed({
hideExtendedFab()
}, 300)
} else {
@@ -112,7 +140,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
binding.fabTaskIcon.setOnClickListener {
openNewTask()
- Handler().postDelayed({
+ binding.fabTaskIcon.postDelayed({
hideExtendedFab()
}, 300)
}
@@ -278,18 +306,9 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
}
}
+ @Deprecated("Deprecated in Java")
override fun onBackPressed() {
- if (binding.mainMenu.isSearchOpen) {
- closeSearch()
- } else {
- binding.swipeRefreshLayout.isRefreshing = false
- checkSwipeRefreshAvailability()
- when {
- binding.fabExtendedOverlay.isVisible() -> hideExtendedFab()
- currentFragments.size > 1 -> removeTopFragment()
- else -> super.onBackPressed()
- }
- }
+ super.onBackPressed()
}
override fun onNewIntent(intent: Intent?) {
@@ -383,9 +402,9 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
@SuppressLint("NewApi")
private fun getNewEventShortcut(appIconColor: Int): ShortcutInfo {
val newEvent = getString(R.string.new_event)
- val newEventDrawable = resources.getDrawable(R.drawable.shortcut_event, theme)
- (newEventDrawable as LayerDrawable).findDrawableByLayerId(R.id.shortcut_event_background).applyColorFilter(appIconColor)
- val newEventBitmap = newEventDrawable.convertToBitmap()
+ val newEventDrawable = ResourcesCompat.getDrawable(resources, R.drawable.shortcut_event, theme)
+ (newEventDrawable as? LayerDrawable)?.findDrawableByLayerId(R.id.shortcut_event_background)?.applyColorFilter(appIconColor)
+ val newEventBitmap = newEventDrawable?.convertToBitmap() ?: Icon.createWithResource(this, R.drawable.shortcut_event).loadDrawable(this)!!.convertToBitmap()
val newEventIntent = Intent(this, SplashActivity::class.java)
newEventIntent.action = SHORTCUT_NEW_EVENT
@@ -400,9 +419,9 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
@SuppressLint("NewApi")
private fun getNewTaskShortcut(appIconColor: Int): ShortcutInfo {
val newTask = getString(R.string.new_task)
- val newTaskDrawable = resources.getDrawable(R.drawable.shortcut_task, theme)
- (newTaskDrawable as LayerDrawable).findDrawableByLayerId(R.id.shortcut_task_background).applyColorFilter(appIconColor)
- val newTaskBitmap = newTaskDrawable.convertToBitmap()
+ val newTaskDrawable = ResourcesCompat.getDrawable(resources, R.drawable.shortcut_task, theme)
+ (newTaskDrawable as? LayerDrawable)?.findDrawableByLayerId(R.id.shortcut_task_background)?.applyColorFilter(appIconColor)
+ val newTaskBitmap = newTaskDrawable?.convertToBitmap() ?: Icon.createWithResource(this, R.drawable.shortcut_task).loadDrawable(this)!!.convertToBitmap()
val newTaskIntent = Intent(this, SplashActivity::class.java)
newTaskIntent.action = SHORTCUT_NEW_TASK
return ShortcutInfo.Builder(this, "new_task")
@@ -572,19 +591,18 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun addHolidays() {
val items = getHolidayRadioItems()
RadioGroupDialog(this, items) { selectedHoliday ->
- SetRemindersDialog(this, OTHER_EVENT) {
- val reminders = it
+ SetRemindersDialog(this, OTHER_EVENT) { reminders ->
toast(com.simplemobiletools.commons.R.string.importing)
- ensureBackgroundThread {
+ lifecycleScope.launch(Dispatchers.IO) {
val holidays = getString(R.string.holidays)
var eventTypeId = eventsHelper.getEventTypeIdWithClass(HOLIDAY_EVENT)
if (eventTypeId == -1L) {
eventTypeId = eventsHelper.createPredefinedEventType(holidays, R.color.default_holidays_color, HOLIDAY_EVENT, true)
}
- val result = IcsImporter(this).importEvents(selectedHoliday as String, eventTypeId, 0, false, reminders)
+ val result = IcsImporter(this@MainActivity).importEvents(selectedHoliday as String, eventTypeId, 0, false, reminders)
handleParseResult(result)
if (result != ImportResult.IMPORT_FAIL) {
- runOnUiThread {
+ withContext(Dispatchers.Main) {
updateViewPager()
setupQuickFilter()
}
@@ -597,23 +615,22 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun tryAddBirthdays() {
handlePermission(PERMISSION_READ_CONTACTS) {
if (it) {
- SetRemindersDialog(this, BIRTHDAY_EVENT) {
- val reminders = it
- val privateCursor = getMyContactsCursor(false, false)
+ SetRemindersDialog(this, BIRTHDAY_EVENT) { reminders ->
+ val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = false)
- ensureBackgroundThread {
- val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
+ lifecycleScope.launch(Dispatchers.IO) {
+ val privateContacts = MyContactsContentProvider.getSimpleContacts(this@MainActivity, privateCursor)
addPrivateEvents(true, privateContacts, reminders) { eventsFound, eventsAdded ->
- addContactEvents(true, reminders, eventsFound, eventsAdded) {
- when {
- it > 0 -> {
- toast(R.string.birthdays_added)
- updateViewPager()
- setupQuickFilter()
- }
-
- it == -1 -> toast(R.string.no_new_birthdays)
- else -> toast(R.string.no_birthdays)
+ addContactEvents(true, reminders, eventsFound, eventsAdded) { result ->
+ val toastId = when {
+ result > 0 -> R.string.birthdays_added
+ result == -1 -> R.string.no_new_birthdays
+ else -> R.string.no_birthdays
+ }
+ toast(toastId)
+ if (result > 0) {
+ updateViewPager()
+ setupQuickFilter()
}
}
}
@@ -628,23 +645,22 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun tryAddAnniversaries() {
handlePermission(PERMISSION_READ_CONTACTS) {
if (it) {
- SetRemindersDialog(this, ANNIVERSARY_EVENT) {
- val reminders = it
- val privateCursor = getMyContactsCursor(false, false)
+ SetRemindersDialog(this, ANNIVERSARY_EVENT) { reminders ->
+ val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = false)
- ensureBackgroundThread {
- val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
+ lifecycleScope.launch(Dispatchers.IO) {
+ val privateContacts = MyContactsContentProvider.getSimpleContacts(this@MainActivity, privateCursor)
addPrivateEvents(false, privateContacts, reminders) { eventsFound, eventsAdded ->
- addContactEvents(false, reminders, eventsFound, eventsAdded) {
- when {
- it > 0 -> {
- toast(R.string.anniversaries_added)
- updateViewPager()
- setupQuickFilter()
- }
-
- it == -1 -> toast(R.string.no_new_anniversaries)
- else -> toast(R.string.no_anniversaries)
+ addContactEvents(false, reminders, eventsFound, eventsAdded) { result ->
+ val toastId = when {
+ result > 0 -> R.string.anniversaries_added
+ result == -1 -> R.string.no_new_anniversaries
+ else -> R.string.no_anniversaries
+ }
+ toast(toastId)
+ if (result > 0) {
+ updateViewPager()
+ setupQuickFilter()
}
}
}
@@ -661,10 +677,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
return
}
- val privateCursor = getMyContactsCursor(false, false)
+ val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = false)
- ensureBackgroundThread {
- val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
+ lifecycleScope.launch(Dispatchers.IO) {
+ val privateContacts = MyContactsContentProvider.getSimpleContacts(this@MainActivity, privateCursor)
if (config.addBirthdaysAutomatically) {
addPrivateEvents(true, privateContacts, config.birthdayReminders) { eventsFound, eventsAdded ->
addContactEvents(true, config.birthdayReminders, eventsFound, eventsAdded) {
@@ -720,10 +736,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
val dateFormats = getDateFormats()
val yearDateFormats = getDateFormatsWithYear()
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
- val importIDs = HashMap()
- existingEvents.forEach {
- importIDs[it.importId] = it.startTS
- }
+ val importIDs = existingEvents.associateBy({ it.importId }, { it.startTS }).toMutableMap()
val eventTypeId = if (birthdays) eventsHelper.getLocalBirthdaysEventTypeId() else eventsHelper.getAnniversariesEventTypeId()
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
@@ -736,7 +749,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
for (format in dateFormats) {
try {
val formatter = SimpleDateFormat(format, Locale.getDefault())
- val date = formatter.parse(startDate)
+ val date = formatter.parse(startDate) ?: continue
val flags = if (format in yearDateFormats) {
FLAG_ALL_DAY
} else {
@@ -751,20 +764,12 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
repeatInterval = YEAR, repeatRule = REPEAT_SAME_DAY, eventType = eventTypeId, source = source, lastUpdated = lastUpdated
)
- val importIDsToDelete = ArrayList()
- for ((key, value) in importIDs) {
- if (key == contactId && value != timestamp) {
- val deleted = eventsDB.deleteBirthdayAnniversary(source, key)
- if (deleted == 1) {
- importIDsToDelete.add(key)
- }
+ importIDs.filter { it.key == contactId && it.value != timestamp }.keys.forEach { key ->
+ if (eventsDB.deleteBirthdayAnniversary(source, key) == 1) {
+ importIDs.remove(key)
}
}
- importIDsToDelete.forEach {
- importIDs.remove(it)
- }
-
eventsFound++
if (!importIDs.containsKey(contactId)) {
// avoid adding duplicate birthdays/anniversaries
@@ -803,10 +808,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
- val importIDs = HashMap()
- existingEvents.forEach {
- importIDs[it.importId] = it.startTS
- }
+ val importIDs = existingEvents.associateBy({ it.importId }, { it.startTS }).toMutableMap()
contacts.forEach { contact ->
val events = if (birthdays) contact.birthdays else contact.anniversaries
@@ -819,12 +821,13 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
}
val formatter = SimpleDateFormat(format, Locale.getDefault())
- val date = formatter.parse(birthdayAnniversary)
- if (date.year < 70) {
- date.year = 70
+ val date = formatter.parse(birthdayAnniversary) ?: return@forEach
+ val calendar = Calendar.getInstance().apply { time = date }
+ if (calendar.get(Calendar.YEAR) < 1970) {
+ calendar.set(Calendar.YEAR, 1970)
}
- val timestamp = date.time / 1000L
+ val timestamp = calendar.timeInMillis / 1000L
val lastUpdated = System.currentTimeMillis()
val event = Event(
null, timestamp, timestamp, contact.name, reminder1Minutes = reminders[0], reminder2Minutes = reminders[1],
@@ -832,20 +835,12 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
repeatInterval = YEAR, repeatRule = REPEAT_SAME_DAY, eventType = eventTypeId, source = source, lastUpdated = lastUpdated
)
- val importIDsToDelete = ArrayList()
- for ((key, value) in importIDs) {
- if (key == contact.contactId.toString() && value != timestamp) {
- val deleted = eventsDB.deleteBirthdayAnniversary(source, key)
- if (deleted == 1) {
- importIDsToDelete.add(key)
- }
+ importIDs.filter { it.key == contact.contactId.toString() && it.value != timestamp }.keys.forEach { key ->
+ if (eventsDB.deleteBirthdayAnniversary(source, key) == 1) {
+ importIDs.remove(key)
}
}
- importIDsToDelete.forEach {
- importIDs.remove(it)
- }
-
eventsFound++
if (!importIDs.containsKey(contact.contactId.toString())) {
eventsHelper.insertEvent(event, false, false) {
@@ -1078,6 +1073,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun searchQueryChanged(text: String) {
mLatestSearchQuery = text
+ searchJob?.cancel()
if (text.isNotEmpty() && binding.searchHolder.isGone()) {
binding.searchHolder.fadeIn()
@@ -1094,32 +1090,36 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
binding.searchPlaceholder.setText(placeholderTextId)
binding.searchPlaceholder2.beVisibleIf(text.length == 1)
+
if (text.length >= 2) {
- if (binding.searchResultsList.adapter == null) {
- minFetchedSearchTS = DateTime().minusYears(2).seconds()
- maxFetchedSearchTS = DateTime().plusYears(2).seconds()
- }
+ searchJob = lifecycleScope.launch {
+ delay(300.milliseconds) // debounce
+ if (binding.searchResultsList.adapter == null) {
+ minFetchedSearchTS = DateTime().minusYears(2).seconds()
+ maxFetchedSearchTS = DateTime().plusYears(2).seconds()
+ }
- eventsHelper.getEvents(minFetchedSearchTS, maxFetchedSearchTS, searchQuery = text) { events ->
- if (text == mLatestSearchQuery) {
- // if we have less than MIN_EVENTS_THRESHOLD events, search again by extending the time span
- showSearchResultEvents(events, INITIAL_EVENTS)
+ eventsHelper.getEvents(minFetchedSearchTS, maxFetchedSearchTS, searchQuery = text) { events ->
+ if (text == mLatestSearchQuery) {
+ showSearchResultEvents(events, INITIAL_EVENTS)
- if (events.size < MIN_EVENTS_TRESHOLD) {
- minFetchedSearchTS = 0L
- maxFetchedSearchTS = MAX_SEARCH_YEAR
+ if (events.size < MIN_EVENTS_TRESHOLD) {
+ minFetchedSearchTS = 0L
+ maxFetchedSearchTS = MAX_SEARCH_YEAR
- eventsHelper.getEvents(minFetchedSearchTS, maxFetchedSearchTS, searchQuery = text) { events ->
- events.forEach { event ->
- try {
- if (searchResultEvents.firstOrNull { it.id == event.id && it.startTS == event.startTS } == null) {
- searchResultEvents.add(0, event)
+ eventsHelper.getEvents(minFetchedSearchTS, maxFetchedSearchTS, searchQuery = text) { extendedEvents ->
+ val newEvents = ArrayList()
+ extendedEvents.forEach { event ->
+ if (searchResultEvents.none { it.id == event.id && it.startTS == event.startTS }) {
+ newEvents.add(event)
}
- } catch (ignored: ConcurrentModificationException) {
}
- }
- showSearchResultEvents(searchResultEvents, INITIAL_EVENTS)
+ if (newEvents.isNotEmpty()) {
+ searchResultEvents.addAll(0, newEvents)
+ showSearchResultEvents(searchResultEvents, INITIAL_EVENTS)
+ }
+ }
}
}
}
@@ -1132,18 +1132,13 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun showSearchResultEvents(events: ArrayList, updateStatus: Int) {
val currentSearchQuery = binding.mainMenu.getCurrentQuery()
- val filtered = try {
- events.filter {
- it.title.contains(currentSearchQuery, true) || it.location.contains(currentSearchQuery, true) || it.description.contains(
- currentSearchQuery,
- true
- )
- }
- } catch (e: ConcurrentModificationException) {
- return
+ val filtered = events.filter {
+ it.title.contains(currentSearchQuery, true) ||
+ it.location.contains(currentSearchQuery, true) ||
+ it.description.contains(currentSearchQuery, true)
}
- searchResultEvents = filtered.toMutableList() as ArrayList
+ searchResultEvents = ArrayList(filtered)
runOnUiThread {
binding.searchResultsList.beVisibleIf(filtered.isNotEmpty())
binding.searchPlaceholder.beVisibleIf(filtered.isEmpty())
@@ -1174,17 +1169,23 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
}
} else {
(currAdapter as EventListAdapter).updateListItems(listItems)
- if (updateStatus == UPDATE_TOP) {
- val item = listItems.indexOfFirst { it == bottomItemAtRefresh }
- if (item != -1) {
- binding.searchResultsList.scrollToPosition(item)
+ when (updateStatus) {
+ UPDATE_TOP -> {
+ val item = listItems.indexOfFirst { it == bottomItemAtRefresh }
+ if (item != -1) {
+ binding.searchResultsList.scrollToPosition(item)
+ }
}
- } else if (updateStatus == UPDATE_BOTTOM) {
- binding.searchResultsList.smoothScrollBy(0, resources.getDimension(R.dimen.endless_scroll_move_height).toInt())
- } else {
- val firstNonPastSectionIndex = listItems.indexOfFirst { it is ListSectionDay && !it.isPastSection }
- if (firstNonPastSectionIndex != -1) {
- binding.searchResultsList.scrollToPosition(firstNonPastSectionIndex)
+
+ UPDATE_BOTTOM -> {
+ binding.searchResultsList.smoothScrollBy(0, resources.getDimension(R.dimen.endless_scroll_move_height).toInt())
+ }
+
+ else -> {
+ val firstNonPastSectionIndex = listItems.indexOfFirst { it is ListSectionDay && !it.isPastSection }
+ if (firstNonPastSectionIndex != -1) {
+ binding.searchResultsList.scrollToPosition(firstNonPastSectionIndex)
+ }
}
}
}
@@ -1201,17 +1202,20 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
val oldMinFetchedTS = minFetchedSearchTS - 1
minFetchedSearchTS -= FETCH_INTERVAL
- eventsHelper.getEvents(minFetchedSearchTS, oldMinFetchedTS, searchQuery = mLatestSearchQuery) { events ->
- events.forEach { event ->
- try {
- if (searchResultEvents.firstOrNull { it.id == event.id && it.startTS == event.startTS } == null) {
- searchResultEvents.add(0, event)
+ lifecycleScope.launch {
+ eventsHelper.getEvents(minFetchedSearchTS, oldMinFetchedTS, searchQuery = mLatestSearchQuery) { events ->
+ val newEvents = ArrayList()
+ events.forEach { event ->
+ if (searchResultEvents.none { it.id == event.id && it.startTS == event.startTS }) {
+ newEvents.add(event)
}
- } catch (ignored: ConcurrentModificationException) {
}
- }
- showSearchResultEvents(searchResultEvents, UPDATE_TOP)
+ if (newEvents.isNotEmpty()) {
+ searchResultEvents.addAll(0, newEvents)
+ showSearchResultEvents(searchResultEvents, UPDATE_TOP)
+ }
+ }
}
}
@@ -1222,17 +1226,20 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
val oldMaxFetchedTS = maxFetchedSearchTS + 1
maxFetchedSearchTS += FETCH_INTERVAL
- eventsHelper.getEvents(oldMaxFetchedTS, maxFetchedSearchTS, searchQuery = mLatestSearchQuery) { events ->
- events.forEach { event ->
- try {
- if (searchResultEvents.firstOrNull { it.id == event.id && it.startTS == event.startTS } == null) {
- searchResultEvents.add(0, event)
+ lifecycleScope.launch {
+ eventsHelper.getEvents(oldMaxFetchedTS, maxFetchedSearchTS, searchQuery = mLatestSearchQuery) { events ->
+ val newEvents = ArrayList()
+ events.forEach { event ->
+ if (searchResultEvents.none { it.id == event.id && it.startTS == event.startTS }) {
+ newEvents.add(event)
}
- } catch (ignored: ConcurrentModificationException) {
}
- }
- showSearchResultEvents(searchResultEvents, UPDATE_BOTTOM)
+ if (newEvents.isNotEmpty()) {
+ searchResultEvents.addAll(newEvents)
+ showSearchResultEvents(searchResultEvents, UPDATE_BOTTOM)
+ }
+ }
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SimpleActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SimpleActivity.kt
index dc4fac394..c2b79a839 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SimpleActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SimpleActivity.kt
@@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.pro.activities
import android.content.Context
import android.database.ContentObserver
import android.os.Handler
+import android.os.Looper
import android.provider.CalendarContract
import androidx.core.app.NotificationManagerCompat
import com.simplemobiletools.calendar.pro.R
@@ -16,7 +17,7 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
open class SimpleActivity : BaseSimpleActivity() {
val CALDAV_REFRESH_DELAY = 3000L
- val calDAVRefreshHandler = Handler()
+ val calDAVRefreshHandler = Handler(Looper.getMainLooper())
var calDAVRefreshCallback: (() -> Unit)? = null
override fun getAppIconIDs() = arrayListOf(
@@ -54,7 +55,7 @@ open class SimpleActivity : BaseSimpleActivity() {
}
// caldav refresh content observer triggers multiple times in a row at updating, so call the callback only a few seconds after the (hopefully) last one
- private val calDAVSyncObserver = object : ContentObserver(Handler()) {
+ private val calDAVSyncObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
if (!selfChange) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyDayPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyDayPagerAdapter.kt
index 812683121..23e54c633 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyDayPagerAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyDayPagerAdapter.kt
@@ -1,21 +1,18 @@
package com.simplemobiletools.calendar.pro.adapters
import android.os.Bundle
-import android.util.SparseArray
import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentStatePagerAdapter
+import androidx.viewpager2.adapter.FragmentStateAdapter
import com.simplemobiletools.calendar.pro.fragments.DayFragment
import com.simplemobiletools.calendar.pro.helpers.DAY_CODE
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
-class MyDayPagerAdapter(fm: FragmentManager, private val mCodes: List, private val mListener: NavigationListener) :
- FragmentStatePagerAdapter(fm) {
- private val mFragments = SparseArray()
+class MyDayPagerAdapter(fragment: Fragment, private val mCodes: List, private val mListener: NavigationListener) :
+ FragmentStateAdapter(fragment) {
- override fun getCount() = mCodes.size
+ override fun getItemCount() = mCodes.size
- override fun getItem(position: Int): Fragment {
+ override fun createFragment(position: Int): Fragment {
val bundle = Bundle()
val code = mCodes[position]
bundle.putString(DAY_CODE, code)
@@ -23,18 +20,18 @@ class MyDayPagerAdapter(fm: FragmentManager, private val mCodes: List, p
val fragment = DayFragment()
fragment.arguments = bundle
fragment.mListener = mListener
-
- mFragments.put(position, fragment)
return fragment
}
- fun updateCalendars(pos: Int) {
+ fun updateCalendars(pos: Int, fragment: Fragment) {
for (i in -1..1) {
- mFragments[pos + i]?.updateCalendar()
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? DayFragment
+ f?.updateCalendar()
}
}
- fun printCurrentView(pos: Int) {
- mFragments[pos].printCurrentView()
+ fun printCurrentView(pos: Int, fragment: Fragment) {
+ val f = fragment.childFragmentManager.findFragmentByTag("f$pos") as? DayFragment
+ f?.printCurrentView()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt
index 020701c81..09c0e7268 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt
@@ -1,20 +1,18 @@
package com.simplemobiletools.calendar.pro.adapters
import android.os.Bundle
-import android.util.SparseArray
import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentStatePagerAdapter
+import androidx.viewpager2.adapter.FragmentStateAdapter
import com.simplemobiletools.calendar.pro.fragments.MonthDayFragment
import com.simplemobiletools.calendar.pro.helpers.DAY_CODE
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
-class MyMonthDayPagerAdapter(fm: FragmentManager, private val mCodes: List, private val mListener: NavigationListener) : FragmentStatePagerAdapter(fm) {
- private val mFragments = SparseArray()
+class MyMonthDayPagerAdapter(fragment: Fragment, private val mCodes: List, private val mListener: NavigationListener) :
+ FragmentStateAdapter(fragment) {
- override fun getCount() = mCodes.size
+ override fun getItemCount() = mCodes.size
- override fun getItem(position: Int): Fragment {
+ override fun createFragment(position: Int): Fragment {
val bundle = Bundle()
val code = mCodes[position]
bundle.putString(DAY_CODE, code)
@@ -22,20 +20,23 @@ class MyMonthDayPagerAdapter(fm: FragmentManager, private val mCodes: List, private val mListener: NavigationListener) : FragmentStatePagerAdapter(fm) {
- private val mFragments = SparseArray()
+class MyMonthPagerAdapter(fragment: Fragment, private val mCodes: List, private val mListener: NavigationListener) :
+ FragmentStateAdapter(fragment) {
- override fun getCount() = mCodes.size
+ override fun getItemCount() = mCodes.size
- override fun getItem(position: Int): Fragment {
+ override fun createFragment(position: Int): Fragment {
val bundle = Bundle()
val code = mCodes[position]
bundle.putString(DAY_CODE, code)
@@ -22,18 +20,18 @@ class MyMonthPagerAdapter(fm: FragmentManager, private val mCodes: List,
val fragment = MonthFragment()
fragment.arguments = bundle
fragment.listener = mListener
-
- mFragments.put(position, fragment)
return fragment
}
- fun updateCalendars(pos: Int) {
+ fun updateCalendars(pos: Int, fragment: Fragment) {
for (i in -1..1) {
- mFragments[pos + i]?.updateCalendar()
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? MonthFragment
+ f?.updateCalendar()
}
}
- fun printCurrentView(pos: Int) {
- mFragments[pos].printCurrentView()
+ fun printCurrentView(pos: Int, fragment: Fragment) {
+ val f = fragment.childFragmentManager.findFragmentByTag("f$pos") as? MonthFragment
+ f?.printCurrentView()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyWeekPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyWeekPagerAdapter.kt
index 66de13650..538241a61 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyWeekPagerAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyWeekPagerAdapter.kt
@@ -1,21 +1,18 @@
package com.simplemobiletools.calendar.pro.adapters
import android.os.Bundle
-import android.util.SparseArray
import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentStatePagerAdapter
+import androidx.viewpager2.adapter.FragmentStateAdapter
import com.simplemobiletools.calendar.pro.fragments.WeekFragment
import com.simplemobiletools.calendar.pro.helpers.WEEK_START_TIMESTAMP
import com.simplemobiletools.calendar.pro.interfaces.WeekFragmentListener
-class MyWeekPagerAdapter(fm: FragmentManager, private val mWeekTimestamps: List, private val mListener: WeekFragmentListener) :
- FragmentStatePagerAdapter(fm) {
- private val mFragments = SparseArray()
+class MyWeekPagerAdapter(fragment: Fragment, private val mWeekTimestamps: List, private val mListener: WeekFragmentListener) :
+ FragmentStateAdapter(fragment) {
- override fun getCount() = mWeekTimestamps.size
+ override fun getItemCount() = mWeekTimestamps.size
- override fun getItem(position: Int): Fragment {
+ override fun createFragment(position: Int): Fragment {
val bundle = Bundle()
val weekTimestamp = mWeekTimestamps[position]
bundle.putLong(WEEK_START_TIMESTAMP, weekTimestamp)
@@ -23,28 +20,34 @@ class MyWeekPagerAdapter(fm: FragmentManager, private val mWeekTimestamps: List<
val fragment = WeekFragment()
fragment.arguments = bundle
fragment.listener = mListener
-
- mFragments.put(position, fragment)
return fragment
}
- fun updateScrollY(pos: Int, y: Int) {
- mFragments[pos - 1]?.updateScrollY(y)
- mFragments[pos + 1]?.updateScrollY(y)
+ fun updateScrollY(pos: Int, y: Int, fragment: Fragment) {
+ for (i in -1..1) {
+ if (i == 0) continue
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? WeekFragment
+ f?.updateScrollY(y)
+ }
}
- fun updateCalendars(pos: Int) {
+ fun updateCalendars(pos: Int, fragment: Fragment) {
for (i in -1..1) {
- mFragments[pos + i]?.updateCalendar()
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? WeekFragment
+ f?.updateCalendar()
}
}
- fun updateNotVisibleScaleLevel(pos: Int) {
- mFragments[pos - 1]?.updateNotVisibleViewScaleLevel()
- mFragments[pos + 1]?.updateNotVisibleViewScaleLevel()
+ fun updateNotVisibleScaleLevel(pos: Int, fragment: Fragment) {
+ for (i in -1..1) {
+ if (i == 0) continue
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? WeekFragment
+ f?.updateNotVisibleViewScaleLevel()
+ }
}
- fun togglePrintMode(pos: Int) {
- mFragments[pos].togglePrintMode()
+ fun togglePrintMode(pos: Int, fragment: Fragment) {
+ val f = fragment.childFragmentManager.findFragmentByTag("f$pos") as? WeekFragment
+ f?.togglePrintMode()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyYearPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyYearPagerAdapter.kt
index 750d8f8c3..57863604d 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyYearPagerAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyYearPagerAdapter.kt
@@ -1,20 +1,18 @@
package com.simplemobiletools.calendar.pro.adapters
import android.os.Bundle
-import android.util.SparseArray
import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentStatePagerAdapter
+import androidx.viewpager2.adapter.FragmentStateAdapter
import com.simplemobiletools.calendar.pro.fragments.YearFragment
import com.simplemobiletools.calendar.pro.helpers.YEAR_LABEL
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
-class MyYearPagerAdapter(fm: FragmentManager, val mYears: List, private val mListener: NavigationListener) : FragmentStatePagerAdapter(fm) {
- private val mFragments = SparseArray()
+class MyYearPagerAdapter(fragment: Fragment, val mYears: List, private val mListener: NavigationListener) :
+ FragmentStateAdapter(fragment) {
- override fun getCount() = mYears.size
+ override fun getItemCount() = mYears.size
- override fun getItem(position: Int): Fragment {
+ override fun createFragment(position: Int): Fragment {
val bundle = Bundle()
val year = mYears[position]
bundle.putInt(YEAR_LABEL, year)
@@ -22,18 +20,18 @@ class MyYearPagerAdapter(fm: FragmentManager, val mYears: List, private val
val fragment = YearFragment()
fragment.arguments = bundle
fragment.listener = mListener
-
- mFragments.put(position, fragment)
return fragment
}
- fun updateCalendars(pos: Int) {
+ fun updateCalendars(pos: Int, fragment: Fragment) {
for (i in -1..1) {
- mFragments[pos + i]?.updateCalendar()
+ val f = fragment.childFragmentManager.findFragmentByTag("f${pos + i}") as? YearFragment
+ f?.updateCalendar()
}
}
- fun printCurrentView(pos: Int) {
- mFragments[pos].printCurrentView()
+ fun printCurrentView(pos: Int, fragment: Fragment) {
+ val f = fragment.childFragmentManager.findFragmentByTag("f$pos") as? YearFragment
+ f?.printCurrentView()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Bundle.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Bundle.kt
new file mode 100644
index 000000000..03f17a964
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Bundle.kt
@@ -0,0 +1,24 @@
+package com.simplemobiletools.calendar.pro.extensions
+
+import android.os.Build
+import android.os.Bundle
+import android.os.Parcelable
+import java.io.Serializable
+
+inline fun Bundle.getSerializableCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getSerializable(key, T::class.java)
+ } else {
+ @Suppress("DEPRECATION")
+ getSerializable(key) as? T
+ }
+}
+
+inline fun Bundle.getParcelableArrayListCompat(key: String): ArrayList? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getParcelableArrayList(key, T::class.java)
+ } else {
+ @Suppress("DEPRECATION")
+ getParcelableArrayList(key)
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Intent.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Intent.kt
new file mode 100644
index 000000000..ff238b132
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Intent.kt
@@ -0,0 +1,14 @@
+package com.simplemobiletools.calendar.pro.extensions
+
+import android.content.Intent
+import android.os.Build
+import java.io.Serializable
+
+inline fun Intent.getSerializableExtraCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getSerializableExtra(key, T::class.java)
+ } else {
+ @Suppress("DEPRECATION")
+ getSerializableExtra(key) as? T
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/DayFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/DayFragmentsHolder.kt
index ffabf66b3..095612439 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/DayFragmentsHolder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/DayFragmentsHolder.kt
@@ -6,7 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyDayPagerAdapter
import com.simplemobiletools.calendar.pro.databinding.FragmentDaysHolderBinding
@@ -17,13 +17,12 @@ import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.setupDialogStuff
-import com.simplemobiletools.commons.views.MyViewPager
import org.joda.time.DateTime
class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_DAYS = 251
- private lateinit var viewPager: MyViewPager
+ private lateinit var viewPager: ViewPager2
private var defaultDailyPage = 0
private var todayDayCode = ""
private var currentDayCode = ""
@@ -48,18 +47,13 @@ class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
private fun setupFragment() {
val codes = getDays(currentDayCode)
- val dailyAdapter = MyDayPagerAdapter(requireActivity().supportFragmentManager, codes, this)
+ val dailyAdapter = MyDayPagerAdapter(this, codes, this)
defaultDailyPage = codes.size / 2
viewPager.apply {
adapter = dailyAdapter
- addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrollStateChanged(state: Int) {
- }
-
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
- }
-
+ offscreenPageLimit = 1
+ registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentDayCode = codes[position]
val shouldGoToTodayBeVisible = shouldGoToTodayBeVisible()
@@ -69,7 +63,7 @@ class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
}
})
- currentItem = defaultDailyPage
+ setCurrentItem(defaultDailyPage, false)
}
}
@@ -126,7 +120,7 @@ class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
override fun refreshEvents() {
- (viewPager.adapter as? MyDayPagerAdapter)?.updateCalendars(viewPager.currentItem)
+ (viewPager.adapter as? MyDayPagerAdapter)?.updateCalendars(viewPager.currentItem, this)
}
override fun shouldGoToTodayBeVisible() = currentDayCode != todayDayCode
@@ -134,7 +128,7 @@ class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
override fun getNewEventDayCode() = currentDayCode
override fun printView() {
- (viewPager.adapter as? MyDayPagerAdapter)?.printCurrentView(viewPager.currentItem)
+ (viewPager.adapter as? MyDayPagerAdapter)?.printCurrentView(viewPager.currentItem, this)
}
override fun getCurrentDate(): DateTime? {
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt
index 82e2093a4..10335d373 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyMonthDayPagerAdapter
import com.simplemobiletools.calendar.pro.databinding.FragmentMonthsDaysHolderBinding
@@ -20,13 +20,12 @@ import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.setupDialogStuff
-import com.simplemobiletools.commons.views.MyViewPager
import org.joda.time.DateTime
class MonthDayFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_MONTHS = 251
- private lateinit var viewPager: MyViewPager
+ private lateinit var viewPager: ViewPager2
private var defaultMonthlyPage = 0
private var todayDayCode = ""
private var currentDayCode = ""
@@ -51,16 +50,13 @@ class MonthDayFragmentsHolder : MyFragmentHolder(), NavigationListener {
private fun setupFragment() {
val codes = getMonths(currentDayCode)
- val monthlyDailyAdapter = MyMonthDayPagerAdapter(requireActivity().supportFragmentManager, codes, this)
+ val monthlyDailyAdapter = MyMonthDayPagerAdapter(this, codes, this)
defaultMonthlyPage = codes.size / 2
viewPager.apply {
adapter = monthlyDailyAdapter
- addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrollStateChanged(state: Int) {}
-
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
-
+ offscreenPageLimit = 1
+ registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentDayCode = codes[position]
val shouldGoToTodayBeVisible = shouldGoToTodayBeVisible()
@@ -70,7 +66,7 @@ class MonthDayFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
}
})
- currentItem = defaultMonthlyPage
+ setCurrentItem(defaultMonthlyPage, false)
}
}
@@ -129,12 +125,12 @@ class MonthDayFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
override fun refreshEvents() {
- (viewPager.adapter as? MyMonthDayPagerAdapter)?.updateCalendars(viewPager.currentItem)
+ (viewPager.adapter as? MyMonthDayPagerAdapter)?.updateCalendars(viewPager.currentItem, this)
}
override fun shouldGoToTodayBeVisible() = currentDayCode.getMonthCode() != todayDayCode.getMonthCode()
- override fun getNewEventDayCode() = (viewPager.adapter as? MyMonthDayPagerAdapter)?.getNewEventDayCode(viewPager.currentItem)
+ override fun getNewEventDayCode() = (viewPager.adapter as? MyMonthDayPagerAdapter)?.getNewEventDayCode(viewPager.currentItem, this)
?: if (shouldGoToTodayBeVisible()) {
currentDayCode
} else {
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragmentsHolder.kt
index e177811e4..d3b42c486 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragmentsHolder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragmentsHolder.kt
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyMonthPagerAdapter
import com.simplemobiletools.calendar.pro.databinding.FragmentMonthsHolderBinding
@@ -20,13 +20,12 @@ import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.setupDialogStuff
-import com.simplemobiletools.commons.views.MyViewPager
import org.joda.time.DateTime
class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_MONTHS = 251
- private lateinit var viewPager: MyViewPager
+ private lateinit var viewPager: ViewPager2
private var defaultMonthlyPage = 0
private var todayDayCode = ""
private var currentDayCode = ""
@@ -51,18 +50,13 @@ class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
private fun setupFragment() {
val codes = getMonths(currentDayCode)
- val monthlyAdapter = MyMonthPagerAdapter(requireActivity().supportFragmentManager, codes, this)
+ val monthlyAdapter = MyMonthPagerAdapter(this, codes, this)
defaultMonthlyPage = codes.size / 2
viewPager.apply {
adapter = monthlyAdapter
- addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrollStateChanged(state: Int) {
- }
-
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
- }
-
+ offscreenPageLimit = 1
+ registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentDayCode = codes[position]
val shouldGoToTodayBeVisible = shouldGoToTodayBeVisible()
@@ -72,7 +66,7 @@ class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
}
})
- currentItem = defaultMonthlyPage
+ setCurrentItem(defaultMonthlyPage, false)
}
}
@@ -131,7 +125,7 @@ class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
override fun refreshEvents() {
- (viewPager.adapter as? MyMonthPagerAdapter)?.updateCalendars(viewPager.currentItem)
+ (viewPager.adapter as? MyMonthPagerAdapter)?.updateCalendars(viewPager.currentItem, this)
}
override fun shouldGoToTodayBeVisible() = currentDayCode.getMonthCode() != todayDayCode.getMonthCode()
@@ -139,7 +133,7 @@ class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
override fun getNewEventDayCode() = if (shouldGoToTodayBeVisible()) currentDayCode else todayDayCode
override fun printView() {
- (viewPager.adapter as? MyMonthPagerAdapter)?.printCurrentView(viewPager.currentItem)
+ (viewPager.adapter as? MyMonthPagerAdapter)?.printCurrentView(viewPager.currentItem, this)
}
override fun getCurrentDate(): DateTime? {
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragmentsHolder.kt
index d4301190c..b34e12337 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragmentsHolder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragmentsHolder.kt
@@ -10,7 +10,7 @@ import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.RelativeLayout
import android.widget.TextView
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyWeekPagerAdapter
import com.simplemobiletools.calendar.pro.databinding.FragmentWeekHolderBinding
@@ -23,7 +23,6 @@ import com.simplemobiletools.calendar.pro.interfaces.WeekFragmentListener
import com.simplemobiletools.calendar.pro.views.MyScrollView
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.WEEK_SECONDS
-import com.simplemobiletools.commons.views.MyViewPager
import org.joda.time.DateTime
class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
@@ -31,7 +30,7 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
private val MAX_SEEKBAR_VALUE = 14
private lateinit var binding: FragmentWeekHolderBinding
- private lateinit var viewPager: MyViewPager
+ private lateinit var viewPager: ViewPager2
private var defaultWeeklyPage = 0
private var thisWeekTS = 0L
private var currentWeekTS = 0L
@@ -96,17 +95,14 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
private fun setupWeeklyViewPager() {
val weekTSs = getWeekTimestamps(currentWeekTS)
- val weeklyAdapter = MyWeekPagerAdapter(requireActivity().supportFragmentManager, weekTSs, this)
+ val weeklyAdapter = MyWeekPagerAdapter(this, weekTSs, this)
defaultWeeklyPage = weekTSs.size / 2
viewPager.apply {
adapter = weeklyAdapter
- addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrollStateChanged(state: Int) {}
-
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
-
+ offscreenPageLimit = 1
+ registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentWeekTS = weekTSs[position]
val shouldGoToTodayBeVisible = shouldGoToTodayBeVisible()
@@ -118,13 +114,13 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
setupWeeklyActionbarTitle(weekTSs[position])
}
})
- currentItem = defaultWeeklyPage
+ setCurrentItem(defaultWeeklyPage, false)
}
binding.weekViewHoursScrollview.setOnScrollviewListener(object : MyScrollView.ScrollViewListener {
override fun onScrollChanged(scrollView: MyScrollView, x: Int, y: Int, oldx: Int, oldy: Int) {
weekScrollY = y
- weeklyAdapter.updateScrollY(viewPager.currentItem, y)
+ weeklyAdapter.updateScrollY(viewPager.currentItem, y, this@WeekFragmentsHolder)
}
})
}
@@ -223,7 +219,7 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
}
override fun refreshEvents() {
- (viewPager.adapter as? MyWeekPagerAdapter)?.updateCalendars(viewPager.currentItem)
+ (viewPager.adapter as? MyWeekPagerAdapter)?.updateCalendars(viewPager.currentItem, this)
}
override fun shouldGoToTodayBeVisible() = currentWeekTS != thisWeekTS
@@ -262,7 +258,7 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
}
binding.weekViewHoursHolder.setPadding(0, 0, 0, rowHeight)
- (viewPager.adapter as? MyWeekPagerAdapter)?.updateNotVisibleScaleLevel(viewPager.currentItem)
+ (viewPager.adapter as? MyWeekPagerAdapter)?.updateNotVisibleScaleLevel(viewPager.currentItem, this)
}
override fun getFullFragmentHeight() =
@@ -278,7 +274,7 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
weekViewWeekNumber.setTextColor(lightTextColor)
weekViewMonthLabel.setTextColor(lightTextColor)
root.background = ColorDrawable(Color.WHITE)
- (viewPager.adapter as? MyWeekPagerAdapter)?.togglePrintMode(viewPager.currentItem)
+ (viewPager.adapter as? MyWeekPagerAdapter)?.togglePrintMode(viewPager.currentItem, this@WeekFragmentsHolder)
Handler().postDelayed({
requireContext().printBitmap(binding.weekViewHolder.getViewBitmap())
@@ -291,7 +287,7 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
weekViewMonthLabel.setTextColor(requireContext().getProperTextColor())
addHours()
root.background = ColorDrawable(requireContext().getProperBackgroundColor())
- (viewPager.adapter as? MyWeekPagerAdapter)?.togglePrintMode(viewPager.currentItem)
+ (viewPager.adapter as? MyWeekPagerAdapter)?.togglePrintMode(viewPager.currentItem, this@WeekFragmentsHolder)
}, 1000)
}, 1000)
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragmentsHolder.kt
index ebf0471ef..0d286504b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragmentsHolder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragmentsHolder.kt
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyYearPagerAdapter
import com.simplemobiletools.calendar.pro.databinding.FragmentYearsHolderBinding
@@ -19,13 +19,12 @@ import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.setupDialogStuff
-import com.simplemobiletools.commons.views.MyViewPager
import org.joda.time.DateTime
class YearFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_YEARS = 61
- private lateinit var viewPager: MyViewPager
+ private lateinit var viewPager: ViewPager2
private var defaultYearlyPage = 0
private var todayYear = 0
private var currentYear = 0
@@ -51,16 +50,13 @@ class YearFragmentsHolder : MyFragmentHolder(), NavigationListener {
private fun setupFragment() {
val years = getYears(currentYear)
- val yearlyAdapter = MyYearPagerAdapter(requireActivity().supportFragmentManager, years, this)
+ val yearlyAdapter = MyYearPagerAdapter(this, years, this)
defaultYearlyPage = years.size / 2
viewPager.apply {
adapter = yearlyAdapter
- addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrollStateChanged(state: Int) {}
-
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
-
+ offscreenPageLimit = 1
+ registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentYear = years[position]
val shouldGoToTodayBeVisible = shouldGoToTodayBeVisible()
@@ -70,7 +66,7 @@ class YearFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
}
})
- currentItem = defaultYearlyPage
+ setCurrentItem(defaultYearlyPage, false)
}
}
@@ -124,7 +120,7 @@ class YearFragmentsHolder : MyFragmentHolder(), NavigationListener {
}
override fun refreshEvents() {
- (viewPager.adapter as? MyYearPagerAdapter)?.updateCalendars(viewPager.currentItem)
+ (viewPager.adapter as? MyYearPagerAdapter)?.updateCalendars(viewPager.currentItem, this)
}
override fun shouldGoToTodayBeVisible() = currentYear != todayYear
@@ -132,7 +128,7 @@ class YearFragmentsHolder : MyFragmentHolder(), NavigationListener {
override fun getNewEventDayCode() = Formatter.getTodayCode()
override fun printView() {
- (viewPager.adapter as? MyYearPagerAdapter)?.printCurrentView(viewPager.currentItem)
+ (viewPager.adapter as? MyYearPagerAdapter)?.printCurrentView(viewPager.currentItem, this)
}
override fun getCurrentDate() = null
diff --git a/app/src/main/res/layout/activity_day.xml b/app/src/main/res/layout/activity_day.xml
index 125e7b5cc..7848b50be 100644
--- a/app/src/main/res/layout/activity_day.xml
+++ b/app/src/main/res/layout/activity_day.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
-
-
-
-