Anonymous
Architekten-Outlook-ähnlicher Kalender in Jetpack Compose: Komplexe Ereignislayoutausrichtung
Post
by Anonymous » 13 Apr 2025, 10:47
Ich entwickle einen outlook-ähnlichen Kalender in Jetpack komponiert, der aus zwei Ebenen besteht: < /p>
Standardkalender-Layout (DefaultEventLayout): Diese Ebene zeigt
das Basiskalender-Gitter mit Tagen und Stunden an. Anzeigen
Ereignisse als Kästchen, die im Kalenderraster positioniert sind. Während sich die Höhe ordnungsgemäß anpasst, wird die Breite von Ereignissen komprimiert oder falsch ausgerichtet. Ich verwende zwei Schichten, um dies zu erreichen:
DefaultEventLayout: Erstellt das Basiskalendergitter mit Tagen und Stunden. Overlay) Eine geeignete Strategie zum Erstellen eines outlook-ähnlichen Kalenders in Jetpack komponieren? EventLayout. hier] 2
Code
Code: Select all
@Composable
fun MainLayout(modifier: Modifier = Modifier) {
val itemsData = listOf(
ItemData(x = 50.dp, y = 50.dp, height = 50.dp),
ItemData(x = 100.dp, y = 120.dp, height = 80.dp),
ItemData(x = 20.dp, y = 200.dp, height = 60.dp),
ItemData(x = 150.dp, y = 280.dp, height = 70.dp),
ItemData(x = 80.dp, y = 350.dp, height = 90.dp),
ItemData(x = 120.dp, y = 440.dp, height = 55.dp),
ItemData(x = 30.dp, y = 500.dp, height = 75.dp),
ItemData(x = 180.dp, y = 580.dp, height = 65.dp),
ItemData(x = 60.dp, y = 650.dp, height = 85.dp),
ItemData(x = 10.dp, y = 730.dp, height = 70.dp),
ItemData(x = 140.dp, y = 800.dp, height = 60.dp),
ItemData(x = 90.dp, y = 880.dp, height = 80.dp),
ItemData(x = 200.dp, y = 950.dp, height = 95.dp),
ItemData(x = 40.dp, y = 1020.dp, height = 58.dp),
ItemData(x = 160.dp, y = 1090.dp, height = 72.dp),
ItemData(x = 70.dp, y = 1160.dp, height = 68.dp),
ItemData(x = 110.dp, y = 1230.dp, height = 82.dp),
ItemData(x = 25.dp, y = 1300.dp, height = 78.dp),
ItemData(x = 190.dp, y = 1370.dp, height = 62.dp),
ItemData(x = 55.dp, y = 1440.dp, height = 92.dp)
)
Column(
modifier
.fillMaxSize()
.background(Color.White)
) {
Row(
modifier
.fillMaxWidth()
.height(40.dp)
.padding(1.dp)
.background(Color.Gray)
) { }
LazyRow(
modifier
.fillMaxWidth()
.height(30.dp)
.padding(1.dp)
.background(Color.DarkGray)
) { }
//Row hours and events
Row(
modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(2.dp)
.background(colorResource(R.color.blue))
) {
val lazyListState = rememberScrollState()
val verticalScrollState = rememberScrollState()
val horizontalScrollState = rememberScrollState()
//Layout default for time and clock
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
//Main box for hold 2 box default and Event
Box(
modifier = Modifier
.weight(1f)
.fillMaxHeight()
// .verticalScroll(verticalScrollState)
) {
//Default layout
DefaultEventLayout(verticalScrollState, horizontalScrollState)
//Event layout
EventLayout(
true,
verticalScrollState = verticalScrollState,
horizontalScrollState = horizontalScrollState,
itemsData,
) {
itemsData.forEach { data ->
Box(
modifier = Modifier
.width(100.dp)
.height(data.height)
.background(colorResource(android.R.color.holo_orange_light))
)
}
}
}
}
//Hours
HoursLayout(verticalScrollState)
}
}
}
@Composable
fun DefaultEventLayout(verticalScrollState: ScrollState, horizontalScrollState: ScrollState) {
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.verticalScroll(verticalScrollState) // Scroll vertical
) {
Row(
modifier = Modifier
.horizontalScroll(horizontalScrollState) // Scroll horizontal
) {
Column {
// list item
repeat(24) { rowIndex ->
Row {
repeat(7) { columnIndex ->
//Calendar cell
DefaultEventCell()
}
}
}
}
}
}
}
@Composable
fun EventLayout(
showLayout: Boolean,
verticalScrollState: ScrollState,
horizontalScrollState: ScrollState,
itemData: List,
content: @Composable () -> Unit,
) {
if (showLayout) {
Layout(
content = content,
modifier = Modifier
.verticalScroll(verticalScrollState)
.horizontalScroll(horizontalScrollState)
.background(Color.Blue.copy(0.5f)),
) { measurables, constraints ->
val placeables: List = measurables.mapIndexed { index, measurable ->
val itemHeight = itemData[index].height.toPx().toInt()
val itemConstraints = constraints.copy(minHeight = itemHeight, maxHeight = itemHeight)
measurable.measure(itemConstraints)
}
var maxWidth = 0
var maxHeight = 0
placeables.forEachIndexed { index, placeable ->
val itemX = itemData[index].x.toPx().toInt()
val itemY = itemData[index].y.toPx().toInt()
val itemWidth = placeable.width
val itemHeight = placeable.height
maxWidth = maxOf(maxWidth, itemX + itemWidth)
maxHeight = maxOf(maxHeight, itemY + itemHeight)
}
val layoutWidth = constraints.constrainWidth(maxWidth)
val layoutHeight = constraints.constrainHeight(maxHeight)
layout(width = layoutWidth, height = layoutHeight) {
placeables.forEachIndexed { index, placeable ->
val itemX = itemData[index].x.toPx().toInt()
val itemY = itemData[index].y.toPx().toInt()
placeable.place(x = itemX, y = itemY)
}
}
}
}
}
1744534070
Anonymous
Ich entwickle einen outlook-ähnlichen Kalender in Jetpack komponiert, der aus zwei Ebenen besteht: < /p> Standardkalender-Layout (DefaultEventLayout): Diese Ebene zeigt das Basiskalender-Gitter mit Tagen und Stunden an. Anzeigen Ereignisse als Kästchen, die im Kalenderraster positioniert sind. Während sich die Höhe ordnungsgemäß anpasst, wird die Breite von Ereignissen komprimiert oder falsch ausgerichtet. Ich verwende zwei Schichten, um dies zu erreichen: DefaultEventLayout: Erstellt das Basiskalendergitter mit Tagen und Stunden. Overlay) Eine geeignete Strategie zum Erstellen eines outlook-ähnlichen Kalenders in Jetpack komponieren? EventLayout. hier] 2 [b] Code [/b] [code] @Composable fun MainLayout(modifier: Modifier = Modifier) { val itemsData = listOf( ItemData(x = 50.dp, y = 50.dp, height = 50.dp), ItemData(x = 100.dp, y = 120.dp, height = 80.dp), ItemData(x = 20.dp, y = 200.dp, height = 60.dp), ItemData(x = 150.dp, y = 280.dp, height = 70.dp), ItemData(x = 80.dp, y = 350.dp, height = 90.dp), ItemData(x = 120.dp, y = 440.dp, height = 55.dp), ItemData(x = 30.dp, y = 500.dp, height = 75.dp), ItemData(x = 180.dp, y = 580.dp, height = 65.dp), ItemData(x = 60.dp, y = 650.dp, height = 85.dp), ItemData(x = 10.dp, y = 730.dp, height = 70.dp), ItemData(x = 140.dp, y = 800.dp, height = 60.dp), ItemData(x = 90.dp, y = 880.dp, height = 80.dp), ItemData(x = 200.dp, y = 950.dp, height = 95.dp), ItemData(x = 40.dp, y = 1020.dp, height = 58.dp), ItemData(x = 160.dp, y = 1090.dp, height = 72.dp), ItemData(x = 70.dp, y = 1160.dp, height = 68.dp), ItemData(x = 110.dp, y = 1230.dp, height = 82.dp), ItemData(x = 25.dp, y = 1300.dp, height = 78.dp), ItemData(x = 190.dp, y = 1370.dp, height = 62.dp), ItemData(x = 55.dp, y = 1440.dp, height = 92.dp) ) Column( modifier .fillMaxSize() .background(Color.White) ) { Row( modifier .fillMaxWidth() .height(40.dp) .padding(1.dp) .background(Color.Gray) ) { } LazyRow( modifier .fillMaxWidth() .height(30.dp) .padding(1.dp) .background(Color.DarkGray) ) { } //Row hours and events Row( modifier .fillMaxWidth() .fillMaxHeight() .padding(2.dp) .background(colorResource(R.color.blue)) ) { val lazyListState = rememberScrollState() val verticalScrollState = rememberScrollState() val horizontalScrollState = rememberScrollState() //Layout default for time and clock CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { //Main box for hold 2 box default and Event Box( modifier = Modifier .weight(1f) .fillMaxHeight() // .verticalScroll(verticalScrollState) ) { //Default layout DefaultEventLayout(verticalScrollState, horizontalScrollState) //Event layout EventLayout( true, verticalScrollState = verticalScrollState, horizontalScrollState = horizontalScrollState, itemsData, ) { itemsData.forEach { data -> Box( modifier = Modifier .width(100.dp) .height(data.height) .background(colorResource(android.R.color.holo_orange_light)) ) } } } } //Hours HoursLayout(verticalScrollState) } } } @Composable fun DefaultEventLayout(verticalScrollState: ScrollState, horizontalScrollState: ScrollState) { Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight() .verticalScroll(verticalScrollState) // Scroll vertical ) { Row( modifier = Modifier .horizontalScroll(horizontalScrollState) // Scroll horizontal ) { Column { // list item repeat(24) { rowIndex -> Row { repeat(7) { columnIndex -> //Calendar cell DefaultEventCell() } } } } } } } @Composable fun EventLayout( showLayout: Boolean, verticalScrollState: ScrollState, horizontalScrollState: ScrollState, itemData: List, content: @Composable () -> Unit, ) { if (showLayout) { Layout( content = content, modifier = Modifier .verticalScroll(verticalScrollState) .horizontalScroll(horizontalScrollState) .background(Color.Blue.copy(0.5f)), ) { measurables, constraints -> val placeables: List = measurables.mapIndexed { index, measurable -> val itemHeight = itemData[index].height.toPx().toInt() val itemConstraints = constraints.copy(minHeight = itemHeight, maxHeight = itemHeight) measurable.measure(itemConstraints) } var maxWidth = 0 var maxHeight = 0 placeables.forEachIndexed { index, placeable -> val itemX = itemData[index].x.toPx().toInt() val itemY = itemData[index].y.toPx().toInt() val itemWidth = placeable.width val itemHeight = placeable.height maxWidth = maxOf(maxWidth, itemX + itemWidth) maxHeight = maxOf(maxHeight, itemY + itemHeight) } val layoutWidth = constraints.constrainWidth(maxWidth) val layoutHeight = constraints.constrainHeight(maxHeight) layout(width = layoutWidth, height = layoutHeight) { placeables.forEachIndexed { index, placeable -> val itemX = itemData[index].x.toPx().toInt() val itemY = itemData[index].y.toPx().toInt() placeable.place(x = itemX, y = itemY) } } } } } [/code]