diff --git a/app/src/main/java/com/dt/calendarwork/MainActivity.kt b/app/src/main/java/com/dt/calendarwork/MainActivity.kt index 3b9c37b..e44303a 100644 --- a/app/src/main/java/com/dt/calendarwork/MainActivity.kt +++ b/app/src/main/java/com/dt/calendarwork/MainActivity.kt @@ -6,7 +6,9 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -34,38 +36,52 @@ class MainActivity : ComponentActivity() { @Composable fun MainScreen() { val calendar = Calendar.getInstance() - calendar.set(Calendar.YEAR, 2021) - calendar.set(Calendar.MONTH, 5) + calendar.set(Calendar.YEAR, 2022) + calendar.set(Calendar.MONTH, 1) calendar.set(Calendar.DAY_OF_MONTH, 1) val calendarMax = Calendar.getInstance() - calendarMax.set(Calendar.YEAR, 2022) + calendarMax.set(Calendar.YEAR, 2023) calendarMax.set(Calendar.MONTH, 0) - calendar.set(Calendar.DAY_OF_MONTH, 1) + calendarMax.set(Calendar.DAY_OF_MONTH, 1) + + val initialCalendar = Calendar.getInstance() + initialCalendar.set(Calendar.YEAR, 2022) + initialCalendar.set(Calendar.MONTH, 3) + initialCalendar.set(Calendar.DAY_OF_MONTH, 1) val (open, setOpen) = remember { mutableStateOf(true) } - Box(Modifier - .fillMaxSize() - .background(color = Color.Gray), contentAlignment = Alignment.Center) { + Box( + modifier = Modifier + .fillMaxSize() + .background(color = Color.Gray), + contentAlignment = Alignment.Center + ) { if (open) { - ComposeCalendar( - minDate = calendar.time, - maxDate = calendarMax.time, - locale = Locale("en"), - title = "Select Date", - monthViewType = MonthViewType.ONLY_NUMBER_ONE_COLUMN, - listener = object : SelectDateListener { - override fun onDateSelected(date: Date) { - Log.i("DENEME", date.toString()) - } + Box( + Modifier + .fillMaxWidth(0.8f) + .fillMaxHeight(0.7f)) { + ComposeCalendar( + minDate = calendar.time, + maxDate = calendarMax.time, + initialDate = initialCalendar.time, + locale = Locale("en"), + title = "Select Date", + monthViewType = MonthViewType.ONLY_NUMBER_ONE_COLUMN, + listener = object : SelectDateListener { + override fun onDateSelected(date: Date) { + Log.i("DENEME", date.toString()) + } - override fun onCanceled() { - setOpen(false) - } - }) + override fun onCanceled() { + setOpen(false) + } + }) + } } } } diff --git a/library/src/main/java/com/dt/composedatepicker/CalendarBottom.kt b/library/src/main/java/com/dt/composedatepicker/CalendarBottom.kt index 7e8608e..4e3eab4 100644 --- a/library/src/main/java/com/dt/composedatepicker/CalendarBottom.kt +++ b/library/src/main/java/com/dt/composedatepicker/CalendarBottom.kt @@ -3,21 +3,30 @@ package com.dt.composedatepicker import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @Composable -fun CalendarBottom(onPositiveClick: () -> Unit, onCancelClick: () -> Unit,themeColor:Color,negativeButtonTitle:String,positiveButtonTitle:String) { - Row(modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 40.dp) - .padding(vertical = 20.dp), - horizontalArrangement = Arrangement.End) { +fun CalendarBottom( + onPositiveClick: () -> Unit, + onCancelClick: () -> Unit, + themeColor: Color, + negativeButtonTitle: String, + positiveButtonTitle: String +) { + Row( + modifier = Modifier + .fillMaxSize() + .padding(end = 20.dp), + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically + ) { Text(text = negativeButtonTitle, color = themeColor, modifier = Modifier diff --git a/library/src/main/java/com/dt/composedatepicker/CalendarMonthView.kt b/library/src/main/java/com/dt/composedatepicker/CalendarMonthView.kt index 806de89..c5bb317 100644 --- a/library/src/main/java/com/dt/composedatepicker/CalendarMonthView.kt +++ b/library/src/main/java/com/dt/composedatepicker/CalendarMonthView.kt @@ -3,7 +3,13 @@ package com.dt.composedatepicker import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape @@ -13,39 +19,41 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.unit.dp -import java.util.* @Composable fun CalendarMonthView( - monthList:List, + monthList: List, selectedMonth: MonthData, setMonth: (MonthData) -> Unit, minMonth: Int, maxMonth: Int, - minYear:Int, - maxYear:Int, - selectedYear:Int, - setShowMonths:(Boolean)->Unit, - setHeight:(Int)->Unit, - showOnlyMonth:Boolean, - themeColor:Color, + minYear: Int, + maxYear: Int, + selectedYear: Int, + setShowMonths: (Boolean) -> Unit, + showOnlyMonth: Boolean, + themeColor: Color, monthViewType: MonthViewType? ) { val NUMBER_OF_ROW_ITEMS = 3 var numberOfElement = 0 - LazyColumn(modifier = Modifier - .padding(horizontal = 20.dp) - .padding(vertical = 20.dp) - .onGloballyPositioned { setHeight(it.size.height) }) { + LazyColumn( + modifier = Modifier + .fillMaxHeight(0.85f) + .fillMaxWidth() + .padding(10.dp) + ) { items(items = monthList.chunked(NUMBER_OF_ROW_ITEMS)) { rowItems -> - Row(modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { for ((index, item) in rowItems.withIndex()) { - MonthItem(month = item, + MonthItem( + month = item, index = index, numberOfElement = numberOfElement, rowSize = NUMBER_OF_ROW_ITEMS, @@ -83,44 +91,70 @@ fun MonthItem( selectedYear: Int, setShowMonths: (Boolean) -> Unit, showOnlyMonth: Boolean, - themeColor:Color, + themeColor: Color, monthViewType: MonthViewType? ) { - val enabled = checkDate(minYear = minYear,maxYear = maxYear,selectedYear = selectedYear,maxMonth = maxMonth,minMonth = minMonth,numberOfElement = numberOfElement) - val monthText:String = when(monthViewType){ + val enabled = checkDate( + minYear = minYear, + maxYear = maxYear, + selectedYear = selectedYear, + maxMonth = maxMonth, + minMonth = minMonth, + numberOfElement = numberOfElement + ) + val monthText: String = when (monthViewType) { MonthViewType.ONLY_MONTH -> month.name.uppercase() MonthViewType.ONLY_NUMBER -> numberOfElement.plus(1).toString() - MonthViewType.BOTH_NUMBER_AND_MONTH -> month.name.uppercase() + " " + "(${numberOfElement.plus(1)})" + MonthViewType.BOTH_NUMBER_AND_MONTH -> month.name.uppercase() + " " + "(${ + numberOfElement.plus( + 1 + ) + })" else -> month.name.uppercase() } - Box(modifier = Modifier - .background(color = if (month.name == selectedMonth) themeColor else Color.Transparent, - shape = RoundedCornerShape(100)) - .fillMaxWidth(1f / (rowSize - index + 1f)) - .aspectRatio(1f) - .clickable(indication = null, - interactionSource = remember { MutableInteractionSource() }, - enabled = enabled) { - setMonth(month) - if (!showOnlyMonth) { - setShowMonths(false) - } - }, - contentAlignment = Alignment.Center) { - Text(text = monthText, + Box( + modifier = Modifier + .background( + color = if (month.name == selectedMonth) themeColor else Color.Transparent, + shape = RoundedCornerShape(100) + ) + .fillMaxWidth(1f / (rowSize - index + 1f)) + .aspectRatio(1f) + .clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() }, + enabled = enabled + ) { + setMonth(month) + if (!showOnlyMonth) { + setShowMonths(false) + } + }, + contentAlignment = Alignment.Center + ) { + Text( + text = monthText, color = if (enabled && month.name == selectedMonth) Color.White else if (enabled) Color.Black - else Color.Gray) + else Color.Gray + ) } } -private fun checkDate(minYear: Int,maxYear: Int,selectedYear: Int,minMonth: Int,maxMonth: Int,numberOfElement: Int):Boolean{ + +private fun checkDate( + minYear: Int, + maxYear: Int, + selectedYear: Int, + minMonth: Int, + maxMonth: Int, + numberOfElement: Int +): Boolean { if (minYear == maxYear) return numberOfElement in minMonth..maxMonth - if (selectedYear==minYear){ - return numberOfElement>=minMonth - } - else if (selectedYear==maxYear) { - if (numberOfElement>maxMonth) return false + if (selectedYear == minYear) { + return numberOfElement >= minMonth + } else if (selectedYear == maxYear) { + if (numberOfElement > maxMonth) return false } return true } \ No newline at end of file diff --git a/library/src/main/java/com/dt/composedatepicker/CalendarMonthViewOneColumn.kt b/library/src/main/java/com/dt/composedatepicker/CalendarMonthViewOneColumn.kt index dfb76fc..c12eadd 100644 --- a/library/src/main/java/com/dt/composedatepicker/CalendarMonthViewOneColumn.kt +++ b/library/src/main/java/com/dt/composedatepicker/CalendarMonthViewOneColumn.kt @@ -14,7 +14,6 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -29,18 +28,17 @@ fun CalendarMonthViewOneColumn( maxYear: Int, selectedYear: Int, setShowMonths: (Boolean) -> Unit, - setHeight: (Int) -> Unit, showOnlyMonth: Boolean, themeColor: Color, ) { - LazyColumn(modifier = Modifier - .padding(horizontal = 20.dp) - .padding(vertical = 20.dp) - .fillMaxHeight(0.7f) - .fillMaxWidth() - .onGloballyPositioned { setHeight(it.size.height) }, - horizontalAlignment = Alignment.CenterHorizontally) { + LazyColumn( + modifier = Modifier + .fillMaxHeight(0.85f) + .fillMaxWidth() + .padding(10.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { items(items = monthList) { item -> MonthItemOneColumn( month = item, @@ -75,28 +73,34 @@ fun MonthItemOneColumn( showOnlyMonth: Boolean, themeColor: Color, ) { - val enabled = checkDate(minYear = minYear, + val enabled = checkDate( + minYear = minYear, maxYear = maxYear, selectedYear = selectedYear, maxMonth = maxMonth, minMonth = minMonth, - numberOfElement = index) + numberOfElement = index + ) Box(modifier = Modifier .padding(vertical = 6.dp) - .clickable(indication = null, + .clickable( + indication = null, interactionSource = remember { MutableInteractionSource() }, - enabled = enabled) { + enabled = enabled + ) { setMonth(month) if (!showOnlyMonth) { setShowMonths(false) } }) { - Text(text = index.plus(1).toString(), + Text( + text = index.plus(1).toString(), fontSize = if (month.name == selectedMonth) 35.sp else 30.sp, color = if (enabled && month.name == selectedMonth) themeColor else if (enabled) Color.Black - else Color.Gray) + else Color.Gray + ) } } diff --git a/library/src/main/java/com/dt/composedatepicker/CalendarYearView.kt b/library/src/main/java/com/dt/composedatepicker/CalendarYearView.kt index dc6babf..df61227 100644 --- a/library/src/main/java/com/dt/composedatepicker/CalendarYearView.kt +++ b/library/src/main/java/com/dt/composedatepicker/CalendarYearView.kt @@ -1,10 +1,9 @@ package com.dt.composedatepicker -import android.util.DisplayMetrics import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState @@ -14,7 +13,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.launch @@ -25,20 +23,21 @@ fun CalendarYearView( setYear: (Int) -> Unit, minYear: Int, maxYear: Int, - height: Int, - themeColor:Color + themeColor: Color ) { val years = IntRange(minYear, maxYear).toList() val listState = rememberLazyListState() val scope = rememberCoroutineScope() val selectedIndex = years.indexOf(selectedYear) - val metrics = LocalContext.current.resources.displayMetrics - val mHeight = (if (height==0) 5*(metrics.heightPixels)/10 else height) / (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT) - LazyColumn(state = listState, modifier = Modifier - .fillMaxWidth() - .requiredHeight((mHeight + 40).dp) //40dp for padding in MonthView - ,horizontalAlignment = Alignment.CenterHorizontally) { + LazyColumn( + state = listState, + modifier = Modifier + .fillMaxHeight(0.85f) + .fillMaxWidth() + .padding(10.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { items(years) { year -> Text(text = year.toString(), fontSize = if (year == selectedYear) 35.sp else 30.sp, diff --git a/library/src/main/java/com/dt/composedatepicker/ComposeCalendar.kt b/library/src/main/java/com/dt/composedatepicker/ComposeCalendar.kt index c53ab4b..44f7bd2 100644 --- a/library/src/main/java/com/dt/composedatepicker/ComposeCalendar.kt +++ b/library/src/main/java/com/dt/composedatepicker/ComposeCalendar.kt @@ -2,7 +2,7 @@ package com.dt.composedatepicker import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.Card import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -13,20 +13,22 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import java.text.DateFormatSymbols +import java.time.Year import java.util.* @Composable fun ComposeCalendar( minDate: Date? = null, maxDate: Date? = null, + initialDate: Date? = null, locale: Locale = Locale.getDefault(), title: String = "", listener: SelectDateListener, showOnlyMonth: Boolean = false, showOnlyYear: Boolean = false, - themeColor:Color = Color(0xFF614FF0), - negativeButtonTitle:String = "CANCEL", - positiveButtonTitle:String = "OK", + themeColor: Color = Color(0xFF614FF0), + negativeButtonTitle: String = "CANCEL", + positiveButtonTitle: String = "OK", monthViewType: MonthViewType? = MonthViewType.ONLY_MONTH ) { if (showOnlyMonth && showOnlyYear) { @@ -37,6 +39,11 @@ fun ComposeCalendar( var minMonth = 0 var maxYear = 2100 var maxMonth = 11 + + var initialCalendar = Calendar.getInstance(locale) + var currentMonth = initialCalendar.get(Calendar.MONTH) + var currentYear = initialCalendar.get(Calendar.YEAR) + minDate?.let { val calendarMin = Calendar.getInstance() calendarMin.time = minDate @@ -49,19 +56,17 @@ fun ComposeCalendar( maxMonth = calendarMax.get(Calendar.MONTH) maxYear = calendarMax.get(Calendar.YEAR) } - - val (height, setHeight) = remember { - mutableStateOf(0) + initialDate?.let { + initialCalendar.time = initialDate + currentMonth = initialCalendar.get(Calendar.MONTH) + currentYear = initialCalendar.get(Calendar.YEAR) } - val calendar = Calendar.getInstance(locale) - val currentMonth = calendar.get(Calendar.MONTH) - var currentYear = calendar.get(Calendar.YEAR) - if (minYear>currentYear){ + if (minYear > currentYear) { currentYear = minYear } - if (maxYear { - if (monthViewType == MonthViewType.ONLY_NUMBER_ONE_COLUMN){ - CalendarMonthViewOneColumn(selectedMonth = selectedMonth, + if (monthViewType == MonthViewType.ONLY_NUMBER_ONE_COLUMN) { + CalendarMonthViewOneColumn( + selectedMonth = selectedMonth, setMonth = setMonth, minMonth = minMonth, maxMonth = maxMonth, @@ -130,13 +142,12 @@ fun ComposeCalendar( maxYear = maxYear, selectedYear = selectedYear, monthList = monthList, - setHeight = setHeight, showOnlyMonth = showOnlyMonth, - themeColor=themeColor + themeColor = themeColor ) - } - else{ - CalendarMonthView(selectedMonth = selectedMonth, + } else { + CalendarMonthView( + selectedMonth = selectedMonth, setMonth = setMonth, minMonth = minMonth, maxMonth = maxMonth, @@ -145,29 +156,33 @@ fun ComposeCalendar( maxYear = maxYear, selectedYear = selectedYear, monthList = monthList, - setHeight = setHeight, showOnlyMonth = showOnlyMonth, - themeColor=themeColor, - monthViewType = monthViewType) + themeColor = themeColor, + monthViewType = monthViewType + ) } } - false -> CalendarYearView(selectedYear = selectedYear, + false -> CalendarYearView( + selectedYear = selectedYear, setYear = setYear, minYear = minYear, maxYear = maxYear, - height = height, - themeColor=themeColor) + themeColor = themeColor + ) } } - CalendarBottom(onPositiveClick = { listener.onDateSelected(selectedDate) }, + CalendarBottom( + onPositiveClick = { listener.onDateSelected(selectedDate) }, onCancelClick = { listener.onCanceled() }, - themeColor=themeColor, - negativeButtonTitle=negativeButtonTitle, - positiveButtonTitle=positiveButtonTitle) + themeColor = themeColor, + negativeButtonTitle = negativeButtonTitle, + positiveButtonTitle = positiveButtonTitle + ) } } } } + enum class MonthViewType { ONLY_MONTH, ONLY_NUMBER,