Home > Mobile >  Is there a way to make a scrollable calendar
Is there a way to make a scrollable calendar

Time:04-12

I have this calendar I'm working on in jetpack compose. I have gotten some help with placement in rows and stuff like that using weight. The problem is though that I'm trying to make an item of a month in the calendar and place that in a LazyRow but i think it has to do with that lazy rows are scrollable so the weight function for the box with the text in it makes it so that no text shows up if the code looks like this...

fun CalendarRowItem(calendarSize: Int, initWeekday: Int, textColor: Color, clickedColor: Color){
    var dayCounter: Int = 1
    var week: Int = 1
    var _initWeekday = initWeekday

    Column() {
         while(dayCounter <= calendarSize){
            Row(modifier = Modifier.fillMaxWidth().padding(5.dp)) {
                if(initWeekday > 0){
                    repeat(initWeekday){
                        Spacer(modifier = Modifier.weight(1f))
                    }
                }
                for (i in week..(7 - _initWeekday)){
                    if(dayCounter <= 31){
                        Box(
                            contentAlignment = Alignment.Center,
                            modifier = Modifier
                                .padding(10.dp)
                                .background(clickedColor, CircleShape)
                                .clickable { }
                        ) {
                            Text(text = dayCounter  .toString(), color = textColor )
                        }

                    }else{
                        Spacer(modifier = Modifier.weight(1f))
                    }
                    _initWeekday = 0
                }
            }
        }
    }
}

but without the weight i cant place the dates correctly plus i have no clue how i would make it so that only one item is visible in the screen at once?

CodePudding user response:

I think using HorizontalPager instead of LazyRow may suit better in this case: it has pagination, as you probably don't need your scroll to stop in between the month, and won't have such a problem out of the box, as same modifier as I suggest you below in applied by the component.

Below is a general answer to the problem, as you still may face it in other cases.


That indeed happens because the parent is horizontally scrollable.

In such case Modifier.fillMaxWidth, as well as Modifier.weight with fill parameter set to true (it's default value) has no effect, as parent width constraint is equal to infinity.

You need to restrict parent width. In this case Modifier.fillParentMaxWidth() can be used on the container: it'll make the view width be equal to the LazyRow width - the part of scroll view which takes exactly "one screen".

As this modifier is defined on LazyItemScope, you have two options to apply it:

  1. Define CalendarRowItem on the scope, in this case CalendarRowItem will only be available to use from lazy view item.

    fun LazyItemScope.CalendarRowItem(/* ... */) {
        // ...
        Column(Modifier.fillParentMaxWidth()) {
            // ...
        }
    }
    
  2. Add a modifier parameter for CalendarRowItem and pass Modifier.fillParentMaxWidth from item scope:

    fun CalendarRowItem(/* ... */, modifier: Modifier) {
        // ...
        Column(modifier) {
            // ...
        }
    }
    
    items(yourItems) { item -> 
        CalendarRowItem(
            /* ... */, 
            modifier = Modifier.fillParentMaxWidth()
        )
    }
    
  • Related