MustafaKhaled
MustafaKhaled

Reputation: 1489

How to add List Item to FutureBuilder ListView without reloading the data from remote server? [Flutter]

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

Answers (1)

Ninja
Ninja

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

Related Questions