diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
new file mode 100644
index 0000000..1ce1599
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
@@ -0,0 +1,8 @@
+package com.applikeysolutions.cosmocalendar.listeners;
+
+import com.applikeysolutions.cosmocalendar.model.Month;
+
+public interface OnMonthChangeListener {
+
+ void onMonthChanged(Month month);
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
new file mode 100644
index 0000000..1ce1599
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
@@ -0,0 +1,8 @@
+package com.applikeysolutions.cosmocalendar.listeners;
+
+import com.applikeysolutions.cosmocalendar.model.Month;
+
+public interface OnMonthChangeListener {
+
+ void onMonthChanged(Month month);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
new file mode 100644
index 0000000..b266532
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
@@ -0,0 +1,161 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.utils.DateUtils;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class Day {
+
+ private Calendar calendar;
+ private boolean belongToMonth;
+ private boolean current;
+ private boolean selected;
+ private boolean disabled;
+ private boolean weekend;
+
+ //Connected days
+ private boolean fromConnectedCalendar;
+ private int connectedDaysTextColor;
+ private int connectedDaysSelectedTextColor;
+ private int connectedDaysDisabledTextColor;
+
+ //For animation states
+ private SelectionState selectionState;
+ private boolean isSelectionCircleDrawed;
+
+ public Day(Date date) {
+ this.calendar = DateUtils.getCalendar(date);
+ this.current = DateUtils.isCurrentDate(date);
+ this.selected = false;
+ }
+
+ public Day(Calendar calendar) {
+ Calendar tempCalendar = Calendar.getInstance();
+ tempCalendar.setTime(calendar.getTime());
+ this.calendar = tempCalendar;
+ this.current = DateUtils.isCurrentDate(calendar.getTime());
+ this.selected = false;
+ }
+
+ public boolean isBelongToMonth() {
+ return belongToMonth;
+ }
+
+ public void setBelongToMonth(boolean belongToMonth) {
+ this.belongToMonth = belongToMonth;
+ }
+
+ public boolean isCurrent() {
+ return current;
+ }
+
+ public void setCurrent(boolean current) {
+ this.current = current;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isWeekend() {
+ return weekend;
+ }
+
+ public void setWeekend(boolean weekend) {
+ this.weekend = weekend;
+ }
+
+ public boolean isFromConnectedCalendar() {
+ return fromConnectedCalendar;
+ }
+
+ public void setFromConnectedCalendar(boolean fromConnectedCalendar) {
+ this.fromConnectedCalendar = fromConnectedCalendar;
+ }
+
+ public boolean isSelectionCircleDrawed() {
+ return isSelectionCircleDrawed;
+ }
+
+ public void setSelectionCircleDrawed(boolean selectionCircleDrawed) {
+ isSelectionCircleDrawed = selectionCircleDrawed;
+ }
+
+ public SelectionState getSelectionState() {
+ return selectionState;
+ }
+
+ public void setSelectionState(SelectionState selectionState) {
+ this.selectionState = selectionState;
+ }
+
+ public int getConnectedDaysTextColor() {
+ return connectedDaysTextColor;
+ }
+
+ public void setConnectedDaysTextColor(int connectedDaysTextColor) {
+ this.connectedDaysTextColor = connectedDaysTextColor;
+ }
+
+ public int getConnectedDaysSelectedTextColor() {
+ return connectedDaysSelectedTextColor;
+ }
+
+ public void setConnectedDaysSelectedTextColor(int connectedDaysSelectedTextColor) {
+ this.connectedDaysSelectedTextColor = connectedDaysSelectedTextColor;
+ }
+
+ public int getConnectedDaysDisabledTextColor() {
+ return connectedDaysDisabledTextColor;
+ }
+
+ public void setConnectedDaysDisabledTextColor(int connectedDaysDisabledTextColor) {
+ this.connectedDaysDisabledTextColor = connectedDaysDisabledTextColor;
+ }
+
+ public Calendar getCalendar() {
+ return calendar;
+ }
+
+ public int getDayNumber() {
+ return calendar.get(Calendar.DAY_OF_MONTH);
+ }
+
+ @Override
+ public String toString() {
+ return "Day{day=" + calendar.getTime() + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Day day = (Day) o;
+ Calendar anotherCalendar = day.getCalendar();
+ return anotherCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR) &&
+ anotherCalendar.get(Calendar.DAY_OF_YEAR) == calendar.get(Calendar.DAY_OF_YEAR);
+ }
+
+ @Override
+ public int hashCode() {
+ return calendar != null ? calendar.hashCode() : 0;
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
new file mode 100644
index 0000000..1ce1599
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
@@ -0,0 +1,8 @@
+package com.applikeysolutions.cosmocalendar.listeners;
+
+import com.applikeysolutions.cosmocalendar.model.Month;
+
+public interface OnMonthChangeListener {
+
+ void onMonthChanged(Month month);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
new file mode 100644
index 0000000..b266532
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
@@ -0,0 +1,161 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.utils.DateUtils;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class Day {
+
+ private Calendar calendar;
+ private boolean belongToMonth;
+ private boolean current;
+ private boolean selected;
+ private boolean disabled;
+ private boolean weekend;
+
+ //Connected days
+ private boolean fromConnectedCalendar;
+ private int connectedDaysTextColor;
+ private int connectedDaysSelectedTextColor;
+ private int connectedDaysDisabledTextColor;
+
+ //For animation states
+ private SelectionState selectionState;
+ private boolean isSelectionCircleDrawed;
+
+ public Day(Date date) {
+ this.calendar = DateUtils.getCalendar(date);
+ this.current = DateUtils.isCurrentDate(date);
+ this.selected = false;
+ }
+
+ public Day(Calendar calendar) {
+ Calendar tempCalendar = Calendar.getInstance();
+ tempCalendar.setTime(calendar.getTime());
+ this.calendar = tempCalendar;
+ this.current = DateUtils.isCurrentDate(calendar.getTime());
+ this.selected = false;
+ }
+
+ public boolean isBelongToMonth() {
+ return belongToMonth;
+ }
+
+ public void setBelongToMonth(boolean belongToMonth) {
+ this.belongToMonth = belongToMonth;
+ }
+
+ public boolean isCurrent() {
+ return current;
+ }
+
+ public void setCurrent(boolean current) {
+ this.current = current;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isWeekend() {
+ return weekend;
+ }
+
+ public void setWeekend(boolean weekend) {
+ this.weekend = weekend;
+ }
+
+ public boolean isFromConnectedCalendar() {
+ return fromConnectedCalendar;
+ }
+
+ public void setFromConnectedCalendar(boolean fromConnectedCalendar) {
+ this.fromConnectedCalendar = fromConnectedCalendar;
+ }
+
+ public boolean isSelectionCircleDrawed() {
+ return isSelectionCircleDrawed;
+ }
+
+ public void setSelectionCircleDrawed(boolean selectionCircleDrawed) {
+ isSelectionCircleDrawed = selectionCircleDrawed;
+ }
+
+ public SelectionState getSelectionState() {
+ return selectionState;
+ }
+
+ public void setSelectionState(SelectionState selectionState) {
+ this.selectionState = selectionState;
+ }
+
+ public int getConnectedDaysTextColor() {
+ return connectedDaysTextColor;
+ }
+
+ public void setConnectedDaysTextColor(int connectedDaysTextColor) {
+ this.connectedDaysTextColor = connectedDaysTextColor;
+ }
+
+ public int getConnectedDaysSelectedTextColor() {
+ return connectedDaysSelectedTextColor;
+ }
+
+ public void setConnectedDaysSelectedTextColor(int connectedDaysSelectedTextColor) {
+ this.connectedDaysSelectedTextColor = connectedDaysSelectedTextColor;
+ }
+
+ public int getConnectedDaysDisabledTextColor() {
+ return connectedDaysDisabledTextColor;
+ }
+
+ public void setConnectedDaysDisabledTextColor(int connectedDaysDisabledTextColor) {
+ this.connectedDaysDisabledTextColor = connectedDaysDisabledTextColor;
+ }
+
+ public Calendar getCalendar() {
+ return calendar;
+ }
+
+ public int getDayNumber() {
+ return calendar.get(Calendar.DAY_OF_MONTH);
+ }
+
+ @Override
+ public String toString() {
+ return "Day{day=" + calendar.getTime() + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Day day = (Day) o;
+ Calendar anotherCalendar = day.getCalendar();
+ return anotherCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR) &&
+ anotherCalendar.get(Calendar.DAY_OF_YEAR) == calendar.get(Calendar.DAY_OF_YEAR);
+ }
+
+ @Override
+ public int hashCode() {
+ return calendar != null ? calendar.hashCode() : 0;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
new file mode 100644
index 0000000..2366193
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
@@ -0,0 +1,10 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import java.util.Date;
+
+public class DayOfWeek extends Day {
+
+ public DayOfWeek(Date date) {
+ super(date);
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
new file mode 100644
index 0000000..1ce1599
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
@@ -0,0 +1,8 @@
+package com.applikeysolutions.cosmocalendar.listeners;
+
+import com.applikeysolutions.cosmocalendar.model.Month;
+
+public interface OnMonthChangeListener {
+
+ void onMonthChanged(Month month);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
new file mode 100644
index 0000000..b266532
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
@@ -0,0 +1,161 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.utils.DateUtils;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class Day {
+
+ private Calendar calendar;
+ private boolean belongToMonth;
+ private boolean current;
+ private boolean selected;
+ private boolean disabled;
+ private boolean weekend;
+
+ //Connected days
+ private boolean fromConnectedCalendar;
+ private int connectedDaysTextColor;
+ private int connectedDaysSelectedTextColor;
+ private int connectedDaysDisabledTextColor;
+
+ //For animation states
+ private SelectionState selectionState;
+ private boolean isSelectionCircleDrawed;
+
+ public Day(Date date) {
+ this.calendar = DateUtils.getCalendar(date);
+ this.current = DateUtils.isCurrentDate(date);
+ this.selected = false;
+ }
+
+ public Day(Calendar calendar) {
+ Calendar tempCalendar = Calendar.getInstance();
+ tempCalendar.setTime(calendar.getTime());
+ this.calendar = tempCalendar;
+ this.current = DateUtils.isCurrentDate(calendar.getTime());
+ this.selected = false;
+ }
+
+ public boolean isBelongToMonth() {
+ return belongToMonth;
+ }
+
+ public void setBelongToMonth(boolean belongToMonth) {
+ this.belongToMonth = belongToMonth;
+ }
+
+ public boolean isCurrent() {
+ return current;
+ }
+
+ public void setCurrent(boolean current) {
+ this.current = current;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isWeekend() {
+ return weekend;
+ }
+
+ public void setWeekend(boolean weekend) {
+ this.weekend = weekend;
+ }
+
+ public boolean isFromConnectedCalendar() {
+ return fromConnectedCalendar;
+ }
+
+ public void setFromConnectedCalendar(boolean fromConnectedCalendar) {
+ this.fromConnectedCalendar = fromConnectedCalendar;
+ }
+
+ public boolean isSelectionCircleDrawed() {
+ return isSelectionCircleDrawed;
+ }
+
+ public void setSelectionCircleDrawed(boolean selectionCircleDrawed) {
+ isSelectionCircleDrawed = selectionCircleDrawed;
+ }
+
+ public SelectionState getSelectionState() {
+ return selectionState;
+ }
+
+ public void setSelectionState(SelectionState selectionState) {
+ this.selectionState = selectionState;
+ }
+
+ public int getConnectedDaysTextColor() {
+ return connectedDaysTextColor;
+ }
+
+ public void setConnectedDaysTextColor(int connectedDaysTextColor) {
+ this.connectedDaysTextColor = connectedDaysTextColor;
+ }
+
+ public int getConnectedDaysSelectedTextColor() {
+ return connectedDaysSelectedTextColor;
+ }
+
+ public void setConnectedDaysSelectedTextColor(int connectedDaysSelectedTextColor) {
+ this.connectedDaysSelectedTextColor = connectedDaysSelectedTextColor;
+ }
+
+ public int getConnectedDaysDisabledTextColor() {
+ return connectedDaysDisabledTextColor;
+ }
+
+ public void setConnectedDaysDisabledTextColor(int connectedDaysDisabledTextColor) {
+ this.connectedDaysDisabledTextColor = connectedDaysDisabledTextColor;
+ }
+
+ public Calendar getCalendar() {
+ return calendar;
+ }
+
+ public int getDayNumber() {
+ return calendar.get(Calendar.DAY_OF_MONTH);
+ }
+
+ @Override
+ public String toString() {
+ return "Day{day=" + calendar.getTime() + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Day day = (Day) o;
+ Calendar anotherCalendar = day.getCalendar();
+ return anotherCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR) &&
+ anotherCalendar.get(Calendar.DAY_OF_YEAR) == calendar.get(Calendar.DAY_OF_YEAR);
+ }
+
+ @Override
+ public int hashCode() {
+ return calendar != null ? calendar.hashCode() : 0;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
new file mode 100644
index 0000000..2366193
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
@@ -0,0 +1,10 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import java.util.Date;
+
+public class DayOfWeek extends Day {
+
+ public DayOfWeek(Date date) {
+ super(date);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java
new file mode 100644
index 0000000..00d2b09
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java
@@ -0,0 +1,56 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+
+public class Month {
+
+ private List days;
+ private Day firstDay;
+
+ public Month(Day firstDay, List days) {
+ this.days = days;
+ this.firstDay = firstDay;
+ }
+
+ public Day getFirstDay() {
+ return firstDay;
+ }
+
+ public void setFirstDay(Day firstDay) {
+ this.firstDay = firstDay;
+ }
+
+ public List getDays() {
+ return days;
+ }
+
+ /**
+ * Returns selected days that belong only to current month
+ *
+ * @return
+ */
+ public List getDaysWithoutTitlesAndOnlyCurrent() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(firstDay.getCalendar().getTime());
+ int currentMonth = calendar.get(Calendar.MONTH);
+
+ List result = new ArrayList<>();
+ for (Day day : days) {
+ calendar.setTime(day.getCalendar().getTime());
+ if (!(day instanceof DayOfWeek) && calendar.get(Calendar.MONTH) == currentMonth) {
+ result.add(day);
+ }
+ }
+ return result;
+ }
+
+ public String getMonthName() {
+ return new SimpleDateFormat("MMMM yyyy", Locale.getDefault()).format(firstDay.getCalendar().getTime());
+ }
+
+
+}
diff --git a/app/build.gradle b/app/build.gradle
index d819b69..8f07600 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,4 +97,6 @@
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//高德导航、定位、地图三合一
implementation 'com.amap.api:navi-3dmap:latest.integration'
+ //日期范围选择
+ implementation project(path: ':cosmocalendar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
new file mode 100644
index 0000000..edd5edc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Calendar.kt
@@ -0,0 +1,9 @@
+package com.casic.br.ktd.extensions
+
+import java.text.SimpleDateFormat
+import java.util.*
+
+fun Calendar.formatDate(): String {
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
+ return dateFormat.format(this.time)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
new file mode 100644
index 0000000..645d414
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/extensions/Dialog.kt
@@ -0,0 +1,21 @@
+package com.casic.br.ktd.extensions
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.WindowManager
+import androidx.annotation.StyleRes
+import com.pengxh.kt.lite.extensions.getScreenWidth
+
+fun Dialog.resetParams(gravity: Int, @StyleRes resId: Int, ratio: Double) {
+ val window = this.window ?: return
+ window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ window.setGravity(gravity)
+ //设置Dialog出现的动画
+ window.setWindowAnimations(resId)
+ val params = window.attributes
+ params.width = ((this.context.getScreenWidth() * ratio).toInt())
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ window.attributes = params
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
index b8941ed..dadedf1 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/AlarmPageFragment.kt
@@ -2,7 +2,9 @@
import android.os.Bundle
import com.casic.br.ktd.R
+import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.pengxh.kt.lite.base.KotlinBaseFragment
+import kotlinx.android.synthetic.main.fragment_alarm.*
class AlarmPageFragment : KotlinBaseFragment() {
override fun initData(savedInstanceState: Bundle?) {
@@ -10,7 +12,15 @@
}
override fun initEvent() {
-
+ calendarView.setOnClickListener {
+ DateRangeActionSheet.Builder().setContext(requireContext())
+ .setOnActionSheetListener(object :
+ DateRangeActionSheet.OnDateRangeSelectedListener {
+ override fun onDateRangeSelected(startDate: String, endDate: String) {
+ selectedDateView.text = "$startDate ~ $endDate"
+ }
+ }).build().show()
+ }
}
override fun initLayoutView(): Int = R.layout.fragment_alarm
diff --git a/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
new file mode 100644
index 0000000..4f693bf
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/widgets/DateRangeActionSheet.kt
@@ -0,0 +1,62 @@
+package com.casic.br.ktd.widgets
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import android.view.Gravity
+import com.casic.br.ktd.R
+import com.casic.br.ktd.extensions.formatDate
+import com.casic.br.ktd.extensions.resetParams
+import com.pengxh.kt.lite.extensions.show
+import kotlinx.android.synthetic.main.action_sheet_date_range.*
+
+class DateRangeActionSheet private constructor(builder: Builder) :
+ Dialog(builder.context, R.style.UserDefinedDialogStyle) {
+
+ private val listener = builder.listener
+
+ class Builder {
+ lateinit var context: Context
+ var listener: OnDateRangeSelectedListener? = null
+
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun setOnActionSheetListener(listener: OnDateRangeSelectedListener?): Builder {
+ this.listener = listener
+ return this
+ }
+
+ fun build(): DateRangeActionSheet {
+ return DateRangeActionSheet(this)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 0.5)
+ setContentView(R.layout.action_sheet_date_range)
+ setCancelable(true)
+ setCanceledOnTouchOutside(true)
+
+ selectedButton.setOnClickListener {
+ val selectedDates = calendarView.selectedDates
+ if (selectedDates.size == 0) {
+ "请选择正确的日期范围".show(context)
+ return@setOnClickListener
+ }
+ val startCalendar = selectedDates[0]
+ val endCalendar = selectedDates[selectedDates.size - 1]
+
+ listener?.onDateRangeSelected(startCalendar.formatDate(), endCalendar.formatDate())
+
+ dismiss()
+ }
+ }
+
+ interface OnDateRangeSelectedListener {
+ fun onDateRangeSelected(startDate: String, endDate: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/action_sheet_date_range.xml b/app/src/main/res/layout/action_sheet_date_range.xml
new file mode 100644
index 0000000..3f8a33d
--- /dev/null
+++ b/app/src/main/res/layout/action_sheet_date_range.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_alarm.xml b/app/src/main/res/layout/fragment_alarm.xml
index abba3c3..e32735c 100644
--- a/app/src/main/res/layout/fragment_alarm.xml
+++ b/app/src/main/res/layout/fragment_alarm.xml
@@ -1,11 +1,47 @@
-
+ android:layout_height="match_parent"
+ android:background="@color/backgroundColor"
+ android:orientation="vertical">
-
-
\ No newline at end of file
+ android:layout_marginHorizontal="@dimen/dp_30"
+ android:layout_marginTop="@dimen/dp_40"
+ android:layout_marginBottom="@dimen/dp_5">
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 0000000..c7a4344
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/calendar.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8166865..88145a3 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -13,4 +13,5 @@
#EEEEEE
#F7F7F7
#EEF1F6
+ #FFAAAAAA
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 6d5c45b..3b3e7e6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,8 @@
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/cosmocalendar/.gitignore b/cosmocalendar/.gitignore
new file mode 100644
index 0000000..ac68059
--- /dev/null
+++ b/cosmocalendar/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.idea
+.externalNativeBuild
\ No newline at end of file
diff --git a/cosmocalendar/build.gradle b/cosmocalendar/build.gradle
new file mode 100644
index 0000000..e828273
--- /dev/null
+++ b/cosmocalendar/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.library'
+
+ext {
+ bintrayRepo = 'maven'
+ bintrayName = 'cosmocalendar'
+
+ publishedGroupId = 'com.github.applikeysolutions'
+ libraryName = 'Cosmocalendar'
+ artifact = 'cosmocalendar'
+
+ libraryDescription = 'Customizable calendar on Android'
+
+ siteUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar'
+ gitUrl = 'https://github.com/AppliKeySolutions/CosmoCalendar.git'
+
+ libraryVersion = '1.0.4'
+
+ developerId = 'devilbrain666'
+ developerName = 'Ostapenko Yura'
+ developerEmail = 'ostapenko1990yura@gmail.com'
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0'
+}
+
+// Place it at the end of the file
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
+apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
diff --git a/cosmocalendar/proguard-rules.pro b/cosmocalendar/proguard-rules.pro
new file mode 100644
index 0000000..694733e
--- /dev/null
+++ b/cosmocalendar/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/deniskolesnik/dev/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
\ No newline at end of file
diff --git a/cosmocalendar/src/main/AndroidManifest.xml b/cosmocalendar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9f283e8
--- /dev/null
+++ b/cosmocalendar/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
new file mode 100644
index 0000000..983d690
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/FetchMonthsAsyncTask.java
@@ -0,0 +1,80 @@
+package com.applikeysolutions.cosmocalendar;
+
+import android.os.AsyncTask;
+
+import com.applikeysolutions.cosmocalendar.adapter.MonthAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Created by leonardo on 08/10/17.
+ */
+
+public class FetchMonthsAsyncTask extends AsyncTask> {
+
+ private boolean future;
+ private MonthAdapter monthAdapter;
+ private int defaultMonthCount;
+
+ @Override
+ protected List doInBackground(FetchParams... fetchParams) {
+ FetchParams params = fetchParams[0];
+ Month month = params.month;
+ future = params.future;
+ SettingsManager settingsManager = params.settingsManager;
+ monthAdapter = params.monthAdapter;
+ defaultMonthCount = params.defaultMonthCount;
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(month.getFirstDay().getCalendar().getTime());
+ final List result = new ArrayList<>();
+ for (int i = 0; i < SettingsManager.DEFAULT_MONTH_COUNT; i++) {
+ if (isCancelled())
+ break;
+
+ calendar.add(Calendar.MONTH, future ? 1 : -1);
+ Month newMonth = CalendarUtils.createMonth(calendar.getTime(), settingsManager);
+ if (future) {
+ result.add(newMonth);
+ } else {
+ result.add(0, newMonth);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List months) {
+ if (!months.isEmpty()) {
+ if (future) {
+ monthAdapter.getData().addAll(months);
+ monthAdapter.notifyItemRangeInserted(monthAdapter.getData().size() - 1, defaultMonthCount);
+ } else {
+ monthAdapter.getData().addAll(0, months);
+ monthAdapter.notifyItemRangeInserted(0, defaultMonthCount);
+ }
+ }
+ }
+
+ public static class FetchParams {
+ private final boolean future;
+ private final Month month;
+ private final SettingsManager settingsManager;
+ private final MonthAdapter monthAdapter;
+ private final int defaultMonthCount;
+
+ public FetchParams(boolean future, Month month, SettingsManager settingsManager, MonthAdapter monthAdapter, int defaultMonthCount) {
+ this.future = future;
+ this.month = month;
+ this.settingsManager = settingsManager;
+ this.monthAdapter = monthAdapter;
+ this.defaultMonthCount = defaultMonthCount;
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
new file mode 100644
index 0000000..0704b8f
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/DaysAdapter.java
@@ -0,0 +1,134 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.DayOfWeekHolder;
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.OtherDayHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+public class DaysAdapter extends RecyclerView.Adapter {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate otherDayDelegate;
+ private CalendarView calendarView;
+
+ private DaysAdapter(Month month,
+ DayOfWeekDelegate dayOfWeekDelegate,
+ DayDelegate dayDelegate,
+ OtherDayDelegate otherDayDelegate,
+ CalendarView calendarView) {
+ setHasStableIds(false);
+ this.month = month;
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ this.dayDelegate = dayDelegate;
+ this.otherDayDelegate = otherDayDelegate;
+ this.calendarView = calendarView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < Constants.DAYS_IN_WEEK && calendarView.isShowDaysOfWeek()) {
+ return ItemViewType.DAY_OF_WEEK;
+ }
+ if (month.getDays().get(position).isBelongToMonth()) {
+ return ItemViewType.MONTH_DAY;
+ } else {
+ return ItemViewType.OTHER_MONTH_DAY;
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ItemViewType.DAY_OF_WEEK:
+ return dayOfWeekDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.MONTH_DAY:
+ return dayDelegate.onCreateDayHolder(parent, viewType);
+ case ItemViewType.OTHER_MONTH_DAY:
+ return otherDayDelegate.onCreateDayHolder(parent, viewType);
+ default:
+ throw new IllegalArgumentException("Unknown view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final Day day = month.getDays().get(position);
+ switch (holder.getItemViewType()) {
+ case ItemViewType.DAY_OF_WEEK:
+ dayOfWeekDelegate.onBindDayHolder(day, (DayOfWeekHolder) holder, position);
+ break;
+ case ItemViewType.OTHER_MONTH_DAY:
+ otherDayDelegate.onBindDayHolder(day, (OtherDayHolder) holder, position);
+ break;
+ case ItemViewType.MONTH_DAY:
+ dayDelegate.onBindDayHolder(this, day, (DayHolder) holder, position);
+ break;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return month == null ? 0 : month.getDays().size();
+ }
+
+ public void setMonth(Month month) {
+ this.month = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return month.getDays().get(position).getCalendar().getTimeInMillis();
+ }
+
+ public static class DaysAdapterBuilder {
+
+ private Month month;
+ private DayOfWeekDelegate dayOfWeekDelegate;
+ private DayDelegate dayDelegate;
+ private OtherDayDelegate anotherDayDelegate;
+ private CalendarView calendarView;
+
+ public DaysAdapterBuilder setMonth(Month month) {
+ this.month = month;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayOfWeekDelegate(DayOfWeekDelegate dayOfWeekDelegate) {
+ this.dayOfWeekDelegate = dayOfWeekDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setDayDelegate(DayDelegate dayDelegate) {
+ this.dayDelegate = dayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setOtherDayDelegate(OtherDayDelegate anotherDayDelegate) {
+ this.anotherDayDelegate = anotherDayDelegate;
+ return this;
+ }
+
+ public DaysAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public DaysAdapter createDaysAdapter() {
+ return new DaysAdapter(month, dayOfWeekDelegate, dayDelegate, anotherDayDelegate, calendarView);
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
new file mode 100644
index 0000000..cc41f98
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/MonthAdapter.java
@@ -0,0 +1,170 @@
+package com.applikeysolutions.cosmocalendar.adapter;
+
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.viewholder.MonthHolder;
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.utils.DayFlag;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.ItemViewType;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.DayOfWeekDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.MonthDelegate;
+import com.applikeysolutions.cosmocalendar.view.delegate.OtherDayDelegate;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+public class MonthAdapter extends RecyclerView.Adapter {
+
+ private final List months;
+
+ private MonthDelegate monthDelegate;
+
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+ private DaysAdapter daysAdapter;
+
+ private MonthAdapter(List months,
+ MonthDelegate monthDelegate,
+ CalendarView calendarView,
+ BaseSelectionManager selectionManager) {
+ setHasStableIds(true);
+ this.months = months;
+ this.monthDelegate = monthDelegate;
+ this.calendarView = calendarView;
+ this.selectionManager = selectionManager;
+ }
+
+ public void setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public BaseSelectionManager getSelectionManager() {
+ return selectionManager;
+ }
+
+ @Override
+ public MonthHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ daysAdapter = new DaysAdapter.DaysAdapterBuilder()
+ .setDayOfWeekDelegate(new DayOfWeekDelegate(calendarView))
+ .setOtherDayDelegate(new OtherDayDelegate(calendarView))
+ .setDayDelegate(new DayDelegate(calendarView, this))
+ .setCalendarView(calendarView)
+ .createDaysAdapter();
+ return monthDelegate.onCreateMonthHolder(daysAdapter, parent, viewType);
+ }
+
+ @Override
+ public void onBindViewHolder(MonthHolder holder, int position) {
+ final Month month = months.get(position);
+ monthDelegate.onBindMonthHolder(month, holder, position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return months.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ItemViewType.MONTH;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return months.get(position).getFirstDay().getCalendar().getTimeInMillis();
+ }
+
+ public List getData() {
+ return months;
+ }
+
+ public static class MonthAdapterBuilder {
+
+ private List months;
+ private MonthDelegate monthDelegate;
+ private CalendarView calendarView;
+ private BaseSelectionManager selectionManager;
+
+ public MonthAdapterBuilder setMonths(List months) {
+ this.months = months;
+ return this;
+ }
+
+ public MonthAdapterBuilder setMonthDelegate(MonthDelegate monthHolderDelegate) {
+ this.monthDelegate = monthHolderDelegate;
+ return this;
+ }
+
+ public MonthAdapterBuilder setCalendarView(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ return this;
+ }
+
+ public MonthAdapterBuilder setSelectionManager(BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ return this;
+ }
+
+ public MonthAdapter createMonthAdapter() {
+ return new MonthAdapter(months,
+ monthDelegate,
+ calendarView,
+ selectionManager);
+ }
+ }
+
+ public void setWeekendDays(Set weekendDays) {
+ setDaysAccordingToSet(weekendDays, DayFlag.WEEKEND);
+ }
+
+ public void setDisabledDays(Set disabledDays) {
+ setDaysAccordingToSet(disabledDays, DayFlag.DISABLED);
+ }
+
+ public void setConnectedCalendarDays(Set connectedCalendarDays) {
+ setDaysAccordingToSet(connectedCalendarDays, DayFlag.FROM_CONNECTED_CALENDAR);
+ }
+
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria){
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ if(!day.isDisabled()){
+ day.setDisabled(CalendarUtils.isDayDisabledByCriteria(day, criteria));
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ private void setDaysAccordingToSet(Set days, DayFlag dayFlag) {
+ if (days != null && !days.isEmpty()) {
+ for (Month month : months) {
+ for (Day day : month.getDays()) {
+ switch (dayFlag) {
+ case WEEKEND:
+ day.setWeekend(days.contains(day.getCalendar().get(Calendar.DAY_OF_WEEK)));
+ break;
+
+ case DISABLED:
+ day.setDisabled(CalendarUtils.isDayInSet(day, days));
+ break;
+
+ case FROM_CONNECTED_CALENDAR:
+ day.setFromConnectedCalendar(CalendarUtils.isDayInSet(day, days));
+ break;
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
new file mode 100644
index 0000000..0c27221
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/BaseDayHolder.java
@@ -0,0 +1,19 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+
+public abstract class BaseDayHolder extends RecyclerView.ViewHolder {
+
+ protected TextView tvDay;
+ protected CalendarView calendarView;
+
+ public BaseDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView);
+ this.calendarView = calendarView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
new file mode 100644
index 0000000..a4a7329
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayHolder.java
@@ -0,0 +1,185 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.content.res.Resources;
+import android.view.View;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.selection.BaseSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.RangeSelectionManager;
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.settings.appearance.ConnectedDayIconPosition;
+import com.applikeysolutions.cosmocalendar.utils.CalendarUtils;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.cosmocalendar.view.customviews.CircleAnimationTextView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class DayHolder extends BaseDayHolder {
+
+ private CircleAnimationTextView ctvDay;
+ private BaseSelectionManager selectionManager;
+
+ public DayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ ctvDay = itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day, BaseSelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ ctvDay.setText(String.valueOf(day.getDayNumber()));
+
+ boolean isSelected = selectionManager.isDaySelected(day);
+ if (isSelected && !day.isDisabled()) {
+ select(day);
+ } else {
+ unselect(day);
+ }
+
+ if (day.isCurrent()) {
+ addCurrentDayIcon(isSelected);
+ }
+
+ if(day.isDisabled()){
+ ctvDay.setTextColor(calendarView.getDisabledDayTextColor());
+ }
+ }
+
+ private void addCurrentDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getCurrentDayIconHeight(isSelected)) * -1);
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getCurrentDaySelectedIconRes()
+ : calendarView.getCurrentDayIconRes(), 0, 0);
+ }
+
+ private int getCurrentDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getCurrentDayIconRes());
+ }
+ }
+
+ private int getConnectedDayIconHeight(boolean isSelected){
+ if (isSelected) {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDaySelectedIconRes());
+ } else {
+ return CalendarUtils.getIconHeight(calendarView.getContext().getResources(), calendarView.getConnectedDayIconRes());
+ }
+ }
+
+ private void select(Day day) {
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ ctvDay.setTextColor(day.getConnectedDaysDisabledTextColor());
+ } else {
+ ctvDay.setTextColor(day.getConnectedDaysSelectedTextColor());
+ }
+ addConnectedDayIcon(true);
+ } else {
+ ctvDay.setTextColor(calendarView.getSelectedDayTextColor());
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ SelectionState state;
+ if (selectionManager instanceof RangeSelectionManager) {
+ state = ((RangeSelectionManager) selectionManager).getSelectedState(day);
+ } else {
+ state = SelectionState.SINGLE_DAY;
+ }
+ animateDay(state, day);
+ }
+
+ private void addConnectedDayIcon(boolean isSelected){
+ ctvDay.setCompoundDrawablePadding(getPadding(getConnectedDayIconHeight(isSelected)) * -1);
+
+ switch (calendarView.getConnectedDayIconPosition()){
+ case ConnectedDayIconPosition.TOP:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes(), 0, 0);
+ break;
+
+ case ConnectedDayIconPosition.BOTTOM:
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, isSelected
+ ? calendarView.getConnectedDaySelectedIconRes()
+ : calendarView.getConnectedDayIconRes());
+ break;
+ }
+ }
+
+ private void animateDay(SelectionState state, Day day) {
+ if (day.getSelectionState() != state) {
+ if (day.isSelectionCircleDrawed() && state == SelectionState.SINGLE_DAY) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.START_RANGE_DAY) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else if (day.isSelectionCircleDrawed() && state == SelectionState.END_RANGE_DAY) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ } else {
+ switch (state) {
+ case SINGLE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsSingleCircle(calendarView);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case RANGE_DAY:
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ break;
+
+ case START_RANGE_DAY_WITHOUT_END:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircleWithoutEnd(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case START_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsStartCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+
+ case END_RANGE_DAY:
+ if (day.isSelectionCircleDrawed()) {
+ ctvDay.showAsEndCircle(calendarView, false);
+ } else {
+ ctvDay.setSelectionStateAndAnimate(state, calendarView, day);
+ }
+ break;
+ }
+ }
+ }
+
+ private void unselect(Day day) {
+ int textColor;
+ if (day.isFromConnectedCalendar()) {
+ if(day.isDisabled()){
+ textColor = day.getConnectedDaysDisabledTextColor();
+ } else {
+ textColor = day.getConnectedDaysTextColor();
+ }
+ addConnectedDayIcon(false);
+ } else if (day.isWeekend()) {
+ textColor = calendarView.getWeekendDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ textColor = calendarView.getDayTextColor();
+ ctvDay.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ day.setSelectionCircleDrawed(false);
+ ctvDay.setTextColor(textColor);
+ ctvDay.clearView();
+ }
+
+ private int getPadding(int iconHeight){
+ return (int) (iconHeight * Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
new file mode 100644
index 0000000..61f0914
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/DayOfWeekHolder.java
@@ -0,0 +1,28 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.utils.Constants;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+public class DayOfWeekHolder extends BaseDayHolder {
+
+ private SimpleDateFormat mDayOfWeekFormatter;
+
+ public DayOfWeekHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_name);
+ mDayOfWeekFormatter = new SimpleDateFormat(Constants.DAY_NAME_FORMAT, Locale.getDefault());
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(mDayOfWeekFormatter.format(day.getCalendar().getTime()));
+ tvDay.setTextColor(calendarView.getWeekDayTitleTextColor());
+ }
+}
\ No newline at end of file
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
new file mode 100644
index 0000000..7610290
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/MonthHolder.java
@@ -0,0 +1,53 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.applikeysolutions.cosmocalendar.adapter.DaysAdapter;
+import com.applikeysolutions.cosmocalendar.model.Month;
+import com.applikeysolutions.cosmocalendar.settings.SettingsManager;
+import com.applikeysolutions.cosmocalendar.view.MonthView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class MonthHolder extends RecyclerView.ViewHolder {
+
+ private LinearLayout llMonthHeader;
+ private TextView tvMonthName;
+ private View viewLeftLine;
+ private View viewRightLine;
+ private MonthView monthView;
+ private SettingsManager appearanceModel;
+
+ public MonthHolder(View itemView, SettingsManager appearanceModel) {
+ super(itemView);
+ llMonthHeader = (LinearLayout) itemView.findViewById(R.id.ll_month_header);
+ monthView = (MonthView) itemView.findViewById(R.id.month_view);
+ tvMonthName = (TextView) itemView.findViewById(R.id.tv_month_name);
+ viewLeftLine = itemView.findViewById(R.id.view_left_line);
+ viewRightLine = itemView.findViewById(R.id.view_right_line);
+ this.appearanceModel = appearanceModel;
+ }
+
+ public void setDayAdapter(DaysAdapter adapter) {
+ getMonthView().setAdapter(adapter);
+ }
+
+ public void bind(Month month) {
+ tvMonthName.setText(month.getMonthName());
+ tvMonthName.setTextColor(appearanceModel.getMonthTextColor());
+
+ viewLeftLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ viewRightLine.setVisibility(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? View.INVISIBLE : View.VISIBLE);
+ llMonthHeader.setBackgroundResource(appearanceModel.getCalendarOrientation() == OrientationHelper.HORIZONTAL ? R.drawable.border_top_bottom : 0);
+
+ monthView.initAdapter(month);
+ }
+
+ public MonthView getMonthView() {
+ return monthView;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
new file mode 100644
index 0000000..feeabad
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/adapter/viewholder/OtherDayHolder.java
@@ -0,0 +1,21 @@
+package com.applikeysolutions.cosmocalendar.adapter.viewholder;
+
+import android.view.View;
+import android.widget.TextView;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+public class OtherDayHolder extends BaseDayHolder {
+
+ public OtherDayHolder(View itemView, CalendarView calendarView) {
+ super(itemView, calendarView);
+ tvDay = (TextView) itemView.findViewById(R.id.tv_day_number);
+ }
+
+ public void bind(Day day) {
+ tvDay.setText(String.valueOf(day.getDayNumber()));
+ tvDay.setTextColor(calendarView.getOtherDayTextColor());
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
new file mode 100644
index 0000000..797afcd
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/CalendarDialog.java
@@ -0,0 +1,396 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+import com.applikeysolutions.cosmocalendar.settings.appearance.AppearanceInterface;
+import com.applikeysolutions.cosmocalendar.settings.date.DateInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.CalendarListsInterface;
+import com.applikeysolutions.cosmocalendar.settings.lists.DisabledDaysCriteria;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDays;
+import com.applikeysolutions.cosmocalendar.settings.lists.connected_days.ConnectedDaysManager;
+import com.applikeysolutions.cosmocalendar.settings.selection.SelectionInterface;
+import com.applikeysolutions.cosmocalendar.utils.SelectionType;
+import com.applikeysolutions.cosmocalendar.view.CalendarView;
+import com.applikeysolutions.customizablecalendar.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class CalendarDialog extends Dialog implements View.OnClickListener,
+ AppearanceInterface, DateInterface, CalendarListsInterface, SelectionInterface {
+
+ //Views
+ private FrameLayout flNavigationButtonsBar;
+ private ImageView ivCancel;
+ private ImageView ivDone;
+ private CalendarView calendarView;
+
+ private OnDaysSelectionListener onDaysSelectionListener;
+
+ public CalendarDialog(@NonNull Context context) {
+ super(context);
+ }
+
+ public CalendarDialog(@NonNull Context context, OnDaysSelectionListener onDaysSelectionListener) {
+ super(context);
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ setContentView(R.layout.dialog_calendar);
+ getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().getAttributes().gravity = Gravity.TOP;
+
+ initViews();
+ }
+
+ private void initViews() {
+ flNavigationButtonsBar = (FrameLayout) findViewById(R.id.fl_navigation_buttons_bar);
+ ivCancel = (ImageView) findViewById(R.id.iv_cancel);
+ ivDone = (ImageView) findViewById(R.id.iv_done);
+ calendarView = (CalendarView) findViewById(R.id.calendar_view);
+
+ Drawable background = calendarView.getBackground();
+
+ if (background instanceof ColorDrawable) {
+ flNavigationButtonsBar.setBackgroundColor(((ColorDrawable) background).getColor());
+ }
+
+ ivCancel.setOnClickListener(this);
+ ivDone.setOnClickListener(this);
+
+ }
+
+ public void setOnDaysSelectionListener(OnDaysSelectionListener onDaysSelectionListener) {
+ this.onDaysSelectionListener = onDaysSelectionListener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.iv_cancel) {
+ cancel();
+ } else if (id == R.id.iv_done) {
+ doneClick();
+ }
+ }
+
+ private void doneClick() {
+ List selectedDays = calendarView.getSelectedDays();
+ if (onDaysSelectionListener != null) {
+ onDaysSelectionListener.onDaysSelected(selectedDays);
+ }
+ dismiss();
+ }
+
+
+ @Override
+ @SelectionType
+ public int getSelectionType() {
+ return calendarView.getSelectionType();
+ }
+
+ @Override
+ public void setSelectionType(@SelectionType int selectionType) {
+ calendarView.setSelectionType(selectionType);
+ }
+
+ @Override
+ public int getCalendarBackgroundColor() {
+ return calendarView.getCalendarBackgroundColor();
+ }
+
+ @Override
+ public int getMonthTextColor() {
+ return calendarView.getMonthTextColor();
+ }
+
+ @Override
+ public int getOtherDayTextColor() {
+ return calendarView.getOtherDayTextColor();
+ }
+
+ @Override
+ public int getDayTextColor() {
+ return calendarView.getDayTextColor();
+ }
+
+ @Override
+ public int getWeekendDayTextColor() {
+ return calendarView.getWeekendDayTextColor();
+ }
+
+ @Override
+ public int getWeekDayTitleTextColor() {
+ return calendarView.getWeekDayTitleTextColor();
+ }
+
+ @Override
+ public int getSelectedDayTextColor() {
+ return calendarView.getSelectedDayTextColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundColor() {
+ return calendarView.getSelectedDayBackgroundColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundStartColor() {
+ return calendarView.getSelectedDayBackgroundStartColor();
+ }
+
+ @Override
+ public int getSelectedDayBackgroundEndColor() {
+ return calendarView.getSelectedDayBackgroundEndColor();
+ }
+
+ @Override
+ public int getCurrentDayTextColor() {
+ return calendarView.getCurrentDayTextColor();
+ }
+
+ @Override
+ public int getCurrentDayIconRes() {
+ return calendarView.getCurrentDayIconRes();
+ }
+
+ @Override
+ public int getCurrentDaySelectedIconRes() {
+ return calendarView.getCurrentDaySelectedIconRes();
+ }
+
+ @Override
+ public int getCalendarOrientation() {
+ return calendarView.getCalendarOrientation();
+ }
+
+ @Override
+ public int getConnectedDayIconRes() {
+ return calendarView.getConnectedDayIconRes();
+ }
+
+ @Override
+ public int getConnectedDaySelectedIconRes() {
+ return calendarView.getConnectedDaySelectedIconRes();
+ }
+
+ @Override
+ public int getConnectedDayIconPosition() {
+ return calendarView.getConnectedDayIconPosition();
+ }
+
+ @Override
+ public int getDisabledDayTextColor() {
+ return calendarView.getDisabledDayTextColor();
+ }
+
+ @Override
+ public int getSelectionBarMonthTextColor() {
+ return calendarView.getSelectionBarMonthTextColor();
+ }
+
+ @Override
+ public int getPreviousMonthIconRes() {
+ return calendarView.getPreviousMonthIconRes();
+ }
+
+ @Override
+ public int getNextMonthIconRes() {
+ return calendarView.getNextMonthIconRes();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeek() {
+ return calendarView.isShowDaysOfWeek();
+ }
+
+ @Override
+ public boolean isShowDaysOfWeekTitle() {
+ return calendarView.isShowDaysOfWeekTitle();
+ }
+
+ @Override
+ public void setCalendarBackgroundColor(int calendarBackgroundColor) {
+ calendarView.setCalendarBackgroundColor(calendarBackgroundColor);
+ }
+
+ @Override
+ public void setMonthTextColor(int monthTextColor) {
+ calendarView.setMonthTextColor(monthTextColor);
+ }
+
+ @Override
+ public void setOtherDayTextColor(int otherDayTextColor) {
+ calendarView.setOtherDayTextColor(otherDayTextColor);
+ }
+
+ @Override
+ public void setDayTextColor(int dayTextColor) {
+ calendarView.setDayTextColor(dayTextColor);
+ }
+
+ @Override
+ public void setWeekendDayTextColor(int weekendDayTextColor) {
+ calendarView.setWeekendDayTextColor(weekendDayTextColor);
+ }
+
+ @Override
+ public void setWeekDayTitleTextColor(int weekDayTitleTextColor) {
+ calendarView.setWeekDayTitleTextColor(weekDayTitleTextColor);
+ }
+
+ @Override
+ public void setSelectedDayTextColor(int selectedDayTextColor) {
+ calendarView.setSelectedDayTextColor(selectedDayTextColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundColor(int selectedDayBackgroundColor) {
+ calendarView.setSelectedDayBackgroundColor(selectedDayBackgroundColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundStartColor(int selectedDayBackgroundStartColor) {
+ calendarView.setSelectedDayBackgroundStartColor(selectedDayBackgroundStartColor);
+ }
+
+ @Override
+ public void setSelectedDayBackgroundEndColor(int selectedDayBackgroundEndColor) {
+ calendarView.setSelectedDayBackgroundEndColor(selectedDayBackgroundEndColor);
+ }
+
+ @Override
+ public void setCurrentDayTextColor(int currentDayTextColor) {
+ calendarView.setCurrentDayTextColor(currentDayTextColor);
+ }
+
+ @Override
+ public void setCurrentDayIconRes(int currentDayIconRes) {
+ calendarView.setCurrentDayIconRes(currentDayIconRes);
+ }
+
+ @Override
+ public void setCurrentDaySelectedIconRes(int currentDaySelectedIconRes) {
+ calendarView.setCurrentDaySelectedIconRes(currentDaySelectedIconRes);
+ }
+
+ @Override
+ public void setCalendarOrientation(int calendarOrientation) {
+ calendarView.setCalendarOrientation(calendarOrientation);
+ }
+
+ @Override
+ public void setConnectedDayIconRes(int connectedDayIconRes) {
+ calendarView.setConnectedDayIconRes(connectedDayIconRes);
+ }
+
+ @Override
+ public void setConnectedDaySelectedIconRes(int connectedDaySelectedIconRes) {
+ calendarView.setConnectedDaySelectedIconRes(connectedDaySelectedIconRes);
+ }
+
+ @Override
+ public void setConnectedDayIconPosition(int connectedDayIconPosition) {
+ calendarView.setConnectedDayIconPosition(connectedDayIconPosition);
+ }
+
+ @Override
+ public void setDisabledDayTextColor(int disabledDayTextColor) {
+ calendarView.setDisabledDayTextColor(disabledDayTextColor);
+ }
+
+ @Override
+ public void setSelectionBarMonthTextColor(int selectionBarMonthTextColor) {
+ calendarView.setSelectionBarMonthTextColor(selectionBarMonthTextColor);
+ }
+
+ @Override
+ public void setPreviousMonthIconRes(int previousMonthIconRes) {
+ calendarView.setPreviousMonthIconRes(previousMonthIconRes);
+ }
+
+ @Override
+ public void setNextMonthIconRes(int nextMonthIconRes) {
+ calendarView.setNextMonthIconRes(nextMonthIconRes);
+ }
+
+ @Override
+ public void setShowDaysOfWeek(boolean showDaysOfWeek) {
+ calendarView.setShowDaysOfWeek(showDaysOfWeek);
+ }
+
+ @Override
+ public void setShowDaysOfWeekTitle(boolean showDaysOfWeekTitle) {
+ calendarView.setShowDaysOfWeekTitle(showDaysOfWeekTitle);
+ }
+
+ @Override
+ public Set getDisabledDays() {
+ return calendarView.getDisabledDays();
+ }
+
+ @Override
+ public ConnectedDaysManager getConnectedDaysManager() {
+ return calendarView.getConnectedDaysManager();
+ }
+
+ @Override
+ public Set getWeekendDays() {
+ return calendarView.getWeekendDays();
+ }
+
+ @Override
+ public DisabledDaysCriteria getDisabledDaysCriteria() {
+ return calendarView.getDisabledDaysCriteria();
+ }
+
+ @Override
+ public void setDisabledDays(Set disabledDays) {
+ calendarView.setDisabledDays(disabledDays);
+ }
+
+ @Override
+ public void setWeekendDays(Set weekendDays) {
+ calendarView.setWeekendDays(weekendDays);
+ }
+
+ @Override
+ public void setDisabledDaysCriteria(DisabledDaysCriteria criteria) {
+ calendarView.setDisabledDaysCriteria(criteria);
+ }
+
+ @Override
+ public void addConnectedDays(ConnectedDays connectedDays) {
+ calendarView.addConnectedDays(connectedDays);
+ }
+
+ @Override
+ public int getFirstDayOfWeek() {
+ return calendarView.getFirstDayOfWeek();
+ }
+
+ @Override
+ public void setFirstDayOfWeek(int firstDayOfWeek) {
+ calendarView.setFirstDayOfWeek(firstDayOfWeek);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
new file mode 100644
index 0000000..ded8cae
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/dialog/OnDaysSelectionListener.java
@@ -0,0 +1,9 @@
+package com.applikeysolutions.cosmocalendar.dialog;
+
+import com.applikeysolutions.cosmocalendar.model.Day;
+
+import java.util.List;
+
+public interface OnDaysSelectionListener {
+ void onDaysSelected(List selectedDays);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
new file mode 100644
index 0000000..1ce1599
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/listeners/OnMonthChangeListener.java
@@ -0,0 +1,8 @@
+package com.applikeysolutions.cosmocalendar.listeners;
+
+import com.applikeysolutions.cosmocalendar.model.Month;
+
+public interface OnMonthChangeListener {
+
+ void onMonthChanged(Month month);
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
new file mode 100644
index 0000000..b266532
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Day.java
@@ -0,0 +1,161 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import com.applikeysolutions.cosmocalendar.selection.SelectionState;
+import com.applikeysolutions.cosmocalendar.utils.DateUtils;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class Day {
+
+ private Calendar calendar;
+ private boolean belongToMonth;
+ private boolean current;
+ private boolean selected;
+ private boolean disabled;
+ private boolean weekend;
+
+ //Connected days
+ private boolean fromConnectedCalendar;
+ private int connectedDaysTextColor;
+ private int connectedDaysSelectedTextColor;
+ private int connectedDaysDisabledTextColor;
+
+ //For animation states
+ private SelectionState selectionState;
+ private boolean isSelectionCircleDrawed;
+
+ public Day(Date date) {
+ this.calendar = DateUtils.getCalendar(date);
+ this.current = DateUtils.isCurrentDate(date);
+ this.selected = false;
+ }
+
+ public Day(Calendar calendar) {
+ Calendar tempCalendar = Calendar.getInstance();
+ tempCalendar.setTime(calendar.getTime());
+ this.calendar = tempCalendar;
+ this.current = DateUtils.isCurrentDate(calendar.getTime());
+ this.selected = false;
+ }
+
+ public boolean isBelongToMonth() {
+ return belongToMonth;
+ }
+
+ public void setBelongToMonth(boolean belongToMonth) {
+ this.belongToMonth = belongToMonth;
+ }
+
+ public boolean isCurrent() {
+ return current;
+ }
+
+ public void setCurrent(boolean current) {
+ this.current = current;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isWeekend() {
+ return weekend;
+ }
+
+ public void setWeekend(boolean weekend) {
+ this.weekend = weekend;
+ }
+
+ public boolean isFromConnectedCalendar() {
+ return fromConnectedCalendar;
+ }
+
+ public void setFromConnectedCalendar(boolean fromConnectedCalendar) {
+ this.fromConnectedCalendar = fromConnectedCalendar;
+ }
+
+ public boolean isSelectionCircleDrawed() {
+ return isSelectionCircleDrawed;
+ }
+
+ public void setSelectionCircleDrawed(boolean selectionCircleDrawed) {
+ isSelectionCircleDrawed = selectionCircleDrawed;
+ }
+
+ public SelectionState getSelectionState() {
+ return selectionState;
+ }
+
+ public void setSelectionState(SelectionState selectionState) {
+ this.selectionState = selectionState;
+ }
+
+ public int getConnectedDaysTextColor() {
+ return connectedDaysTextColor;
+ }
+
+ public void setConnectedDaysTextColor(int connectedDaysTextColor) {
+ this.connectedDaysTextColor = connectedDaysTextColor;
+ }
+
+ public int getConnectedDaysSelectedTextColor() {
+ return connectedDaysSelectedTextColor;
+ }
+
+ public void setConnectedDaysSelectedTextColor(int connectedDaysSelectedTextColor) {
+ this.connectedDaysSelectedTextColor = connectedDaysSelectedTextColor;
+ }
+
+ public int getConnectedDaysDisabledTextColor() {
+ return connectedDaysDisabledTextColor;
+ }
+
+ public void setConnectedDaysDisabledTextColor(int connectedDaysDisabledTextColor) {
+ this.connectedDaysDisabledTextColor = connectedDaysDisabledTextColor;
+ }
+
+ public Calendar getCalendar() {
+ return calendar;
+ }
+
+ public int getDayNumber() {
+ return calendar.get(Calendar.DAY_OF_MONTH);
+ }
+
+ @Override
+ public String toString() {
+ return "Day{day=" + calendar.getTime() + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Day day = (Day) o;
+ Calendar anotherCalendar = day.getCalendar();
+ return anotherCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR) &&
+ anotherCalendar.get(Calendar.DAY_OF_YEAR) == calendar.get(Calendar.DAY_OF_YEAR);
+ }
+
+ @Override
+ public int hashCode() {
+ return calendar != null ? calendar.hashCode() : 0;
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
new file mode 100644
index 0000000..2366193
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/DayOfWeek.java
@@ -0,0 +1,10 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import java.util.Date;
+
+public class DayOfWeek extends Day {
+
+ public DayOfWeek(Date date) {
+ super(date);
+ }
+}
diff --git a/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java
new file mode 100644
index 0000000..00d2b09
--- /dev/null
+++ b/cosmocalendar/src/main/java/com/applikeysolutions/cosmocalendar/model/Month.java
@@ -0,0 +1,56 @@
+package com.applikeysolutions.cosmocalendar.model;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+
+public class Month {
+
+ private List days;
+ private Day firstDay;
+
+ public Month(Day firstDay, List days) {
+ this.days = days;
+ this.firstDay = firstDay;
+ }
+
+ public Day getFirstDay() {
+ return firstDay;
+ }
+
+ public void setFirstDay(Day firstDay) {
+ this.firstDay = firstDay;
+ }
+
+ public List getDays() {
+ return days;
+ }
+
+ /**
+ * Returns selected days that belong only to current month
+ *
+ * @return
+ */
+ public List getDaysWithoutTitlesAndOnlyCurrent() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(firstDay.getCalendar().getTime());
+ int currentMonth = calendar.get(Calendar.MONTH);
+
+ List