How can we access the list item in flutter widget? - flutter

I am trying to access the fullName from the list created in my Future function, but unable to do. I tried it through indexing and this method I have tried snapshot.data.fullName, but still unable to retrieve the data, even after returning from future function I was facing problems.
Below is code for User model
class User {
final String fullname;
final String contactno;
final String address;
final String city;
final String gender;
final String email;
User(this.fullname, this.contactno, this.address, this.city, this.gender, this.email);
factory User.fromMap(Map<String, dynamic> json) {
return User(
json['fullname'],
json['contactno'],
json['address'],
json['city'],
json['gender'],
json['email']
);
}
}
Stateful Class Code
class EditProfile extends StatefulWidget {
// final String user_fullname;
// //const EditProfile(this.user_fullname);
// const EditProfile ({ Key key, this.user_fullname}): super(key: key);
#override
_EditProfileState createState() => _EditProfileState();
}
Future<List<User>> getData() async {
var id = "26";
var url = baseurl + patientData + id;
var data;
var rest;
print('Calling uri: $url');
// 4
http.Response response = await http.get(url);
// 5
if (response.statusCode == 200) {
data = response.body;
print(data);
} else {
print(response.statusCode);
}
//Map<String, dynamic> user = jsonDecode(data);
var jsonData = jsonDecode(data.body);
List<User> users = [];
for (var u in jsonData) {
User user = User(u['fullname'], u['contactno'], u['address'], u['city'], u['gender'], u['email']);
users.add(user);
}
// print(users.length.toString);
}
I want to access the fullName from my above list in future function in Text widget where I have used snapshot.data.fullName below
class _EditProfileState extends State<EditProfile> {
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
getData().then((value) {
print(value);
});
return FutureBuilder(
future: getData(),
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.hasData) {
return WillPopScope(
onWillPop: () {},
child: Scaffold(
appBar: AppBar(title: Text("Your Profile"), automaticallyImplyLeading: false, actions: <Widget>[
IconButton(
icon: Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => PatientDashboard()));
},
)
]),
body: SingleChildScrollView(
child: Container(
// color: Colors.pink,
child: Column(
children: [
Center(
child: Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Container(
// color: kPrimaryLightColor,
child: Stack(
children: [
//Image
CircleAvatar(
radius: 100,
backgroundColor: Colors.red[900],
child: CircleAvatar(
radius: 95,
backgroundImage: _pic == null ? AssetImage("assets/images/doctor2.jpg") : FileImage(_pic),
),
),
Positioned(
bottom: 5,
right: 15,
child: CircleAvatar(
backgroundColor: Colors.cyanAccent,
child: GestureDetector(
onTap: () {
setState(() {
//firstname = widget.user_fullname;
getImage();
state = 19;
});
},
child: Icon(Icons.camera_alt)),
radius: 20,
),
)
],
),
),
),
),
//Name
Container(
width: double.infinity,
//color: Colors.grey[400],
child: Stack(
children: [
Center(
child: Padding(
padding: const EdgeInsets.only(left: 18.0, top: 20),
child: Container(
//color: Colors.cyan[50],
width: MediaQuery.of(context).size.width * 0.78,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Name"),
Padding(
padding: const EdgeInsets.only(top: 2.0),
child: state == 1
? TextField(
decoration: InputDecoration(border: InputBorder.none, hintText: "${snapshot.data}", hintStyle: TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), //style: TextStyle(under),
onChanged: (text) {
firstname = text;
},
)
: Text(
snapshot.data.fullName,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold),
),
)],
else {
return Center(child: CircularProgressIndicator());
}
},
);
}
}
but I am getting this error
Error: NoSuchMethodError: 'body'
method not found
```
Arguments: []
at Object.throw_ [as throw] (http://localhost:59886/dart_sdk.js:5333:11)
at Object.defaultNoSuchMethod (http://localhost:59886/dart_sdk.js:5778:15)
at String.noSuchMethod (http://localhost:59886/dart_sdk.js:6878:19)
at Object.noSuchMethod (http://localhost:59886/dart_sdk.js:5774:30)
at Object.dload (http://localhost:59886/dart_sdk.js:5395:17)
at getData (http://localhost:59886/packages/newfypapproach/patient/screens/patientForgotPassword.dart.lib.js:12720:64)
at getData.next (<anonymous>)
at http://localhost:59886/dart_sdk.js:39031:33
at _RootZone.runUnary (http://localhost:59886/dart_sdk.js:38888:58)
at _FutureListener.thenAwait.handleValue (http://localhost:59886/dart_sdk.js:33874:29)
at handleValueCallback (http://localhost:59886/dart_sdk.js:34434:49)
at Function._propagateToListeners (http://localhost:59886/dart_sdk.js:34472:17)
at _Future.new.[_completeWithValue] (http://localhost:59886/dart_sdk.js:34314:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:59886/dart_sdk.js:34337:35)
at Object._microtaskLoop (http://localhost:59886/dart_sdk.js:39175:13)
at _startMicrotaskLoop (http://localhost:59886/dart_sdk.js:39181:13)
at http://localhost:59886/dart_sdk.js:34688:9
```
I had used this different approach for creating a future function returning list of strings and the list was working perfectly having all values.
```
Future<List<String>> getData() async {
var id = "26";
var url = baseurl + patientData + id;
var data;
var rest;
print('Calling uri: $url');
// 4
http.Response response = await http.get(url);
// 5
if (response.statusCode == 200) {
data = response.body;
print(data);
// rest = data['result'] as List;
// print(rest);
//print(data);
} else {
print(response.statusCode);
}
Map<String, dynamic> user = jsonDecode(data);
// var name = user['result']['name'];
String fullName = user['result'][0][0];
String contactNo = user['result'][0][1];
String address = user['result'][0][2];
String city = user['result'][0][3];
String gender = user['result'][0][4];
String email = user['result'][0][5];
return <String>[fullName, contactNo, address, city, gender, email];
}

Change your getData as follows
Future<List<User>> getData() async {
var id = "26";
var url = baseurl + patientData + id;
Map<String, dynamic> data ={};
var rest;
// 4
http.Response response = await http.get(url);
// 5
if (response.statusCode == 200) {
data = response.body;
print(data);
} else {
print(response.statusCode);
}
//Map<String, dynamic> user = jsonDecode(data);
var jsonData = jsonDecode(data);
List<User> users = [];
for (var u in jsonData) {
User user = User(u['fullname'], u['contactno'], u['address'], u['city'], u['gender'], u['email']);
users.add(user);
}
return users; }

Related

How can I make a list property of a model which comes from firebase observable with GetX in flutter?

I am trying to build an app in which users can share and like posts similar to social media apps. My problem is with liking posts. With the current code, I am getting the length of the 'likes' list from firebase, and when the user clicks the like button for the first time, adding the user's id to the list, and if the user clicks again, removing the id.
The problem is that when the user clicks the like button, there is a delay and the like count doesn't update instantly like in every other app.
What can I do to show the updates instantly?
This is the main screen:
class MainScreen extends StatelessWidget {
MainScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
TextEditingController textController = TextEditingController();
final PostController postController = Get.put(PostController());
return Scaffold(
body: Column(
children: [
Expanded(child: Obx(
() {
return ListView.builder(
itemCount: postController.postList.length,
controller: postController.scrollController,
itemBuilder: (context, index) {
var postData = postController.postList[index];
return PostBuilder(post: postData);
This is the PostBuider widget:
class PostBuilder extends StatelessWidget {
final Post post;
PostBuilder({
Key? key,
required this.post,
}) : super(key: key);
#override
Widget build(BuildContext context) {
PostController postController = Get.find();
return Column(
children: [
ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(post.profile_picture),
),
trailing: PopupMenuButton(
onSelected: (value) {},
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem(
value: MenuSelection.selection1,
child: Text(' '),
),
const PopupMenuItem(
value: MenuSelection.selection2,
child: Text(
' ',
style: TextStyle(color: Colors.red),
),
),
];
},
),
title: Text(
post.full_name ?? '',
style: TextStyle(
color: Colors.indigo.shade900,
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
post.date.toString(),
style: const TextStyle(color: Colors.grey),
),
),
Container(
alignment: Alignment.topLeft,
height: 99,
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SingleChildScrollView(
child: Text(
post.text ?? '',
textAlign: TextAlign.left,
),
),
),
Container(
padding: const EdgeInsets.only(left: 12, right: 28),
child: Obx(
() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconButton(
onPressed: () {
postController.likePost(post.id);
},
icon: Icon(Icons.thumb_up),
),
Text(
postController.likeCount.value.toString(),
style: kGreyText,
)
],
),
Row(
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.messenger),
),
Text(
'0',
style: kGreyText,
),
],
)
],
),
),
)
],
);
}
}
This is the PostController Class:
class PostController extends GetxController {
late Post post;
var isDataProcessing = false.obs;
final int _perPage = 10;
RxList<dynamic> postSnapshots = [].obs;
RxList<dynamic> postList = [].obs;
RxInt likeCount = 0.obs;
//For Pagination
ScrollController scrollController = ScrollController();
var isMoreDataAvailable = true.obs;
#override
void onInit() {
super.onInit();
getInitialPosts();
paginateList();
}
getInitialPosts() async {
print('getÄ°nitialPosts called');
Query q = fbFireStore
.collection('posts')
.orderBy('timestamp', descending: true)
.limit(_perPage);
QuerySnapshot snap = await q.get();
postSnapshots = snap.docs.obs;
for (int i = 0; i < postSnapshots.length; i++) {
post = Post.fromSnap(postSnapshots[i]);
postList.add(post);
}
}
void paginateList() {
scrollController.addListener(() {
if (scrollController.position.pixels ==
scrollController.position.maxScrollExtent) {
print('reached end of the page');
getMorePosts();
}
});
}
getMorePosts() async {
try {
print('getMorePosts called');
Query q = fbFireStore
.collection('posts')
.orderBy('timestamp', descending: true)
.startAfterDocument(postSnapshots[postSnapshots.length - 1])
.limit(_perPage);
QuerySnapshot snap = await q.get();
postSnapshots.value = snap.docs;
print('postSnapshots length is ${postSnapshots.length}');
for (int i = 0; i < postSnapshots.length; i++) {
post = Post.fromSnap(postSnapshots[i]);
postList.add(post);
}
Post lastPostCheck = postList[postList.length - 1];
print(lastPostCheck.full_name);
print('postList length is ${postList.length}');
} catch (e) {
Get.snackbar('error', e.toString());
}
}
void likePost(String id) async {
print(id);
DocumentSnapshot q = await fbFireStore.collection('posts').doc(id).get();
likeCount.value = q['likes'].length;
DocumentSnapshot doc = await fbFireStore.collection('posts').doc(id).get();
var uid = authController.user.uid;
if (doc['likes'].contains(uid)) {
likeCount.value--;
await fbFireStore.collection('posts').doc(id).update(
{
'likes': FieldValue.arrayRemove([uid]),
},
);
} else {
likeCount.value++;
await fbFireStore.collection('posts').doc(id).update({
'likes': FieldValue.arrayUnion([uid])
});
}
}
}
This is the Post Model:
class Post {
String? full_name;
String profile_picture;
String uid;
String? client;
String? full_url;
String id;
List? likes;
String? text;
String? thumb_storage_uri;
String? userid;
String? date;
Post({
required this.full_name,
this.profile_picture =
' ',
required this.uid,
required this.client,
this.full_url = '',
this.id = '',
required this.likes,
required this.text,
this.thumb_storage_uri = '',
required this.userid,
required this.date,
});
Map<String, dynamic> toJson() => {
'author': {
'full_name': full_name,
'profile_picture': profile_picture,
'uid': uid,
},
'client': client,
'full_url': full_url,
'id': id,
'likes': likes,
'text': text,
'thumb_storage_uri': thumb_storage_uri,
'userid': userid,
'timestamp': FieldValue.serverTimestamp(),
};
static Post fromSnap(DocumentSnapshot snap) {
var snapShot = snap.data() as Map<String, dynamic>;
return Post(
full_name: snapShot['author']['full_name'],
profile_picture: snapShot['author']['profile_picture'],
uid: snapShot['author']['uid'],
client: snapShot['client'],
id: snapShot['id'],
likes: snapShot['likes'],
text: snapShot['text'],
userid: snapShot['userid'],
date: snapShot['timestamp'].toString());
}
}
The solution I could think of was that when getting the posts for the ListViewBuilder, saving the length of the 'likes' list as a static value and using it as an observable integer but I couldn't achieve it with getx.
I am also very new in app development. If you have any advice about the rest of the code I would appreciate it.

I want to get api data from online and want to put into a list in flutter

fetchData is my function from where I call the API and put the data into an object, which is UserModel Somehow, it is working perfectly. But I want to put my data into a list because I want to make a search function where I can search by name. Look into my code, which will help you to understand.
Future<UserModel>? futureUser;
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// this is a way which I've tried already and it works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
But I want to put the data into a list and make the search available. Like if i put some name like r+a+b+b+i, it will show the matching name from the API.
I have tried this but I am not clear about the consepet. I am not familiar with how to manipulate the JSON data in a list or object or how to convert an object into a list.
List<UserModel>? userList = [];
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// var result= UserModel.fromJson(jsonDecode(response.body));
// print('this is result $userList');
return userList.add(UserModel.fromJson(jsonDecode(response.body)));
// this is an way which i tried already and its works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
This is my whole code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:learning_1ui_6228/utilities/app_colors.dart';
import 'package:learning_1ui_6228/utilities/helper.dart';
import 'package:learning_1ui_6228/utilities/widgets/app_line.dart';
import 'package:learning_1ui_6228/utilities/widgets/list_tile_widget.dart';
import 'package:learning_1ui_6228/views/nav_pages/profile_page.dart';
import 'package:http/http.dart' as http;
import '../model/UserModel.dart';
class FirstScreen extends StatefulWidget {
const FirstScreen({Key? key}) : super(key: key);
#override
State<FirstScreen> createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
Future<UserModel>? futureUser;
TextEditingController textController = TextEditingController();
// List<UserModel> userList=[];
#override
void initState() {
// searchedList = userList;
futureUser = fetchData();
super.initState();
}
List<UserModel>? userList = [];
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// var result= UserModel.fromJson(jsonDecode(response.body));
// print('this is result $userList');
return userList.add(UserModel.fromJson(jsonDecode(response.body)));
// this is an way which i tried already and its works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
List<UserModel> searchedList = [];
void searchUser(String enteredData){
print('entered word + ${enteredData}');
searchedList = [];
for(int i=0; i<userList!.length; i++){
if(userList[i].data![i].firstName!.toLowerCase().contains(enteredData.toLowerCase())){
searchedList.add(userList![i]);
}
}
}
#override
Widget build(BuildContext context) {
//print('user list data + $searchedList');
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xfff8f8fa),
body: Column(
children: [
//1st Section
Container(
height: HelperClass.h250,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: AppColors.gradientColor,
),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(HelperClass.r10),
bottomLeft: Radius.circular(HelperClass.r10))),
child: Column(
children: <Widget>[
//Text and cross button
Container(
margin: EdgeInsets.only(
left: HelperClass.w10,
right: HelperClass.w10,
top: HelperClass.h20),
height: HelperClass.h50,
// color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.clear,
color: Colors.white,
size: 30,
))),
Expanded(
child: Container(
margin: EdgeInsets.only(right: 30),
alignment: Alignment.center,
// color: Colors.lightBlueAccent,
child: Text(
'Search',
style: TextStyle(
fontSize: HelperClass.t25,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
],
),
),
SizedBox(
height: HelperClass.h25,
),
//Search Bar
Container(
margin: EdgeInsets.only(
left: HelperClass.w10, right: HelperClass.w10),
//color: Colors.amber,
height: HelperClass.h70,
width: double.infinity,
child: TextField(
controller: textController,
onChanged: (name) {
setState(() {
searchUser(name);
});
},
decoration: InputDecoration(
prefix: Icon(
Icons.search,
size: 26,
),
suffix: IconButton(
onPressed: () {
setState(() {
textController.clear();
searchedList = userList;
});
},
icon: Icon(
Icons.clear,
size: 26,
),
),
hintText: 'Search',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(3),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.white,
),
),
),
],
),
),
// List View
Expanded(
child: FutureBuilder<UserModel>(
future: futureUser,
builder: (context, snapshot){
if(snapshot.hasData){
return ListView.builder(
itemCount: snapshot.data!.data!.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(10),
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage(
userName:snapshot.data!.data![index].firstName??'',
followers: snapshot.data!.data![index].id.toString(),
address: snapshot.data!.data![index].email.toString(),
following: snapshot.data!.data![index].lastName.toString(),
imageUrl: snapshot.data!.data![index].avatar.toString(),
),
));
},
child: ListTileWidgets(
following: snapshot.data!.data![index].lastName.toString(),
address: snapshot.data!.data![index].email.toString(),
imageUrl:snapshot.data!.data![index].avatar.toString(),
name: snapshot.data!.data![index].firstName??'',
followersCount:
'Followers: ${snapshot.data!.data![index].id.toString()}',
iconWidget: Icon(
Icons.person_add_alt_outlined,
color: Colors.red,
size: 25,
),
),
),
AppLine(
paddingLeft: 10,
paddingRight: 10,
heightLine: 1,
lineColor: Colors.grey),
],
),
);
},
);
}
else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return Center(child: CircularProgressIndicator());
}),
),
],
),
),
);
}
}
This is my UserModel class
import 'dart:convert';
UserModel userModelFromJson(String str) => UserModel.fromJson(json.decode(str));
String userModelToJson(UserModel data) => json.encode(data.toJson());
class UserModel {
UserModel({
this.page,
this.perPage,
this.total,
this.totalPages,
this.data,
this.support,});
UserModel.fromJson(dynamic json) {
page = json['page'];
perPage = json['per_page'];
total = json['total'];
totalPages = json['total_pages'];
if (json['data'] != null) {
data = [];
json['data'].forEach((v) {
data?.add(Data.fromJson(v));
});
}
support = json['support'] != null ? Support.fromJson(json['support']) : null;
}
int? page;
int? perPage;
int? total;
int? totalPages;
List<Data>? data;
Support? support;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['page'] = page;
map['per_page'] = perPage;
map['total'] = total;
map['total_pages'] = totalPages;
if (data != null) {
map['data'] = data?.map((v) => v.toJson()).toList();
}
if (support != null) {
map['support'] = support?.toJson();
}
return map;
}
}
Support supportFromJson(String str) => Support.fromJson(json.decode(str));
String supportToJson(Support data) => json.encode(data.toJson());
class Support {
Support({
this.url,
this.text,});
Support.fromJson(dynamic json) {
url = json['url'];
text = json['text'];
}
String? url;
String? text;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['url'] = url;
map['text'] = text;
return map;
}
}
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
Data({
this.id,
this.email,
this.firstName,
this.lastName,
this.avatar,});
Data.fromJson(dynamic json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['email'] = email;
map['first_name'] = firstName;
map['last_name'] = lastName;
map['avatar'] = avatar;
return map;
}
}
this is my api link
https://reqres.in/api/users?page=2
No need to add UserModel to list.
change this
class _FirstScreenState extends State<FirstScreen> {
UserModel? usermodel;
List<Data?> searchResult= [];
change your fetch data . this will return UserModel as result.
Future<UserModel?> fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
create init function to set your initial data
void initFunction() async {
UserModel data = await fetchData(); // you have to await until get the response
//then setState to local variable so it can display to widget
// if you skip this , your usermodel is null
setState ({
usermodel = data ;
});
}
then in your initState
#override
void initState() {
initFunction();
super.initState();
}
usermodel.data consist of data user.
to then you can apply logic to search user from the list.
void searchUser(String enteredData){
List<Data?> temp = [];
for(int i=0; i<usermodel.data.length; i++){
if(enteredData.toLowerCase() == usermodel.data[i].firstName.toLowerCase()){
temp.add(usermodel.data[i];
}
}
// you need to setState again
setState({
searchResult = temp;
});
}
last in you can acces the data in userModel
#override
Widget build(BuildContext context) {
//print('user list data + $searchedList');
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xfff8f8fa),
body: Column(
children: [
Text('${usermodel.data.length}'), /// number all list user
Text('${searchResult.length}'), /// number search user
// now you have list all user
// and all searched list user
// additional, you need to add logic when query is empty
.................
maybe there error in null-safety, please debug first.
You can simply do this
var myList= []; // declare an empty list
if (response.statusCode == 200) {
var result= UserModel.fromJson(jsonDecode(response.body));
if(result != null){
myList.clear();
myList.addAll(result);
}
}

flutter Sqlite problem : my app doesnt generate a database

my console shows no error but still i cant generate a data base with my app i dont know where's the problem at first when i run the app and add a transaction and then i enter the transaction page it shows 'no transactions' and then when i left the app and get back it shows 'loading' and when i try add another transaction the button add doesnt respond i have to say that when i delete the part of the code about db the app works perfectly but without a database
import 'dart:io';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'transaction.dart';
class TransactionsDatabase {
static final TransactionsDatabase instance = TransactionsDatabase._init();
static Database? _database;
TransactionsDatabase._init();
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDB();
return _database!;
}
Future<Database> _initDB() async {
Directory documentsDirectory = await getApplicationSupportDirectory();
String path = join(documentsDirectory.path, 'TransactionsDatabase.db');
return await openDatabase(path, version: 1, onCreate: _createDB);
}
Future _createDB(Database db, int version) async {
final idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
final textType = 'TEXT NOT NULL';
final boolType = 'BOOLEAN NOT NULL';
final doubleType = 'DOUBLE NOT NULL';
await db.execute('''
CREATE TABLE $tableTransactions (
${TransactionFields.id} $idType,
${TransactionFields.isIncome} $boolType,
${TransactionFields.Tname} $textType,
${TransactionFields.Tamount} $doubleType,
${TransactionFields.time} $textType
)
''');
}
Future<int> create(Transactionn transactionn) async {
Database db = await instance.database;
return await db.insert(tableTransactions, transactionn.toJson());
}
Future<List<Transactionn>> readAllNotes() async {
Database db = await instance.database;
var transactions =
await db.query(tableTransactions, orderBy: TransactionFields.Tname);
List<Transactionn> transactionList = transactions.isNotEmpty
? transactions.map((json) => Transactionn.fromJson(json)).toList()
: [];
return transactionList;
}
Future close() async {
final db = await instance.database;
db.close();
}
}
my class exemple look like this : Transaction.dart
final String tableTransactions = 'transactions';
class TransactionFields {
static final List<String> values = [
/// Add all fields
id, isIncome, Tname, Tamount, time
];
static final String id = '_id';
static final String isIncome = 'isIncome';
static final String Tname = 'tname';
static final String Tamount = 'tamount';
static final String time = 'time';
}
class Transactionn {
final int? id;
final bool isIncome;
final String Tname;
final double Tamount;
final DateTime createdTime;
const Transactionn(
{this.id,
required this.isIncome,
required this.Tname,
required this.Tamount,
required this.createdTime});
Map<String, Object?> toJson() => {
TransactionFields.id: id,
TransactionFields.isIncome: isIncome ? 1 : 0,
TransactionFields.Tname: Tname,
TransactionFields.Tamount: Tamount,
TransactionFields.time: createdTime.toIso8601String(),
};
Transactionn copy({
int? id,
bool? isIncome,
String? Tname,
double? Tamount,
DateTime? createdTime,
}) =>
Transactionn(
id: id ?? this.id,
isIncome: isIncome ?? this.isIncome,
Tname: Tname ?? this.Tname,
Tamount: Tamount ?? this.Tamount,
createdTime: createdTime ?? this.createdTime,
);
static Transactionn fromJson(Map<String, Object?> json) => Transactionn(
id: json[TransactionFields.id] as int?,
isIncome: json[TransactionFields.isIncome] == 1,
Tname: json[TransactionFields.Tname] as String,
Tamount: json[TransactionFields.Tamount] as double,
createdTime: DateTime.parse(json[TransactionFields.time] as String),
);
}
in my Homepage class i use a dialogbox to add a transaction to my db :
onPressed: () async {
if (_IncomeName.text.isNotEmpty &
_IncomeAmountName.text.isNotEmpty) {
IncomeName = _IncomeName.text;
IncomeAmountName = _IncomeAmountName.text;
IncomeAmount = double.parse(IncomeAmountName);
IncomeAmount = IncomeAmount.toDouble();
await TransactionsDatabase.instance.create(Transactionn(
isIncome: true,
Tname: IncomeName,
Tamount: IncomeAmount,
createdTime: DateTime.now()));
tt = preferences.getDouble('total');
if (tt == null) {
ttt = IncomeAmount;
} else {
ttt = IncomeAmount + tt!;
}
preferences.setDouble('total', ttt);
setState(() {
capital = preferences.getDouble('total') as double;
});
_IncomeName.clear();
_IncomeAmountName.clear();
Navigator.pop(context);
} else {}
},
and then i have a transactions page where im supposed to see all my db contents transactions.dart
import 'package:flutter/material.dart';
import 'package:mywallet/Database_Helper.dart';
import 'package:mywallet/transaction.dart';
class TransactionsPage extends StatefulWidget {
const TransactionsPage({Key? key}) : super(key: key);
#override
State<TransactionsPage> createState() => _TransactionsPageState();
}
class _TransactionsPageState extends State<TransactionsPage> {
List<Transactionn> transactions = [];
bool isLoading = false;
#override
void initState() {
refreshTransactions();
super.initState();
}
#override
void dispose() {
TransactionsDatabase.instance.close();
super.dispose();
}
Future refreshTransactions() async {
setState(() {
isLoading = true;
});
this.transactions = await TransactionsDatabase.instance.readAllNotes();
setState(() {
isLoading = false;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black26,
body: Container(
padding:
const EdgeInsets.only(top: 40, left: 15, right: 15, bottom: 40),
child: Column(
children: [
Row(
children: [
const SizedBox(
width: 20,
),
IconButton(
icon: Image.asset(
'images/Images/back.png',
width: 24,
height: 24,
),
onPressed: () {
Navigator.pop(context);
},
)
],
),
const SizedBox(
height: 70,
),
Container(
width: MediaQuery.of(context).size.width,
height: 350,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 25, 28, 31),
borderRadius: BorderRadius.circular(30)),
child: Container(
padding: const EdgeInsets.only(
top: 30, left: 20, right: 10, bottom: 10),
child: Column(
children: [
Row(
children: const [
Text('Transactions : ',
style: TextStyle(
fontSize: 14,
color: Color.fromARGB(249, 95, 190, 188),
fontWeight: FontWeight.bold))
],
),
const SizedBox(height: 20),
Center(
child: FutureBuilder<List<Transactionn>>(
future: TransactionsDatabase.instance.readAllNotes(),
builder: (BuildContext context,
AsyncSnapshot<List<Transactionn>> snapshot) {
if (!snapshot.hasData) {
return Center(
child: Text(
'Loading..',
style: TextStyle(
color: Colors.white, fontSize: 20),
));
}
return snapshot.data!.isEmpty
? const Center(
child: Text(
'no traansactiions',
style: TextStyle(
color: Colors.white, fontSize: 20),
))
: ListView(
children:
snapshot.data!.map((Transactionn) {
return Center(
child: ListTile(
title: Text(Transactionn.Tname),
),
);
}).toList(),
);
},
),
)
],
),
))
],
),
),
);
}
}

Dropdown in flutter from LIST

Displaying the data from my API based on the Dropdown selected value. I want to display on the same page. The data from the server(response) is displaying on the console. But still, this data is not displaying.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
//import 'package:json_parsing_example/model2.dart';
//import 'package:json_parsing_example/models.dart'
List<YouModel> youModelFromJson(String str) => List<YouModel>.from(json.decode(str).map((x) => YouModel.fromJson(x)));
String youModelToJson(List<YouModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class YouModel {
String columnName;
YouModel({
this.columnName,
});
factory YouModel.fromJson(Map<String, dynamic> json) => YouModel(
columnName: json["column_name"],
);
Map<String, dynamic> toJson() => {
"column_name": columnName,
};
}
UserModel userModelFromJson(String str) => UserModel.fromJson(json.decode(str));
String userModelToJson(UserModel data) => json.encode(data.toJson());
class UserModel {
String username;
String name;
UserModel({
this.username,
this.name,
});
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
username: json["username"],
name: json["Name"],
);
Map<String, dynamic> toJson() => {
"username": username,
"Name": name,
};
}
class Addoffers2 extends StatefulWidget {
#override
State<StatefulWidget> createState() => _Addoffers2State();
}
class _Addoffers2State extends State<Addoffers2> {
List<String> _companies = [];
bool _isLoading = false;
String _selectedCompany;
#override
void initState() {
super.initState();
_selectedCompany=null;
_getcompanylist();
}
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
_getcompanylist() async {
setState(() {
_isLoading = true;
});
print("getting..");
final responseStr =
await http.get('http://10.0.2.2/Flutter/GetCompanieslist.php');
//String responseStr = await loadFromAssets();
final listData = youModelFromJson(responseStr.body);
for(int i=0;i<listData.length;i++)
{
print('this is the list :'+listData[i].columnName);
// _companies.add(listData[i].columnName);
}
// above method is the standard method to get creating a model class and then get the list of strings
// I have just shown you but example is according to you code .
// this above loadFromAssets is that you hit the api and you get the json string response
// i have created a dummy json file where i can the String.
// Else everything is the same as below you just have to pass the response.body to the json.decode method.
var jsonData = json.decode(responseStr.body);
for (var u in jsonData) {
_companies.add(u.toString().substring(14, u.toString().length - 1));
}
for (int i = 0; i < _companies.length; i++) {
print(_companies[i].toString());
}
setState(() {
_isLoading = false;
});
}
#override
Widget build(BuildContext context) {
//double width = MediaQuery.of(context).size.width;
//double height = MediaQuery.of(context).size.height;
return MaterialApp(
//color: Colors.red,
home: Scaffold(
backgroundColor: Colors.red,
appBar: AppBar(
backgroundColor: Theme.of(context).backgroundColor,
title: Text("Add.."),
),
body: Container(
color: Colors.blue,
// just put your height i have modified it replace it by height / 8
child: _isLoading
? CircularProgressIndicator()
: Center(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
//MainAxisAlignment: MainAxisAlignment.spaceBetween,
Text('Choose..'),
DropdownButtonHideUnderline(
child: DropdownButton(
// hint: Text('Choose Company'), // Not necessary for Option 1
value: _selectedCompany,
onChanged: (newValue) {
setState(() {
_selectedCompany = newValue;
// here i have taken the boolen variable to show and hide the list if you have not seleted the value from the dropdown the it will show the text and if selected the it will show you the list.
});
print(_selectedCompany);
},
items: _companies.map((company) {
return DropdownMenuItem(
child: new Text(company.toString()),
value: company,
);
}).toList(),
),
),
],
),
),
),
// this is to to check for the initial if string is null then show the text widget.
// else if the value is selected then it will show the listview
_selectedCompany == null
? Text('Select the dropdown value for list to appear.')// sample text you can modify
: Padding(
padding: const EdgeInsets.all(0.0),
child: Container(
height: 100,
color: Theme.of(context).backgroundColor,
child: new FutureBuilder(
future: _getUsers(
_selectedCompany), // a Future<String> or null
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
child: Center(
child: new CircularProgressIndicator(
backgroundColor: Colors.white,
),
));
}
if (snapshot.hasError) {
return Center(
child: new Text(
'Error ${snapshot.error}'),
);
} else {
return Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(
5.0, 8.0, 5.0, 8.0),
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder:
(BuildContext context,
int index) {
List<UserModel> user =
snapshot.data;
var username =
user[index].username;
var stuname =
user[index].name;
print(
'This is the user name :$username');
print(
'This is the name : $stuname');
//var title=snapshot.data[index]["Title"];
// new Text(parsedDate.toString());
return StudentList2(
regdNo: username,
name: stuname);
}),
),
);
}
}),
),
),
],
)),
)),
);
}
}
Future<String> loadFromAssets2() async {
return await rootBundle.loadString('json/parse2.json');
}
// the above method is just for the sample purpose where you get you json String after hitting the api call for _getUsers method
Future<List<UserModel>> _getUsers(String selectedcompany) async {
// here you call you api and you get the response
var url = 'https://10.0.2.2/Flutter/getstudentdata.php;
var data = { 'company': selectedcompany};
// Starting Web Call with data.
var response = await http.post(url, body: json.encode(data));
print(response.body);
//String responseStr = await loadFromAssets2();
final userModel = userModelFromJson(response.body);
// I have just made the model class for where fromt he below you get the complete object and then added to the list and returned.
List<UserModel> users = [];
users.add(userModel);
print('This is the name : ${users[0].name}'); // Even this also not getting printed
return users;
}
class StudentList2 extends StatefulWidget {
final regdNo;
final name;
const StudentList2({
Key key,
this.regdNo,
this.name,
}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<StudentList2> {
bool visible = false;
#override
Widget build(BuildContext context) {
print(widget.regdNo.toString());
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: new Card(
color: Theme.of(context).primaryColor,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 2.0),
child: Container(
child: new Text(
widget.regdNo.toUpperCase(),
style: TextStyle(
color: Colors.yellowAccent,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
),
),
ListTile(
title: new Text(
widget.regdNo,
style: TextStyle(
color: Colors.black,
fontSize: 14.0,
),
),
subtitle: new Text(
(widget.name),
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
),
),
//
],
)),
);
}
}
I am able to retrieve the data from the server and print it on the console. Still, the data is not displaying. I do not know where I did the mistake.
So I have completely updated the answer and there are many things that you don't follow according to the global standard.
So I have listed some of the key things that you should follow :
Following is you company list json :
[
{
"column_name": "ABC"
},
{
"column_name": "XYZ"
}
]
Following is the get user json that you will get :
{"username":"1111","Name":"ABC" }
And Later the model class I have create accordingly to the json that you provided and then you can create your own based in the added json.
There are Two model classes that I have created :
First model class is for the company :
// To parse this JSON data, do
//
// final youModel = youModelFromJson(jsonString);
import 'dart:convert';
List<YouModel> youModelFromJson(String str) => List<YouModel>.from(json.decode(str).map((x) => YouModel.fromJson(x)));
String youModelToJson(List<YouModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class YouModel {
String columnName;
YouModel({
this.columnName,
});
factory YouModel.fromJson(Map<String, dynamic> json) => YouModel(
columnName: json["column_name"],
);
Map<String, dynamic> toJson() => {
"column_name": columnName,
};
}
second mode class is for the user :
// To parse this JSON data, do
//
// final userModel = userModelFromJson(jsonString);
import 'dart:convert';
UserModel userModelFromJson(String str) => UserModel.fromJson(json.decode(str));
String userModelToJson(UserModel data) => json.encode(data.toJson());
class UserModel {
String username;
String name;
UserModel({
this.username,
this.name,
});
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
username: json["username"],
name: json["Name"],
);
Map<String, dynamic> toJson() => {
"username": username,
"Name": name,
};
}
Below is the main ui file just Check the comments that I have made so that it will be helpful for you .
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:json_parsing_example/model2.dart';
import 'package:json_parsing_example/models.dart';
void main() => runApp(Addoffers());
class Addoffers extends StatefulWidget {
#override
State<StatefulWidget> createState() => _AddoffersState();
}
class _AddoffersState extends State<Addoffers> {
List<String> _companies = [];
bool _isLoading = false;
String _selectedCompany;
#override
void initState() {
super.initState();
_selectedCompany=null;
_getcompanylist();
}
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
_getcompanylist() async {
setState(() {
_isLoading = true;
});
print("getting..");
/* final response =
await http.get('http://10.0.2.2/Flutter/GetCompanieslist.php'); */
String responseStr = await loadFromAssets();
final listData = youModelFromJson(responseStr);
for(int i=0;i<listData.length;i++)
{
print('this is the list :'+listData[i].columnName);
// _companies.add(listData[i].columnName);
}
// above method is the standard method to get creating a model class and then get the list of strings
// I have just shown you but example is according to you code .
// this above loadFromAssets is that you hit the api and you get the json string response
// i have created a dummy json file where i can the String.
// Else everything is the same as below you just have to pass the response.body to the json.decode method.
var jsonData = json.decode(responseStr);
for (var u in jsonData) {
_companies.add(u.toString().substring(14, u.toString().length - 1));
}
for (int i = 0; i < _companies.length; i++) {
print(_companies[i].toString());
}
setState(() {
_isLoading = false;
});
}
#override
Widget build(BuildContext context) {
//double width = MediaQuery.of(context).size.width;
//double height = MediaQuery.of(context).size.height;
return MaterialApp(
//color: Colors.red,
home: Scaffold(
backgroundColor: Colors.red,
appBar: AppBar(
backgroundColor: Theme.of(context).backgroundColor,
title: Text("Add.."),
),
body: Container(
color: Colors.blue,
// just put your height i have modified it replace it by height / 8
child: _isLoading
? CircularProgressIndicator()
: Center(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
//MainAxisAlignment: MainAxisAlignment.spaceBetween,
Text('Choose..'),
DropdownButtonHideUnderline(
child: DropdownButton(
// hint: Text('Choose Company'), // Not necessary for Option 1
value: _selectedCompany,
onChanged: (newValue) {
setState(() {
_selectedCompany = newValue;
// here i have taken the boolen variable to show and hide the list if you have not seleted the value from the dropdown the it will show the text and if selected the it will show you the list.
});
print(_selectedCompany);
},
items: _companies.map((company) {
return DropdownMenuItem(
child: new Text(company.toString()),
value: company,
);
}).toList(),
),
),
],
),
),
),
// this is to to check for the initial if string is null then show the text widget.
// else if the value is selected then it will show the listview
_selectedCompany == null
? Text('Select the dropdown value for list to appear.')// sample text you can modify
: Padding(
padding: const EdgeInsets.all(0.0),
child: Container(
height: 100,
color: Theme.of(context).backgroundColor,
child: new FutureBuilder(
future: _getUsers(
_selectedCompany), // a Future<String> or null
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
child: Center(
child: new CircularProgressIndicator(
backgroundColor: Colors.white,
),
));
}
if (snapshot.hasError) {
return Center(
child: new Text(
'Error ${snapshot.error}'),
);
} else {
return Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(
5.0, 8.0, 5.0, 8.0),
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder:
(BuildContext context,
int index) {
List<UserModel> user =
snapshot.data;
var username =
user[index].username;
var stuname =
user[index].name;
print(
'This is the user name :$username');
print(
'This is the name : $stuname');
//var title=snapshot.data[index]["Title"];
// new Text(parsedDate.toString());
return StudentList2(
regdNo: username,
name: stuname);
}),
),
);
}
}),
),
),
],
)),
)),
);
}
}
Future<String> loadFromAssets2() async {
return await rootBundle.loadString('json/parse2.json');
}
// the above method is just for the sample purpose where you get you json String after hitting the api call for _getUsers method
Future<List<UserModel>> _getUsers(String selectedcompany) async {
/* var data = await http.post("http://10.0.2.2/Flutter/getstdata.php", body: {
"company": selectedcompany,
//print(data.body);
}); */
// here you call you api and you get the response
String responseStr = await loadFromAssets2();
final userModel = userModelFromJson(responseStr);
// I have just made the model class for where fromt he below you get the complete object and then added to the list and returned.
List<UserModel> users = [];
users.add(userModel);
print('This is the name : ${users[0].name}');
//final x=users.length.toString();
//debugPrint("records:" + users.length.toString());
//debugPrint("kkk:" + absentees.length.toString());
return users;
}
class StudentList2 extends StatefulWidget {
//MyHomePage(String branch);
final regdNo;
final name;
const StudentList2({
Key key,
this.regdNo,
this.name,
}) : super(key: key);
//final String branch;
//const StudentList({Key key, this.branch}) : super(key: key);
//MyHomePage(String branch);
// final String title;
// final String branch="";
// MyHomePage(String branch, {Key key, this.title}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<StudentList2> {
bool visible = false;
//bool _btnEnabled = false;
//bool _validate = false;
// var _firstPress = true ;
//Color _iconColor = Colors.yellow;
//Color _iconColor2 = Colors.white;
//var poll;
//DateTime parsedDate;
#override
Widget build(BuildContext context) {
print(widget.regdNo.toString());
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: new Card(
color: Theme.of(context).primaryColor,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 2.0),
child: Container(
child: new Text(
widget.regdNo.toUpperCase(),
style: TextStyle(
color: Colors.yellowAccent,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
),
),
ListTile(
title: new Text(
widget.regdNo,
style: TextStyle(
color: Colors.black,
fontSize: 14.0,
),
),
subtitle: new Text(
(widget.name),
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
),
),
//
],
)),
);
}
}
// This is not the good approach to create a model class just check the sample model class that i have created.
class User {
//final int index;
final String username;
final String name;
//final Float cgpa;
User(
this.username,
this.name,
);
}
And below is the sample Gif file for you :
As stated by #pskink the method _getcompanylist() is async. An async function runs asynchronously, which means that the rest of the program doesn't wait for it to complete. You can use a future builder to deal whit that or you can simply wait for it by using the await function. I believe that for your code snippet future builder is the better choice.

How to pass a list object from one class to another

I am working on a simple Todolist app. I have created a database to store the data under the file "to_do_item.dart". the file "database_helper.dart" is where i have stored all the CRUD functions.
When the app is opened, the user will see a screen created under the file "todo_list.dart" where the added tasks will be displayed in a listview. when the user clicks the action button, it will send them to "input_screen.dart" where there is a textfield to enter the tasks. after the user clicks "done" on the on-screen keyboard, the data will be saved in a list called "Itemlist" (line 49 of "input_screen").
I want to send this list to "todo_list.dart" and display them in a scrollable listview but i am unsure of what method to use. At the moment i am only trying to add the item and display it.
Tried using getters but was unable to use it for another class, and tried searching how other todolist apps on flutter were made but they use an AlertDialog on the same class; i want to take input from one screen(class InputScreen) and display it on another screen (class TodoList).
CODE UNDER "todo_list.dart" -
Container(
color: Colors.white,
alignment: Alignment.topLeft,
margin: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 110,),
Text( "tasks for today",),
SizedBox(height: 20,),
//Todo: display listview on below column
// Column(
// children: <Widget>[
// new Flexible(child: ListView.builder(
itemBuilder:(_,intindex){
// return ListTile(
//// title: _itema,
// );
// }
// )
// )
// ],
// ),
SizedBox(height: 320,),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => InputScreen()));
},
heroTag: "btn2",
child: Icon(Icons.add, color: Colors.white,), backgroundColor: Colors.black87,),
],
)
]
),
),
CODE UNDER "input_screen.dart"
class InputScreen extends StatefulWidget {
#override
_InputScreenState createState() => _InputScreenState();
}
class _InputScreenState extends State<InputScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
_readList();
}
void _handleSubmitted(String text) async{
taskcontroller.clear();
TodoItem obj = new TodoItem(text, DateTime.now().toIso8601String());
int SavedItemId = await db.saveItem(obj);
print("item saved id: $SavedItemId");
print("$text");
TodoItem addedItem = await db.getItem(SavedItemId);
setState(() {
Itemlist.insert(0, addedItem);
});
}
_readList() async{
List items = await db.getItems();
items.forEach((item) {
TodoItem todoItem = TodoItem.map(items);
print("db it4ems: ${todoItem.itemName.toString()}");
});
}
var db = new DatabaseHelper();
final List<TodoItem> Itemlist= <TodoItem>[];
TextEditingController taskcontroller = new TextEditingController();
#override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIOverlays([]);
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.white,
alignment: Alignment.topLeft,
margin: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 110,),
Text("tasks for today:",),
SizedBox(height: 10,),
//Todo: remove sized box below and display tasks there
TextField(
autofocus: true,
onEditingComplete: (){Navigator.pop(context);},
maxLength: 10,
onSubmitted: (NewValue){ _handleSubmitted(NewValue);},
controller: taskcontroller,
decoration: InputDecoration(
labelText: "enter tasks here"
),
style: TextStyle(height: 1.2, fontSize: 20, color: Colors.black87),
)
]
),
),
],
),
),
);
}
}
CODE UNDER "to_do_item.dart" -
import 'package:flutter/material.dart';
class TodoItem extends StatelessWidget {
String _itemName;
String _dateCreated;
int _id;
TodoItem(this._itemName, this._dateCreated);
TodoItem.map(dynamic obj) {
this._itemName = obj["itemName"];
this._dateCreated = obj["dateCreated"];
this._id = obj["id"];
}
String get itemName => _itemName;
String get dateCreated => _dateCreated;
int get id => _id;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["itemName"] = _itemName;
map["dateCreated"] = _dateCreated;
if (_id != null) {
map["id"] = _id;
}
return map;
}
TodoItem.fromMap(Map<String, dynamic> map) {
this._itemName = map["itemName"];
this._dateCreated = map["dateCreated"];
this._id = map["id"];
}
#override
Widget build(BuildContext context) {
return new Container(
margin: const EdgeInsets.all(8.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(_itemName, )
],
),
],
),
);
}
}
CODE UNDER "database_helper.dart" -
import 'dart:io';
import 'to_do_item.dart';
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
final String tableName = "todotbl";
final String columnId = "id";
final String columnItemName = "itemName";
final String columnDateCreated = "dateCreated";
static Database _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "todolist_db.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE $tableName(id INTEGER PRIMARY KEY, $columnItemName TEXT, $columnDateCreated TEXT)");
print("Table is created");
}
//insertion
Future<int> saveItem(TodoItem item) async {
var dbClient = await db;
int res = await dbClient.insert("$tableName", item.toMap());
print(res.toString());
return res;
}
//Get
Future<List> getItems() async {
var dbClient = await db;
var result = await dbClient.rawQuery(
"SELECT * FROM $tableName ORDER BY $columnItemName ASC"); //ASC
return result.toList();
// if (result.length == 0) return [];
// var users = [];
//
// for (Map<String, dynamic> map in result) {
// users.add(new User.fromMap(map));
// }
//
// return users;
}
Future<int> getCount() async {
var dbClient = await db;
return Sqflite.firstIntValue(await dbClient.rawQuery(
"SELECT COUNT(*) FROM $tableName"
));
}
//
Future<TodoItem> getItem(int id) async {
var dbClient = await db;
var result = await dbClient.rawQuery(
"SELECT * FROM $tableName WHERE id = $id");
if (result.length == 0) return null;
return new TodoItem.fromMap(result.first);
}
//deletion
// Future<int> deleteItem(int id) async {
// var dbClient = await db;
// var result = await dbClient.rawQuery("DELETE FROM $tableName WHERE id = $id");
// if (result.length == 0) return null;
// return result.first as int;
// }
Future<int> deleteItem(int id) async {
var dbClient = await db;
return await dbClient.delete(tableName,
where: "$columnId = ?", whereArgs: [id]);
}
Future<int> updateItem(TodoItem item) async {
var dbClient = await db;
return await dbClient.update("$tableName", item.toMap(),
where: "$columnId = ?", whereArgs: [item.id]);
}
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}
This is possibly a duplicate of this
Nonetheless I hope this helps
class FrontPage extends StatefulWidget {
#override
_FrontPageState createState() => _FrontPageState();
}
class _FrontPageState extends State<FrontPage> {
// Activity currentActivity;
var recentActivities = <Widget>[];//<Widget>[Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary()];
var upcomingActivities = <Widget>[];//<Widget>[Activity("Jog", "assets/activity_logos/Squat.png", status: ActivityStatus.completed,).getSummary()];
List<String> tasks = ["previous1", "previous2"];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Home'),
actions: <Widget>[
GestureDetector(
child: Align(child:Text("+", style: TextStyle(fontSize: 40)), alignment: Alignment.centerLeft, widthFactor: 2,),
onTap: () => Navigator.pushNamed(context, '/activity/new'),
)
],
),
body: Container(
color: Colors.white,
alignment: Alignment.topLeft,
margin: const EdgeInsets.all(20),
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 110,),
Text( "tasks for today",),
SizedBox(height: 20,),
Expanded(child: ListView.builder(
itemCount: tasks.length,
itemBuilder: (BuildContext context, int index) {
return Text(tasks[index]);
})),
]),
FloatingActionButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InputScreen(),
));
setState(() {
tasks.add(result);
});
},
heroTag: "btn2",
child: Icon(Icons.add, color: Colors.white,), backgroundColor: Colors.black87,),
]),
),
);
}
}
class InputScreen extends StatefulWidget {
#override
_InputScreenState createState() => _InputScreenState();
}
class _InputScreenState extends State<InputScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
// _readList();
}
// final List<TodoItem> Itemlist= <TodoItem>[];
TextEditingController taskcontroller = new TextEditingController();
#override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIOverlays([]);
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.white,
alignment: Alignment.topLeft,
margin: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 110,),
Text("tasks for today:",),
SizedBox(height: 10,),
//Todo: remove sized box below and display tasks there
TextField(
autofocus: true,
onEditingComplete: () {
String textToSendBack = taskcontroller.text;
Navigator.pop(context, textToSendBack );
},
maxLength: 10,
onSubmitted: (NewValue){ },
controller: taskcontroller,
decoration: InputDecoration(
labelText: "enter tasks here"
),
style: TextStyle(height: 1.2, fontSize: 20, color: Colors.black87),
)
]
),
),
],
),
),
);
}
}
class TodoItem extends StatelessWidget {
String _itemName;
String _dateCreated;
int _id;
TodoItem(this._itemName, this._dateCreated);
TodoItem.map(dynamic obj) {
this._itemName = obj["itemName"];
this._dateCreated = obj["dateCreated"];
this._id = obj["id"];
}
String get itemName => _itemName;
String get dateCreated => _dateCreated;
int get id => _id;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["itemName"] = _itemName;
map["dateCreated"] = _dateCreated;
if (_id != null) {
map["id"] = _id;
}
return map;
}
TodoItem.fromMap(Map<String, dynamic> map) {
this._itemName = map["itemName"];
this._dateCreated = map["dateCreated"];
this._id = map["id"];
}
#override
Widget build(BuildContext context) {
return new Container(
margin: const EdgeInsets.all(8.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(_itemName, )
],
),
],
),
);
}
}
The main changes consist of
On input page:
TextField(
autofocus: true,
onEditingComplete: () {
String textToSendBack = taskcontroller.text;
Navigator.pop(context, textToSendBack );
}
On the front page:
FloatingActionButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InputScreen(),
));
setState(() {
tasks.add(result);
});
},
Some widgeting layout, and I am keeping the data in a tasks array but you can change as you wish.