Reputation: 13
I made a timetable schedule with items inside.
But when I scroll the ScrollView the item disappears, as soon as the slot leaves the view.
I tried a CustomScrollView with a SliverList making for each Timeslot a TimeslotRow.
This is the ScrollView:
Expanded(
child: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return TimeslotRow(
timeslot_items[index].name,
timeslot_items[index].items,
);
},
childCount: timeslot_items.length,
),
)
],
),
)
This is the TimeslotRow as a SizedOverflowBox:
Widget TimeslotRow(
String slot,
List<TerminItem> items,
) {
return SizedOverflowBox(
alignment: Alignment.topLeft,
size: const Size(double.infinity, 200),
child: Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(width: 1.5, color: backgroundColor),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (Responsive.isDesktop(context))
Expanded(
flex: 1,
child: SizedBox(
child: Text(slot),
)),
Expanded(
flex: 3,
child: items
.where((item) => item.saal == 0)
.toList()
.map((item) => TerminWidget(item))
.toList()
.isNotEmpty
? Stack(
children: items
.where((item) => item.saal == 0)
.toList()
.map((item) => TerminWidget(item))
.toList(),
)
: EmptyTimeslotItem(slot, 0)),
Expanded(
flex: 3,
child: items
.where((item) => item.saal == 1)
.toList()
.map((item) => TerminWidget(item))
.toList()
.isNotEmpty
? Stack(
children: items
.where((item) => item.saal == 1)
.toList()
.map((item) => TerminWidget(item))
.toList(),
)
: EmptyTimeslotItem(slot, 1)),
Expanded(
flex: 3,
child: items
.where((item) => item.saal == 2)
.toList()
.map((item) => TerminWidget(item))
.toList()
.isNotEmpty
? Stack(
children: items
.where((item) => item.saal == 2)
.toList()
.map((item) => TerminWidget(item))
.toList(),
)
: EmptyTimeslotItem(slot, 2)),
],
),
),
);
}
Each TimeslotRow does have events starting at this timeslot-time. In the TerminWidget the Offset is calculated and the height:
Widget TerminWidget(TerminItem item) {
return Transform.translate(
offset: Offset(
0,
item.start.minute == 15
? 50
: item.start.minute == 30
? 100
: item.start.minute == 45
? 150
: 0),
child: InkWell(
onTap: () {
if (item.name == "Privatstunde") {
PrivateTermin termin = PrivateTermin(
name: item.note1,
kontakt: item.note2,
song: item.note3,
selection: item.name,
time: Timestamp.fromDate(item.start),
dauer: item.dauer,
saal: item.saal == 0
? "Saal Blau"
: item.saal == 1
? "Saal Lila"
: "Saal Grün",
teacher: item.teacher,
privateRef: item.privateRef,
uid: item.uid);
showPrivateDialog_Info(termin);
}
},
child: Container(
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.only(right: 20, top: 2, left: 2),
width: double.infinity,
height: item.dauer * 3.333333333,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10)),
border: Border(
left: BorderSide(width: 6, color: saalIndicators[item.saal]),
top: BorderSide(width: 1, color: saalIndicators[item.saal]),
right: BorderSide(width: 1, color: saalIndicators[item.saal]),
bottom: BorderSide(width: 1, color: saalIndicators[item.saal]),
),
color: saalBackgrounds[item.saal]),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(
"${DateFormat('HH:mm').format(item.start)} Uhr - ${DateFormat('HH:mm').format(item.start.add(Duration(minutes: item.dauer)))} Uhr"),
Text(
item.name,
style:
const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
Text(item.note1),
Text(item.teacher)
],
),
),
),
);
}
Upvotes: 0
Views: 35