Listview.builder не обновляется при изменении данных API

#flutter #dart #listview

#трепетать #дротик #просмотр списка

Вопрос:

Я разработал API, который действительно удаляет задания и отправляет свои данные в JSON обратно в Flutter. Однако любые новые поиски работы не обновляют Listview.builder, даже если метод _getJobs получает новые данные при каждом поиске из моей колбы. Метод FutureBuilder _jobSearch выполняется только один раз при перезапуске приложения, поэтому каждый раз выводятся одни и те же результаты и не выполняется снова для предстоящих поисков.

Вот мой код:

 import 'package:flutter_job_portal/theme/colors.dart'; import 'package:flutter_job_portal/theme/images.dart'; import 'package:flutter_job_portal/ui/bottom_menu_bar.dart'; import 'package:flutter_job_portal/ui/job_detail_page.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'dart:async';  String job = ''; //user's response will be assigned to this variable final _formkey = GlobalKeylt;FormStategt;(); //key created to interact with the form  class Job {  final String title;  final String company;  final String location;  final String salary;   Job(this.title, this.company, this.location, this.salary); }  class HomePage extends StatelessWidget {  Futurelt;voidgt; _savingData() async {  final validation = _formkey.currentState.validate();  if (!validation) {  return;  }  _formkey.currentState.save();  }   Futurelt;Listlt;Jobgt;gt; _getJobs() async {  final url = 'http://127.0.0.1:5000/job';  final response =  await http.post(Uri.parse(url), body: json.encode({'job': job}));   final data = await http.get(Uri.parse(url));  final decoded = json.decode(data.body);   Listlt;Jobgt; jobs = [];  for (var i in decoded) {  Job job = Job(i['Title'], i['Company'], i['Location'], i['Salary']);  jobs.add(job);  }  return jobs;  }   const HomePage({Key key}) : super(key: key);  Widget _appBar(BuildContext context) {  return Container(  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),  child: Row(  children: [  CircleAvatar(  backgroundImage: AssetImage(Images.user1),  ),  Spacer(),  IconButton(  icon: Icon(Icons.notifications_none_rounded),  onPressed: () {},  )  ],  ),  );  }   Widget _header(BuildContext context) {  return Container(  margin: EdgeInsets.symmetric(vertical: 12),  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),  child: Column(  crossAxisAlignment: CrossAxisAlignment.start,  children: [  Text("Hello, Alex!",  style: TextStyle(  fontSize: 15,  color: KColors.subtitle,  fontWeight: FontWeight.w500,  )),  SizedBox(  height: 6,  ),  Text("Swipe to find your future",  style: TextStyle(  fontSize: 20,  color: KColors.title,  fontWeight: FontWeight.bold)),  SizedBox(  height: 10,  ),  Row(  children: [  Expanded(  child: Container(  height: 45,  padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),  decoration: BoxDecoration(  color: KColors.lightGrey,  borderRadius: BorderRadius.circular(10)),  child: Form(  key: _formkey,  child: TextFormField(  decoration: InputDecoration(  hintText: 'Search job title or keywords',  ),  onSaved: (value) {  job =  value; //getting data from the user form and assigning it to job  },  ),  ),  ),  ),  SizedBox(  width: 16,  ),  Container(  decoration: BoxDecoration(  color: KColors.primary,  borderRadius: BorderRadius.circular(10),  ),  height: 40,  child: IconButton(  color: KColors.primary,  icon: Icon(Icons.search, color: Colors.white),  onPressed: () async {  _savingData();  _getJobs();  },  ),  )  ],  )  ],  ),  );  }   Widget _recommendedSection(BuildContext context) {  return Container(  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),  margin: EdgeInsets.symmetric(vertical: 12),  height: 200,  width: MediaQuery.of(context).size.width,  child: Column(  crossAxisAlignment: CrossAxisAlignment.start,  children: [  Text(  "Recommended",  style: TextStyle(fontWeight: FontWeight.bold, color: KColors.title),  ),  SizedBox(height: 10),  Expanded(  child: ListView(  scrollDirection: Axis.horizontal,  children: [  _recommendedJob(context,  company: "Google",  img: Images.google,  title: "Software Engineer",  sub: "$125,000 Remote",  isActive: true),  _recommendedJob(context,  company: "DropBox",  img: Images.dropbox,  title: "Research Assist",  sub: "$45,000 Remote",  isActive: false)  ],  ),  ),  ],  ),  );  }   Widget _recommendedJob(  BuildContext context, {  String img,  String company,  String title,  String sub,  bool isActive = false,  }) {  return Padding(  padding: const EdgeInsets.only(right: 10),  child: GestureDetector(  onTap: () {  Navigator.push(context, JobDetailPage.getJobDetail());  },  child: AspectRatio(  aspectRatio: 1.3,  child: Container(  decoration: BoxDecoration(  color: isActive ? KColors.primary : Colors.white,  borderRadius: BorderRadius.circular(7),  ),  padding: EdgeInsets.all(16),  child: Column(  crossAxisAlignment: CrossAxisAlignment.start,  children: [  Container(  height: 40,  width: 40,  padding: EdgeInsets.all(10),  decoration: BoxDecoration(  color: isActive ? Colors.white : KColors.lightGrey,  borderRadius: BorderRadius.circular(7),  ),  child: Image.asset(img),  ),  SizedBox(height: 16),  Text(  company,  style: TextStyle(  fontSize: 12,  color: isActive ? Colors.white38 : KColors.subtitle,  ),  ),  SizedBox(height: 6),  Text(  title,  style: TextStyle(  fontSize: 14,  color: isActive ? Colors.white : KColors.title,  fontWeight: FontWeight.bold,  ),  ),  SizedBox(height: 6),  Text(  sub,  style: TextStyle(  fontSize: 12,  color: isActive ? Colors.white38 : KColors.subtitle,  ),  ),  ],  ),  ),  ),  ),  );  }   FutureBuilderlt;Listlt;Jobgt;gt; _jobSearch() {  return FutureBuilder(  future: _getJobs(),  builder: (context, snapshot) {  if (snapshot.data == null) {  return Container(  child: Center(  child: CircularProgressIndicator(),  ));  } else {  return ListView.builder(  physics: NeverScrollableScrollPhysics(),  shrinkWrap: true,  itemCount: snapshot.data.length,  itemBuilder: (context, index) {  return ListTile(  title: Text(snapshot.data[index].company),  subtitle: Text(snapshot.data[index].title),  );  },  );  }  },  );  }   @override  Widget build(BuildContext context) {  return new Scaffold(  backgroundColor: KColors.background,  bottomNavigationBar: BottomMenuBar(),  body: SafeArea(  child: Container(  width: MediaQuery.of(context).size.width,  child: SingleChildScrollView(  physics: ScrollPhysics(),  child: Column(  crossAxisAlignment: CrossAxisAlignment.start,  children: [  _appBar(context),  _header(context),  _recommendedSection(context),  _jobSearch(),  ],  ),  ),  ),  ),  );  } }