In flutter, json data is not appearing in listview initially - flutter

At first, the list of publications was shown in ListTile. However, when I changed the String query, it doesn't show any data at all, and I can't search it. I want to show it as a ListView, but I want to hide it before searching and enter the correct title when I search, and I want to see what I searched. It's strange why suddenly a JSON file comes out.
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(MaterialApp(
home: MyGetHttpData(),
));
}
class MyGetHttpData extends StatefulWidget {
#override
MyGetHttpDataState createState() => MyGetHttpDataState();
}
class MyGetHttpDataState extends State<MyGetHttpData> {
String query = '유시민';
int page = 1;
String url;
List data;
Future<String> getJSONData() async {
var response = await http.get(
Uri.encodeFull(url),
headers: {"Accept": "application/json" , 'Authorization' : 'KakaoAK 5a1167ba90ccb4b79d84ef5a41da0fbd'});
//REST API 여기에 입력//
print(response.body);
setState(() {
var dataConvertedToJSON = json.decode(response.body);
data = dataConvertedToJSON['documents'];
});
return "Successfull";
}
TextEditingController editingController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('widgettitle'),
),
body: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
},
controller: editingController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)))),
),
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: data == null ? 0 : data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
data[index]['publisher'].toString(),
style: TextStyle(
fontSize: 20.0, color: Colors.black, ),
),
);
},
),
),
],
),
),
);
}
}
SharedPreferences prefs;
List<String> list;
// ...
Future<bool> _saveList() async {
return await prefs.setStringList("key", list);
}
List<String> _getList() {
return prefs.getStringList("key");
}
#override
void initState() {
String query = '유시민';
int page = 1;
String url;
List data;
url = 'https://dapi.kakao.com/v3/search/book?sort=accuracy&target=title&size=10&query= $query &page= $page';
}

Related

the variable date of DateTime doesn't save when I press on cold reload

I used Share_Prefereces library so I want to save date of adding Item. I tried many ways but
I always get the errors: E/flutter ( 2786): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'DateTime'
and the second error is: Unhandled Exception: Converting object to an encodable object failed: Instance of 'Shopping'
so please help me
the code of Date file is:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Shopping {
String item;
int price;
DateTime date;
Shopping({required this.item, required this.price, required this.date});
Map<String, dynamic> toJson() {
return {
'item': item,
'price': price,
'date': date,
};
}
}
class ItemData extends ChangeNotifier {
List<Shopping> listOfItem = [];
void addItem(Shopping shopping) {
listOfItem.add(shopping);
notifyListeners();
}
void editItem(Shopping shopping, int itemIndex) {
listOfItem[itemIndex] = shopping;
notifyListeners();
}
void deleteItem(int itemIndex) {
listOfItem.removeAt(itemIndex);
notifyListeners();
}
saveData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
List<String> tempList = [];
for (int i = 0; i < listOfItem.length; i++) {
tempList.add(jsonEncode(listOfItem[i]));
}
pref.remove("itemList");
pref.setStringList("itemList", tempList);
}
loadData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
if (pref.getStringList('itemList') != null) {
List<String> tempList = pref.getStringList('itemList')!;
for (int i = 0; i < tempList.length; i++) {
Map<String, dynamic> temp = jsonDecode(tempList[i]);
addItem(
Shopping(
item: temp['item'],
price: temp['price'],
date: temp['date'],
),
);
}
}
}
}
and the code of adding Item, price and date is:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:goods_and_price/shopping_data.dart';
import 'package:provider/provider.dart';
class AddItem extends StatelessWidget {
AddItem({Key? key}) : super(key: key);
TextEditingController userInputItem = TextEditingController();
TextEditingController userInputPrice = TextEditingController();
#override
Widget build(BuildContext context) {
var provider = Provider.of<ItemData>(context, listen: true);
DateTime date = DateTime.now();
return Scaffold(
appBar: AppBar(
title: const Text('Add Item'),
centerTitle: true,
backgroundColor: const Color(0xFF00899C),
),
body: ListView(
physics: const BouncingScrollPhysics(),
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: userInputItem,
decoration: InputDecoration(
hintText: 'Item',
labelText: 'Item',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
prefixIcon: const Icon(
Icons.shopping_cart,
color: Color(0xFF00899C),
)),
maxLines: null,
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: userInputPrice,
decoration: InputDecoration(
hintText: 'Price',
labelText: 'Price',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
prefixIcon: const Icon(
Icons.attach_money,
color: Color(0xFF00899C),
)),
maxLines: null,
),
),
const SizedBox(
height: 10,
),
CupertinoButton(
padding: const EdgeInsets.all(0),
pressedOpacity: 0.5,
child: Container(
height: 50,
width: 120,
decoration: BoxDecoration(
color: const Color(0xFF00899C),
borderRadius: BorderRadius.circular(10)),
child: const Center(
child: Text(
'Add Item',
style: TextStyle(color: Colors.white),
),
),
),
onPressed: () async {
Shopping newItem = Shopping(
item: userInputItem.text,
price: int.parse(userInputPrice.text),
date: date,
);
provider.addItem(newItem);
provider.saveData();
Navigator.pop(context);
},
),
],
),
);
}
}
I don't recommend using DateTime, because it takes a certain amount of work to use in different languages, I find it easier to use String.
I couldn't simulate the error on my machine, but I made an example, I hope it helps.
To create class I like to use this site https://javiercbk.github.io/json_to_dart/
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:zoociadoleite_app/global/my_app.dart';
class TesteScreen extends StatefulWidget {
const TesteScreen({Key key}) : super(key: key);
#override
State<TesteScreen> createState() => _TesteScreenState();
}
class Shopping {
String item;
int price;
String date;
Shopping({this.item, this.price, this.date});
Shopping.fromJson(Map<String, dynamic> json) {
item = json['item'];
price = json['price'];
date = json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['item'] = this.item;
data['price'] = this.price;
data['date'] = this.date;
return data;
}
}
class LocalStorage {
Future<String> get(String item) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(item);
}
Future<bool> set(String item, dynamic data) async {
final prefs = await SharedPreferences.getInstance();
return prefs.setString(item, json.encode(data));
}
Future<bool> remove(String item) async {
final prefs = await SharedPreferences.getInstance();
return prefs.remove(item);
}
}
class _TesteScreenState extends State<TesteScreen> {
final formatDate = new DateFormat.yMMMMd('pt_BR');
Future<List<Shopping>> _future;
List<Shopping> list = [];
load() async {
String data = await LocalStorage().get("Shopping");
if (data != null) {
List<dynamic> lista = json.decode(data) as List;
list = lista.map((shopping) => Shopping.fromJson(shopping)).toList();
}
_future = Future.value(list);
setState(() {});
}
#override
void initState() {
super.initState();
load();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Shopping>>(
future: _future,
builder: (context, snapshot) {
if (snapshot.hasData)
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Shopping shopping = snapshot.data[index];
return ListTile(
title: Text(shopping.item),
subtitle: Text("${shopping.price}"),
trailing: Text("${formatDate.format(DateTime.parse(shopping.date))}"),
);
},
);
return CircularProgressIndicator();
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
list.add(Shopping(item: "test_${list.length + 1}", price: list.length + 1, date: DateTime.now().toString()));
_future = Future.value(list);
LocalStorage().set("Shopping", list);
setState(() {});
},
child: const Icon(Icons.add),
),
);
}
}

Flutter Dynamic Searching appBar

I'm trying to create a dynamic search in the appBar, but unfortunately I'm not succeeding and I have an error on this line.
results = _listPlaces.where((places) => places["place"].toLowerCase().contains(enteredKeyword.toLowerCase())
Full code:
import 'package:favspot/src/views/places_card.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../../services/places.dart';
import 'dart:async';
class SeachPlaces extends StatefulWidget {
#override
State<SeachPlaces> createState() => _SeachPlacesState();
}
class _SeachPlacesState extends State<SeachPlaces> {
List<Object> _listPlaces = [];
List<Object> _searchSearch = [];
#override
initState(){
_searchSearch = _listPlaces;
super.initState();
}
void _runFilter(String enteredKeyword) {
List<Object> results = [];
if (enteredKeyword.isEmpty) {
results = _listPlaces;
} else {
results = _listPlaces.where((places) => places["place"].toLowerCase().contains(enteredKeyword.toLowerCase())
).toList();
setState((){
_searchSearch = results;
});
}
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
getPlacesList();
}
TextEditingController? _textEditngController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Container(
width: double.infinity,
height: 40,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(30)),
child: Center(
child:TextField(
onChanged: (value) => _runFilter(value),
controller: _textEditngController,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
prefixIcon: Icon(Icons.search),
suffix: IconButton(
icon: Icon(Icons.clear),
onPressed: null,
),
hintText: 'Searching...',
border: InputBorder.none,
),
),
),
),
),
body: SafeArea(
child: ListView.builder(
itemCount: _searchSearch.length,
itemBuilder: (context, index) {
return PlacesCard(_searchSearch[index] as Places);
},
)
),
);
}
Future getPlacesList() async {
var data = await FirebaseFirestore.instance
.collection('places')
.orderBy('city', descending: false)
.get();
setState(() {
_listPlaces = List.from(data.docs.map((doc) => Places.fromSnapshot(doc)));
});
}
}
Here is de class Places
class Places {
String? place;
String? city;
String? status;
Places();
Map<String, dynamic> toJson() => {
'city' : city,
'status' : status,
};
Places.fromSnapshot(snapshot) :
place = snapshot.id,
city = snapshot.data()['city'],
status = snapshot.data()['status'];
}
Consider to use List<Places> _listPlaces instead of List<Object> _listPlaces, so you can access properties like this:
results = _listPlaces.where((places) => places.place != null && places.place!.toLowerCase().contains(enteredKeyword.toLowerCase())
).toList();

Flutter Barcode Scan Result Is'nt Listed

My application is to search through the list of books. Two different variables (book name or barcode) can be used while searching. There is no problem when searching by name. but when searching with barcode scanning, no results are listed. When I type the barcode manually, the application still works without any problems.
Can u help me?
Manually entered barcode: https://i.stack.imgur.com/njtLA.png
Barcode scan result : https://i.stack.imgur.com/ZsGot.png
My code here..
import 'package:fff/book_tile.dart';
import 'package:flutter/material.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:fff/book_model.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController _controller = new TextEditingController();
List<Book> _booksForDisplay = [];
List<Book> _books = [];
#override
void initState() {
super.initState();
fetchBooks().then((value) {
setState(() {
_books.addAll(value);
_booksForDisplay = _books;
print(_booksForDisplay.length);
});
});
}
Future _scan(BuildContext context) async {
String barcode = await FlutterBarcodeScanner.scanBarcode(
'#ff0000',
'İptal',
true,
ScanMode.BARCODE
);
_controller.text = barcode;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 80,
title: Padding(
padding: EdgeInsets.all(8),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40)
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 12),
child: TextFormField(
textAlignVertical: TextAlignVertical.center,
controller: _controller,
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(FontAwesomeIcons.barcode),
onPressed: (){
_scan(context);
},
)
),
onChanged: (string){
string = string.toLowerCase();
setState(() {
_booksForDisplay = _books.where((b){
var bName = b.name!.toLowerCase();
var bBarcode = b.barcode!.toLowerCase();
return bName.startsWith(string) || bBarcode.startsWith(string);
}).toList();
});
},
),
),
),
),
),
body: SafeArea(
child: Container(
child: _controller.text.isNotEmpty ? new ListView.builder(
itemCount: _booksForDisplay.length,
itemBuilder: (context, index){
return BookTile(book: this._booksForDisplay[index]);
},
)
:
Center(
child: Text('Searching..'),
)
),
)
);
}
}
I think you only need a listener for your TextEditingController. And you should write your onChanged method inside that listener.
#override
void initState() {
super.initState();
fetchBooks().then((value) {
setState(() {
_books.addAll(value);
_booksForDisplay = _books;
print(_booksForDisplay.length);
});
});
_controller.addListener(() {
print(_controller.text);
var string = _controller.text.toLowerCase();
setState(() {
_booksForDisplay = _books.where((b){
var bName = b.name!.toLowerCase();
var bBarcode = b.barcode!.toLowerCase();
return bName.startsWith(string) ||
bBarcode.startsWith(string);
}).toList();
});
});
}

Flutter with filter search page keeps adding same list view from query when returning to the page

I recently followed this answer : Listview filter search in Flutter on how to achieve a Flutter Listview with search filter . The filter works as explained in the answer . The problem each time i move of out of that particular page and then come back to it , then my results in the listview has doubled. When I go out of the page again , and come back again , it has tripled on so on .
I know I am supposed to clear the list somewhere when go out of the listview page , not sure where thou . Below the code from the example i followed . My MySQL Query is simply . SELECT * FROM table_name.
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(new MaterialApp(
home: new HomePage(),
debugShowCheckedModeBanner: false,
));
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController controller = new TextEditingController();
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
final response = await http.get(url);
final responseJson = json.decode(response.body);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Home'),
elevation: 0.0,
),
body: new Column(
children: <Widget>[
new Container(
color: Theme.of(context).primaryColor,
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
onSearchTextChanged('');
},),
),
),
),
),
new Expanded(
child: _searchResult.length != 0 || controller.text.isNotEmpty
? new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
child: new ListTile(
leading: new CircleAvatar(backgroundImage: new NetworkImage(_searchResult[i].profileUrl,),),
title: new Text(_searchResult[i].firstName + ' ' + _searchResult[i].lastName),
),
margin: const EdgeInsets.all(0.0),
);
},
)
: new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
child: new ListTile(
leading: new CircleAvatar(backgroundImage: new NetworkImage(_userDetails[index].profileUrl,),),
title: new Text(_userDetails[index].firstName + ' ' + _userDetails[index].lastName),
),
margin: const EdgeInsets.all(0.0),
);
},
),
),
],
),
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.firstName.contains(text) || userDetail.lastName.contains(text))
_searchResult.add(userDetail);
});
setState(() {});
}
}
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
final String url = 'my url address for mysql php query ';
class UserDetails {
final int id;
final String firstName, lastName, profileUrl;
UserDetails({this.id, this.firstName, this.lastName, this.profileUrl = 'https://i.amz.mshcdn.com/3NbrfEiECotKyhcUhgPJHbrL7zM=/950x534/filters:quality(90)/2014%2F06%2F02%2Fc0%2Fzuckheadsho.a33d0.jpg'});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
id: json['id'],
firstName: json['name'],
lastName: json['username'],
);
}
}
Try clearing the list before adding new values..
setState(() {
_userDetails.clear();
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
Try adding this
#override
void dispose() {
_userDetails .clear();
_searchResult.clear();
super.dispose();
}

Comma separated in AutoCompleteTextField in flutter

I am using a code which is working well and giving suggestion in dropdown menu by send a HTTP GET request.
import 'package:http/http.dart' as http;
import 'user.dart';
import 'dart:convert';
import 'package:autocomplete_textfield/autocomplete_textfield.dart';
class AutoCompleteDemo extends StatefulWidget {
AutoCompleteDemo() : super();
final String title = "AutoComplete Demo";
#override
_AutoCompleteDemoState createState() => _AutoCompleteDemoState();
}
class _AutoCompleteDemoState extends State<AutoCompleteDemo> {
AutoCompleteTextField searchTextField;
GlobalKey<AutoCompleteTextFieldState<User>> key = new GlobalKey();
static List<User> users = new List<User>();
bool loading = true;
void getUsers() async {
try {
final response =
await http.get("https://jsonplaceholder.typicode.com/users");
if (response.statusCode == 200) {
users = loadUsers(response.body);
print('Users: ${users.length}');
setState(() {
loading = false;
});
} else {
print("Error getting users.");
}
} catch (e) {
print("Error getting users.");
}
}
static List<User> loadUsers(String jsonString) {
final parsed = json.decode(jsonString).cast<Map<String, dynamic>>();
return parsed.map<User>((json) => User.fromJson(json)).toList();
}
#override
void initState() {
getUsers();
super.initState();
}
Widget row(User user) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
user.name,
style: TextStyle(fontSize: 16.0),
),
SizedBox(
width: 10.0,
),
Text(
user.email,
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
loading
? CircularProgressIndicator()
: searchTextField = AutoCompleteTextField<User>(
key: key,
clearOnSubmit: false,
suggestions: users,
style: TextStyle(color: Colors.black, fontSize: 16.0),
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
hintText: "Search Name",
hintStyle: TextStyle(color: Colors.black),
),
itemFilter: (item, query) {
return item.name
.toLowerCase()
.startsWith(query.toLowerCase());
},
itemSorter: (a, b) {
return a.name.compareTo(b.name);
},
itemSubmitted: (item) {
setState(() {
searchTextField.textField.controller.text = item.name;
});
},
itemBuilder: (context, item) {
// ui for the autocompelete row
return row(item);
},
),
],
),
);
}
}
Requirement:
I want to take the input something like this so that every selected item is separated and the drop-down list shown after an item selected.The user could be able to add its own new item which isn't from the list.