Reputation: 1489
I'm new in flutter, I'd like to know how to add an item list dynamically to ListView without reloading data in FutureBuilder. When I add an item to the ListView, it duplicate the list and then added the item to that list.
The Following code, include Model clas called Job.
JobListView is a stateful widget that include the dynamic ListView.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class Job {
@required
String company;
String description;
String employmentType;
int id;
String location;
String position;
List<String> skillsRequired;
Job(
this.company,
this.description,
this.employmentType,
this.id,
this.location,
this.position,
this.skillsRequired);
Job.fromJson(Map<String, dynamic> json) {
company = json['company'];
description = json['description'];
employmentType = json['employmentType'];
id = json['id'];
location = json['location'];
position = json['position'];
if (json['skillsRequired'] != null) {
skillsRequired = new List<String>();
json['skillsRequired'].forEach((v) {
skillsRequired.add(v);
});
}
}
}
class JobListView extends StatefulWidget {
@override
_JobListViewState createState() => _JobListViewState();
}
class _JobListViewState extends State<JobListView> {
List<Job> data = List<Job>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Job>>(
future: _getJob(),
builder: (context, snapshot) {
if (snapshot.hasData) {
data = snapshot.data;
return _listViewFormat(data);
} else if (snapshot.hasError) {
return Container();
}
return Center(
child: Container(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
);
},
) ,
floatingActionButton: (FloatingActionButton(child: Icon(Icons.add),onPressed: (){
setState(() {
var j = Job("CompanyX","Eng.5 position","Full-time",0,"Cairo","Senior",null);
data.add(j);
});
},)),
);
}
}
ListView _listViewFormat(List<Job> data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return _tile(data[index].position, data[index].description, Icons.work);
});
}
ListTile _tile(String title, String subtitle, IconData iconData) {
return ListTile(
title: Text(title, style: TextStyle(fontSize: 20)),
subtitle: Text(
subtitle,
style: TextStyle(fontSize: 12),
),
leading: Icon(iconData),
trailing: Icon(Icons.arrow_right),
);
}
Future<List<Job>> _getJob() async {
String baseUrl = 'https://mock-json-service.glitch.me';
var response = await get(baseUrl);
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body);
return jsonResponse.map((job) => new Job.fromJson(job)).toList();
}
}
Upvotes: 1
Views: 3033
Reputation: 386
Check out this more explanation How to deal with unwanted widget build?
if future changes you will see changes
Move _getJob method inside initState like this:
class _JobListViewState extends State<JobListView> {
List<Job> data = List<Job>();
Future<List<Job>> getJobFuture;
@override
void initState() {
super.initState();
getJobFuture = _getJob();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Job>>(
future: getJobFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
data = snapshot.data;
return _listViewFormat(data);
} else if (snapshot.hasError) {
return Container();
}
return Center(
child: Container(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
);
},
) ,
floatingActionButton: (FloatingActionButton(child: Icon(Icons.add),onPressed: (){
setState(() {
var j = Job("CompanyX","Eng.5 position","Full-time",0,"Cairo","Senior",null);
data.add(j);
});
},)),
);
}
}
Upvotes: 1