#flutter #dart #listview
#трепетать #дротик #просмотр списка
Вопрос:
Я разрабатываю приложение для поиска работы, которое удаляет данные из Indeed с помощью Python, которые отправляются обратно в мой пользовательский интерфейс Flutter в виде данных JSON. Данные JSON успешно получены, однако я получаю ошибку оператора проверки Null, используемого для нулевого значения. Ошибка, по-видимому, связана с виджетом _jobSearch.
Соответствующим виджетом, вызывающим ошибки, был ListView lib/ui/домашняя страница.dart:256
Исключение, обнаруженное библиотекой планировщика
Оператор проверки на нуль, используемый для нулевого значения
Вот код:
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; 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'; String job = ""; //user's response will be assigned to this variable String final_response = ""; final _formkey = GlobalKeylt;FormStategt;(); //key created to interact with the form //function to validate and save user form 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 response1 = await http.post(Uri.parse(url), body: json.encode({'job': job})); final response2 = await http.get(Uri.parse(url)); final decoded = json.decode(response2.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; } 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 { 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: "UX Designer", sub: "$45,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, ), ), ], ), ), ), ), ); } Widget _jobSearch(BuildContext context) { return new Container( child: FutureBuilder( future: _getJobs(), builder: (context, snapshot) { if (snapshot.data == null) { return Container( child: Center( child: Text('Loading...'), )); } else { return ListView.builder( itemCount: snapshot.data.length, itemBuilder: (context, index) { return ListTile( title: Text(snapshot.data[index].location), ); }, ); } }, ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: KColors.background, bottomNavigationBar: BottomMenuBar(), body: SafeArea( child: Container( width: MediaQuery.of(context).size.width, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _appBar(context), _header(context), _recommendedSection(context), _jobSearch(context) ], ), ), ), ), ); } }
Комментарии:
1. Вы уверены, что это ошибка, которую вы получаете, и код, который вы запускаете? Я не вижу никаких «операторов проверки на нуль» в строке, которую вы указали. Не могли бы вы сказать нам, в какой строке упомянута «строка 256» в вашем редакторе?
2. верните ListView.builder( количество элементов: снимок? .data.length, конструктор элементов: (контекст, индекс) { возвращаемый список (заголовок: Текст(снимок? .данные[индекс]? .местоположение), ); }, );