How to retrieve the data shown on the chat screen using streambuilder - flutter

I was trying to get the data from firebase to my chat screen using snapshot data but I am unable to get that as the message.data['text'] and sender gives me error. I want to display the name and the message all on the screen for now so please suggest the fix for this code or a alternative way for that
message code
import 'package:flutter/material.dart';
import 'package:flash_chat/constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatScreen extends StatefulWidget {
static String id = 'chat_screen';
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
User loggedInUser;
String message;
#override
void initState() {
// TODO: implement initState
getCurrentUser();
super.initState();
}
void getCurrentUser() {
try {
final user = _auth.currentUser;
if (user != null) {
loggedInUser = user;
// print(loggedInUser.email);
}
} catch (e) {
print(e);
}
}
void messageStream() async {
await for (var snapshot in _firestore.collection('messages').snapshots()) {
for (var message in snapshot.docs) {
print(message.data());
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
messageStream();
//Implement logout functionality
}),
],
title: Text('⚡️Chat'),
backgroundColor: Colors.lightBlueAccent,
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('messages').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightBlueAccent,
),
);
}
final messages = snapshot.data.docs;
List<Text> messagesWidgets = [];
for (var message in messages) {
final messageText = message.data['text']; //error
final messageSender = message.data['sender']; //error
final messageWidget = Text('$messageText from
$messageSender');
messageWidgets.add(messageWidget)
}
return Column(
children: messagesWidgets,
);
},
),
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
message = value;
//Do something with the user input.
},
decoration: kMessageTextFieldDecoration,
),
),
FlatButton(
onPressed: () {
//message + loggedInuser.email
//Implement send functionality
_firestore.collection('messages').add({
'text': message,
'sender': loggedInUser.email,
});
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
);
}
}

Related

_TypeError (type 'Future<dynamic>' is not a subtype of type 'Widget')

am trying to call the user from data (am using firebase as database)
the profile page not working for more understanding check the other issue i posted last day :
FirebaseException ([cloud_firestore/unavailable] The service is currently unavailable , and how to solve it
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:yumor/models/progress.dart';
import 'package:yumor/models/user_model.dart';
class profile extends StatefulWidget {
const profile({Key? key,required this.userProfile}) : super(key: key);
final String? userProfile;
#override
State<profile> createState() => _profileState();
}
class _profileState extends State<profile> {
final userRef = FirebaseFirestore.instance.collection('users');
buildprofileheader() async{
final doc=await userRef.doc(widget.userProfile).get();
if(doc.exists){
var data=doc.data();
}
return FutureBuilder(future:FirebaseFirestore.instance.collection('users').doc(userRef.id).get(),
builder: ((context, snapshot) {
if(!snapshot.hasData){
return CircularProgress();
}
UserModel user=UserModel.fromMap(Map);
return Padding(padding:EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_circle, size: 90,)
],
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12.0),
child: Text(
user.Username as String,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize:16.0,
),
),
),
],
),
);
}),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Profile",
),
),
body: ListView(children: <Widget>[
buildprofileheader(), // the error shows in this line <=======
]));
}
}
Your buildprofileheader return type is Future<Widget> but it should be Widget in order to use in ListView, so you need to use an other FutureBuilder to get userRef. So just wrap your current FutureBuilder with an other one.
As for the logic part, you can simplify the logic for future method something like
Future<UserModel?> getData() async {
try{
final userRef = FirebaseFirestore.instance.collection('users');
final doc = await userRef.doc(widget.userProfile).get();
if (doc.exists) {
var data = doc.data(); // not sure about this use case
} else {
return null;
}
final data = await FirebaseFirestore.instance
.collection('users')
.doc(userRef.id)
.get();
if (data.exists) {
UserModel user = UserModel.fromMap(data);
return user;
}
} catch(e){ }
}
Create a state variable for future method , and use like
late final future = getData();
Widget buildprofileheader() {
return FutureBuilder<UserModel?>(
future: future,
builder: ((context, snapshot) {
if (!snapshot.hasData) {
return CircularProgress();
}
return Padding(....
class _profileState extends State<profile> {
Future<UserModel?> getData() async {
final userRef = FirebaseFirestore.instance.collection('users');
final doc = await userRef.doc(widget.userProfile).get();
if (doc.exists) {
var data = doc.data(); // not sure about this use case
} else {
return null;
}
final data = await FirebaseFirestore.instance
.collection('users')
.doc(userRef.id)
.get();
if (data.exists) {
UserModel user = UserModel.fromMap(data);
return user;
}
}
late final future = getData();
Widget buildprofileheader() {
return FutureBuilder<UserModel?>(
future: future,
builder: ((context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
return Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.account_circle,
size: 90,
)
],
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12.0),
child: Text(
user.Username as String,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
],
),
);
}),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Profile",
),
),
body: ListView(children: <Widget>[
buildprofileheader(),
]));
}
}

StramBuilder not working , with no errors. FLUTTER

hey guys I'm new to Flutter, and I'm turning to build a very simple chat app for learning purposes, I'm using StreamBulider for that, it shows me no errors, but it's not working
I tread to add Text Widget on its own without the streambuilder so I can make sure that the problem with the streambulder function not anything else and it's works fine
can anyone help find what went wrong?
here is my code
import 'package:flutter/material.dart';
import 'package:flash_chat/constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatScreen extends StatefulWidget {
static String id = 'chat_screen';
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final _fireStore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
late String messegeText;
late User loogedInUser;
#override
void initState() {
super.initState();
getCurrentUser();
}
//------------------------------------------------------------------------------
// GetCurrentUser Method...
void getCurrentUser() async {
try {
// ignore: await_only_futures
final user = await _auth.currentUser;
if (user != null) {
loogedInUser = user;
}
} catch (e) {
print(e);
}
}
//------------------------------------------------------------------------------
// Get Masseges Method...
void messegesStream() async {
await for (var snapshot in _fireStore.collection('messeges').snapshots()) {
for (var message in snapshot.docs) {
print(message.data());
}
}
}
//------------------------------------------------------------------------------
// Code Start...
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurpleAccent,
leading: null,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.download),
onPressed: () {
messegesStream();
// _auth.signOut();
// Navigator.pop(context);
}),
],
title: const Text('⚡️Chat'),
),
body: Container(
constraints: const BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("images/background.jpg"), fit: BoxFit.cover),
),
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//------------------------------------------------------------
// StreamBuilder method...
StreamBuilder<QuerySnapshot>(
stream: _fireStore.collection('messages').snapshots(),
builder: (context, snapshot) {
List<Text> messageWidgets = [];
if (snapshot.hasData) {
final messages = snapshot.data!.docs;
for (var message in messages) {
final messageText = message.get('text');
final messageSender = message.get('sender');
final messageWidget =
Text('$messageSender said $messageText');
messageWidgets.add(messageWidget);
}
}
return Column(
children: messageWidgets,
);
},
),
//------------------------------------------------------------
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
messegeText = value;
},
decoration: kMessageTextFieldDecoration,
),
),
MaterialButton(
onPressed: () {
_fireStore.collection('messeges').add(
{
'text': messegeText,
'sender': loogedInUser.email,
},
);
},
child: const Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
),
);
}
}
my android emulator screen,
Try this code:
StreamBuilder<QuerySnapshot>(
stream: _fireStore.collection('messages').snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> chatSnapshot) {
if (chatSnapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Container(),
);
}
return ListView(
reverse: true,
controller: _controller,
physics: const BouncingScrollPhysics(),
children:
chatSnapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Text(data["text"]);
}).toList(),
);
},
),

Field 'urlVar' has not been initialized. error in Flutter

I have a settings page. On this page I configure "Url". I write it down and save it. Everything is simple. But I want to make sure that the next time I visit this page I have already seen the saved Url. I download it through the shared_preferences package (where I saved it). But there was an initialization error. Someone can help me with this. So that after opening the page I saw the saved Url and could edit it.
My code
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test/setting/сonfiguration_styles.dart';
class Setting extends StatefulWidget {
#override
_EditSettingPageState createState() => _EditSettingPageState();
}
class _EditSettingPageState extends State<Setting> {
late String urlVar;
late TextEditingController _apiController = TextEditingController();
_loadvariable() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
urlVar = (prefs.getString('apiUrl'))?? "";
});
}
#override
void initState() {
_loadvariable()?? "";
_apiController = TextEditingController( text: urlVar )
..addListener(() {
setState(() {});
});
super.initState();
}
#override
void dispose() {
_apiController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
TextFormField(
controller: _apiController,
cursorColor: StyleSettingPage.cursorColor,
style: StyleSettingPage.textBody,
),
SizedBox(height: StyleSettingPage.heightBtwButtItem),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: seveSettingUrl,
child: Text(
"Save",
style: StyleSettingPage.textButton
),
)
],
)
],
),
),
),
);
}
Future<void> seveSettingUrl() async {
SharedPreferences prefs = await SharedPreferences
.getInstance();
prefs.setString('apiUrl', _apiController.text);
}
}
Check this out:
First Page
import 'package:debounce/my_new_page.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class WritePage extends StatefulWidget {
const WritePage({Key? key}) : super(key: key);
#override
State<WritePage> createState() => _WritePageState();
}
class _WritePageState extends State<WritePage> {
final TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
TextFormField(
controller: controller,
),
SizedBox(height: 100),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences
.getInstance();
prefs.setString('apiUrl', controller.text);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Edit()),
);
},
child: Text(
"Save",
),
)
],
)
],
),
),
),
);
}
}
Second Page
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Edit extends StatefulWidget {
#override
_EditSettingPageState createState() => _EditSettingPageState();
}
class _EditSettingPageState extends State<Edit> {
var urlVar;
late TextEditingController _apiController = TextEditingController();
_loadvariable() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
urlVar = (prefs.getString('apiUrl'))?? "";
print("Get URL VALUE: $urlVar");
});
}
#override
void initState() {
_loadvariable();
super.initState();
}
#override
void dispose() {
_apiController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Column(
children: [TextFormField(
controller: TextEditingController( text: urlVar ),
decoration: InputDecoration(
// hintStyle: TextStyle(
// color: Colors.purple,
// fontStyle: FontStyle.italic,
// ),
),
),
SizedBox(height: 100),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences
.getInstance();
prefs.setString('apiUrl', _apiController.text);
print("SET URL VALUE: $urlVar");
},
child: Text(
"Edit",
),
)
],
)],
)
),
),
),
);
}
}

Preview photo after camera takes picture

When a user takes a photo, I want to send it to the photo_preview screen, which gives the user the chance to take another photo.
This page is as follows:
import 'package:flutter/material.dart';
import 'dart:io';
class photo_previewScreen extends StatelessWidget {
final String imagePath;
const photo_previewScreen({Key key, this.imagePath}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Display the Picture')),
body: Image.file(File(imagePath)),
);
}
}
On my current camera page, what's the best way for me to send the photo to the above page?
When the take picture button is pressed, this is what is currently happening:
onPressed: () {
_openGallery();
Navigator.pop(context);
},
EDIT: Full page with edits from the answer
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';
import 'package:stumble/pages/PhotoPreviewScreen.dart';
class Camera extends StatefulWidget {
Function setData;
Camera({Key key, this.setData}) : super(key: key);
#override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<Camera> {
CameraController controller;
List cameras;
int selectedCameraIndex;
String imgPath;
var image;
takePicture;
Future _openGallery() async {
image = await controller.takePicture();
if (widget.setData != null) {
widget.setData(File(image.path));
}
}
#override
void initState() {
super.initState();
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIndex = 0;
});
_initCameraController(cameras[selectedCameraIndex]).then((void v) {});
} else {
print('No camera available');
}
}).catchError((err) {
print('Error :${err.code}Error message : ${err.message}');
});
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller.addListener(() {
if (mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {}
if (mounted) {
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_cameraControlWidget(context), Spacer()],
),
),
)
],
),
),
),
);
}
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(children: <Widget>[
Positioned.fill(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
]);
}
Widget _cameraControlWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.center_focus_strong,
size: 39,
color: Color(0xffffffff),
),
backgroundColor: Color(0xff33333D),
onPressed: () async {
var result = await takePicture();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PhotoPreviewScreen(
imagePath: result,
),
),
);
})
],
),
),
);
}
}
I am getting the error that
'The method 'takePicture isn't defined for the type '_CameraScreenState'
This despite takePicture(); being defined.
You can navigate to the preview screen on clicking the take picture button, passing the image path:
void onTakePictureButtonPressed() async {
var result = await takePicture();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PhotoPreviewScreen(
imagePath: result,
),
),
);
}
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
showErrorFlushbar(context, 'Error: select a camera first.');
return null;
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/ompariwar';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
print(e);
return null;
}
return filePath;
}
In the preview screen, you can do this:
class PhotoPreviewScreen extends StatelessWidget {
final String imagePath;
const PhotoPreviewScreen({Key key, this.imagePath}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pop(context), // Go back to the camera to take the picture again
child: Icon(Icons.camera_alt),
),
appBar: AppBar(title: Text('Display the Picture')),
body: Column(
children: [
Expanded(child: Image.file(File(imagePath))),
SomeButton(), // Add a button to send the image to server or go back to home screen here
],
),
);
}
}
Btw it's a convention to name your class/ Widget name in UpperCamelCase. Read more on this Dart style guide for clean code.

Why my app throw error when i call the coronavirus API?

I am building a project about coronavirus tracker for my class. Everytime I tried to call the api and hit the serach icon it throw an error in the console. I have tried many things but it throw the same error. can anyone help figure out what is wrong with code?
class _HomePageState extends State<HomePage> {
List <Data> data = [];
var countryController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text('CoronaVirus Tracker')),
),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none, hintText: 'Enter a Country'),
controller: countryController,
),
),
IconButton(
icon: Icon(Icons.search),
color: Colors.blue,
onPressed: () {
fetchData().then((newData) {
setState(() {
data = newData as List<Data>;
});
});
}),
],
),
//The search item appear here
Expanded(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(data[index].country),
subtitle: Text(data[index].cases),
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Text('This is a new page!!')))
},
),
);
},
itemCount: data.length,
),
),
],
));
}
Here is the Api code
Future <Data> fetchData() async {
final response = await http.get('https://api.covid19api.com/live/country/malaysia/status/confirmed');
if (response.statusCode == 200) {
print(response.body);
// Transform json into object
return Data.fromJson(json.decode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load data');
}
}
}
Here is the constructor
class Data {
final String date;
final String country;
final String cases;
Data({this.date, this.country, this.cases});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
country: json['Country'],
date: json['Date'],
cases: json['Cases']);
}
}
From the above mentioned code I have created the a sample for you.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isLoading = false;
List<Data> data = List();
TextEditingController countryController = TextEditingController();
Future<List<Data>> fetchData(String countryName) async {
setState(() {
_isLoading = true;
});
//https://api.covid19api.com/live/country/india/status/confirmed
final response = await http.get(
'https://api.covid19api.com/live/country/$countryName/status/confirmed');
print(response.statusCode);
if (response.statusCode == 200) {
print(response.body);
// Transform json into object
var items = json.decode(response.body);
items.forEach((item) {
data.add(Data.fromJson(item));
});
return data;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load data');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Center(child: Text('CoronaVirus Tracker')),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a Country'),
controller: countryController,
),
),
IconButton(
icon: Icon(Icons.search),
color: Colors.blue,
onPressed: () {
fetchData(countryController.text).then((newData) {
setState(() {
data = newData;
_isLoading = false;
});
});
}),
],
),
),
_isLoading
? CircularProgressIndicator()
:
//The search item appear here
Expanded(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(data[index].date.toString()),
subtitle: Text(data[index].cases.toString()),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Text('This is a new page!!')));
},
),
);
},
itemCount: data.length,
),
),
],
)),
);
}
}
class Data {
final String date;
final String country;
final int cases;
Data({this.date, this.country, this.cases});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
country: json['Country'], date: json['Date'], cases: json['Active']);
}
}
Change the model class parameters as you like.
Just check out and let me know if it works.