This is the full code.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Event>> fetchEvents(http.Client client) async {
final response = await http.get(Uri.parse('https://my-json-server.typicode.com/Evgen1987RUS/test-json/events/')); // TODO: тестовый джей сон поменять на нормальный
return compute(parseEvents, response.body);
}
List<Event> parseEvents(String responseBody) {
final parsed = (jsonDecode(responseBody) as List).cast<Map<String, dynamic>>();
return parsed.map<Event>((json) => Event.fromJson(json)).toList();
}
class Event {
final String id;
final String name;
final String description;
final String date;
final String imgPath;
const Event({
required this.id,
required this.name,
required this.description,
required this.date,
required this.imgPath,
});
factory Event.fromJson(Map<String, dynamic> json) {
return Event (
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String,
date: json['date'] as String,
imgPath: json['imgPath'] as String,
);
}
}
void main()
=> runApp(const SPNRApp());
class SPNRApp extends StatelessWidget {
const SPNRApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'СПНР',
theme: ThemeData(
primarySwatch: Colors.amber
),
home: const HomePage(
title: 'Главная страница'
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key, required this.title}) : super(key: key); // make it require the title as a key value
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title)
),
body: Container(
height: 100,
color: Colors.amber,
child: SingleChildScrollView(
child: FutureBuilder<List<Event>>(
future: fetchEvents(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
print('line 83 snapshot failure');
return const Center(
child: Text('Ошибка'),
);
}
else if (snapshot.hasData) {
return EventsList(events: snapshot.data!);
}
else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
);
}
}
class EventsList extends StatelessWidget {
const EventsList({super.key, required this.events});
final List<Event> events;
@override
Widget build(BuildContext context) {
return ListView.builder(
shrinkWrap: true,
itemCount: events.length,
itemBuilder: (context, int index) {
return Text(events[index].name);
}
);
}
}
Here is what happens:
As you can see there is the item6 that can be seen (just a tiny sliver of it and there are more items below). The code itself works fine: json file is parsed the right way and all of the items are shown.
The only thing that can go wrong here is probably that SingleChildScrollView is nested into Container AND Scaffold elements and they probably have some kind of a conflict?
2
Answers
Check out this answer.
Basically you need to add
physics: const NeverScrollableScrollPhysics(),
to theListView.builder
.If you are already using a
ListView
on yourEventList
widget, you don’t need to useSingleChildScrollView
.Just remove that widget and it will work.
If you need to use
SingleChildScrollView
widget anyways, just remove the scroll behavior on yourListView.
: