Reputation: 1084
I want to have all the dates of a month in a horizontal scroll view. The current week 7 days should be displayed first and on scrolling right the previous dates should be shown. later on scrolling left the later weeks dates should be displayed an don tap of a date i should get the date in return. How to do this? I have tried using the below. It displays dates and scrolls horizontally as well but it displays only multiple of 7 and all the exact dates of a month. Also on tapping the date it does not return the position form listview builder as 0 and i returns the index.
Widget displaydates(int week) {
return ListView.builder(
itemCount: 5,
itemBuilder: (BuildContext context, int position) {
return Row(
children: <Widget>[
for (int i = 1; i < 8; i++)
Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
print(position);
},
child: Text(
((week * 7) + i).toString() + " ",
style: TextStyle(),
),
),
),
],
);
});
}
I am calling this like:
displaydates(0),
displaydates(1),
displaydates(2),
displaydates(3),
displaydates(4),
Upvotes: 0
Views: 2807
Reputation: 22437
I have created a widget that let me select date from a list and it is scrollable(along time ago). There lot of code but you can use the selected date under any widget which parent wrapped from InheritedWidget
.
Here is the code(Note that I also created a package for this, if you dont like to write this much code for this):
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class MyInheritedWidget extends InheritedWidget {
final DateTime date;
final int selectedDay;
final int monthDateCount;
final bool isDateHolderActive;
final Map<int, bool> dayAvailabilityMap;
final ValueChanged<bool> toggleDateHolderActive;
final ValueChanged<int> setSelectedDay;
MyInheritedWidget({
Key key,
this.date,
this.selectedDay,
this.monthDateCount,
this.isDateHolderActive,
this.dayAvailabilityMap,
this.toggleDateHolderActive,
this.setSelectedDay,
Widget child,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) {
return oldWidget.selectedDay != selectedDay ||
oldWidget.toggleDateHolderActive != toggleDateHolderActive;
}
}
class DateIndicatorPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
DateIndicator(),
Expanded(
child: Container(),
),
],
),
),
);
}
}
class DateIndicator extends StatefulWidget {
static MyInheritedWidget of(BuildContext context) => context.dependOnInheritedWidgetOfExactType();
@override
_DateIndicatorState createState() => _DateIndicatorState();
}
class _DateIndicatorState extends State<DateIndicator> {
DateTime date = DateTime.now();
int selectedDay = 1;
int monthDateCount = 1;
bool isDateHolderActive = false;
Map<int, bool> dayAvailabilityMap = {};
void toggleDateHolderActive(bool flag) {
setState(() {
isDateHolderActive = flag;
});
}
void setSelectedDay(int index) {
setState(() {
selectedDay = index;
});
}
@override
void initState() {
final DateTime dateForValues = new DateTime(date.year, date.month + 1, 0);
monthDateCount = dateForValues.day;
// Just to show how to activate when something exist for this day(from network response or something)
dayAvailabilityMap[1] = true;
dayAvailabilityMap[2] = true;
dayAvailabilityMap[3] = true;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 68.0,
padding:
const EdgeInsets.only(left: 7.0, right: 3.0, top: 2.0, bottom: 2.0),
decoration: BoxDecoration(
color: Theme.of(context).secondaryHeaderColor,
boxShadow: [
BoxShadow(
color: Colors.blueAccent.withOpacity(.7),
offset: Offset(0.0, .5),
blurRadius: 3.0,
spreadRadius: 0.3),
],
),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: monthDateCount, // to avoid showing zero
itemBuilder: (BuildContext context, int index) {
return MyInheritedWidget(
date: date,
selectedDay: selectedDay,
monthDateCount: monthDateCount,
isDateHolderActive: isDateHolderActive,
dayAvailabilityMap: dayAvailabilityMap,
toggleDateHolderActive: toggleDateHolderActive,
setSelectedDay: setSelectedDay,
child: DateHolder(index));
}),
);
}
}
class DateHolder extends StatelessWidget {
DateHolder(this.index);
final int index;
final Widget activeBubble = Container(
width: 15.0,
height: 15.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.deepOrangeAccent,
),
);
@override
Widget build(BuildContext context) {
final appState = DateIndicator.of(context);
return InkWell(
onTap: () {
appState.toggleDateHolderActive(true);
appState.setSelectedDay(index);
print("Date ${index} selected!");
},
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 5.0),
child: Text(
"${DateFormat('EEEE').format(DateTime(appState.date.year, appState.date.month, index)).substring(0, 1)}",
style: TextStyle(color: Theme.of(context).primaryColor, fontSize: 12.0),
)),
Container(
width: 45.0,
height: 45.0,
margin: const EdgeInsets.only(right: 5.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
border: (index == (appState.selectedDay) &&
appState.isDateHolderActive == true)
? Border.all(width: 2.0, color: Theme.of(context).primaryColor)
: Border.all(color: Colors.transparent),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(
"${index + 1}", // to avoid showing zero
style: TextStyle(color: Theme.of(context).primaryColor, fontSize: 16.0),
),
),
),
),
],
),
(appState.dayAvailabilityMap[index] ?? false)
? Positioned(right: 8.0, bottom: 5.0, child: activeBubble)
: Container(),
],
),
);
}
}
Upvotes: 1
Reputation: 6788
UPDATE:
You can get last day of month using below code :
DateTime(year,month + 1).subtract(Duration(days: 1)).day;
You should use ModalBottomSheet
for the same and then pop that on selection with the Navigator.of(context).pop(result);
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ListView.builder(
itemCount: 5,
itemBuilder: (BuildContext context, int position) {
return Row(
children: <Widget>[
for (int i = 1; i < 8; i++)
Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
Navigator.of(context).pop(position);
},
child: Text(
((week * 7) + i).toString() + " ",
style: TextStyle(),
),
),
),
],
);
}
);
}
);
Upvotes: 1