I've come across a problem which I cannot figure out. I'm trying to display single event on my home screen which is next upcoming by date. That event comes from list of events in the api. Currently I am using listview.builder to display those events however when I set item count to 1 I cannot get the next event by date to be displayed. I was trying to display all events in listview.builder and then filter but I couldn't get it to work.
I need to display events in that order but they need to be shown 1 by 1 based on todays time. So when current time is the same as the events time next event will be shown: firstImage
And this is what I'm getting when the itemCount is 1. This is the last event from the list
which I tried to reverse but no success. secondImage
This is code for the ListView.builder
ListView.builder(
reverse: true,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
// itemCount: 1,
itemCount: 1,
itemBuilder: (context, index) {
var x = eventController.event.value!.data![index];
DateTime formattedStartDate = new DateFormat('yyyy-MM-dd hh:mm')
.parse(eventController
.event.value!.data![index].eventStartDate
.toString());
DateTime splitStartDate = new DateTime(
formattedStartDate.year,
formattedStartDate.month,
formattedStartDate.day,
formattedStartDate.hour,
formattedStartDate.minute);
DateTime today = DateTime.now();
bool isAfter = splitStartDate.isAfter(today);
return Column(
children: [
isAfter == true
? GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EventDetails(
event: eventController
.event.value!.data![index])));
},
child: EventTileMain(
eventController.event.value!.data![index]))
: Container()
],
);
});
This is model calss of event:
// To parse this JSON data, do
//
// final event = eventFromJson(jsonString);
import 'dart:convert';
Event eventFromJson(String str) => Event.fromJson(json.decode(str));
String eventToJson(Event data) => json.encode(data.toJson());
class Event {
Event({
this.success,
this.data,
this.code,
this.count,
});
bool? success;
List<Datum>? data;
int? code;
int? count;
factory Event.fromJson(Map<String, dynamic> json) => Event(
success: json["success"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
code: json["code"],
count: json["count"],
);
Map<String, dynamic> toJson() => {
"success": success,
"data": List<dynamic>.from(data!.map((x) => x.toJson())),
"code": code,
"count": count,
};
}
class Datum {
Datum({
this.id,
this.postTitle,
this.postContent,
this.postName,
this.postUrl,
this.organizer,
this.venue,
this.category,
this.speaker,
this.eventStartDate,
this.eventEndDate,
this.eventDate,
this.featuredImage,
});
String? id;
String? postTitle;
String? postContent;
String? postName;
String? postUrl;
List<Category>? organizer;
List<Category>? venue;
List<Category>? category;
dynamic speaker;
String? eventStartDate;
String? eventEndDate;
DateTime? eventDate;
String? featuredImage;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["ID"],
postTitle: json["post_title"],
postContent: json["post_content"],
postName: json["post_name"],
postUrl: json["post_url"],
organizer: List<Category>.from(json["organizer"].map((x) => Category.fromJson(x))),
venue: List<Category>.from(json["venue"].map((x) => Category.fromJson(x))),
category: List<Category>.from(json["category"].map((x) => Category.fromJson(x))),
speaker: json["speaker"],
eventStartDate: json["event_start_date"],
eventEndDate: json["event_end_date"],
eventDate: DateTime.parse(json["event_date"]),
featuredImage: json["featured_image"],
);
Map<String, dynamic> toJson() => {
"ID": id,
"post_title": postTitle,
"post_content": postContent,
"post_name": postName,
"post_url": postUrl,
"organizer": List<dynamic>.from(organizer!.map((x) => x.toJson())),
"venue": List<dynamic>.from(venue!.map((x) => x.toJson())),
"category": List<dynamic>.from(category!.map((x) => x.toJson())),
"speaker": speaker,
"event_start_date": eventStartDate,
"event_end_date": eventEndDate,
"event_date": eventDate!.toIso8601String(),
"featured_image": featuredImage,
};
}
class Category {
Category({
this.id,
this.name,
});
int? id;
Name? name;
factory Category.fromJson(Map<String, dynamic> json) => Category(
id: json["id"],
name: nameValues.map[json["name"]],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": nameValues.reverse![name],
};
}
enum Name { AUDITORIUM, SEMINAR, XPOSURE, XPOSURE_INTERNATIONAL_PHOTOGRAPHY_FESTIVAL, TOR_SEIDEL, XPOSURE_AUDITORIUM }
final nameValues = EnumValues({
"Auditorium": Name.AUDITORIUM,
"Seminar": Name.SEMINAR,
"Tor Seidel": Name.TOR_SEIDEL,
"Xposure": Name.XPOSURE,
"Xposure Auditorium": Name.XPOSURE_AUDITORIUM,
"Xposure International Photography Festival": Name.XPOSURE_INTERNATIONAL_PHOTOGRAPHY_FESTIVAL
});
class EnumValues<T> {
Map<String, T> map;
Map<T, String>? reverseMap;
EnumValues(this.map);
Map<T, String>? get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
API call
class EventApi {
static var client = http.Client();
static Future<Event?> fetchEvents() async {
final response = await client.get(Uri.parse(
'https://xposure.ae/api/v1/events/'));
// 'https://xposure.ae/wp-json/wp/auditorium/v1/events'));
if (response.statusCode == 200) {
var jsonString = response.body;
return eventFromJson(jsonString);
} else {
return null;
}
}
}
If you need more information please let me know.
CodePudding user response:
you can try this:
ListView.builder(
reverse: true,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
// itemCount: 1,
itemCount: 1,
itemBuilder: (context, index) {
var now = DateTime.now();
Datum? closestEvent;
eventController.event.value!.data!.forEach((element) {
var elementDate =
DateFormat('yyyy-MM-dd hh:mm').parse(element.eventStartDate);
if (closestEvent == null) {
if (elementDate.isAfter(now)) {
closestEvent = element;
}
} else {
var closestDate = DateFormat('yyyy-MM-dd hh:mm').parse(closestEvent!.eventStartDate);
if (elementDate.isAfter(now) && elementDate.isBefore(closestDate)) {
closestEvent = element;
}
}
});
return Column(
children: [
isAfter == true
? GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EventDetails(
event: closestEvent)));
},
child: EventTileMain(
closestEvent))
: Container()
],
);
});
you can simply make a widget function and remove your listview
, like this:
Widget buildEventWidget(BuildContext context){
var now = DateTime.now();
Datum? closestEvent;
eventController.event.value!.data!.forEach((element) {
var elementDate =
DateFormat('yyyy-MM-dd hh:mm').parse(element.eventStartDate);
if (closestEvent == null) {
if (elementDate.isAfter(now)) {
closestEvent = element;
}
} else {
var closestDate = DateFormat('yyyy-MM-dd hh:mm').parse(closestEvent!.eventStartDate);
if (elementDate.isAfter(now) && elementDate.isBefore(closestDate)) {
closestEvent = element;
}
}
});
return Column(
children: [
isAfter == true
? GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EventDetails(
event: closestEvent)));
},
child: EventTileMain(
closestEvent))
: Container()
],
);
}