How to add a plus Button in ListView Builder fetches the data from SQLite in Flutter - flutter

I have a ListView Builder where I have one Stateful Widget. I want to add a plus Button as Widget inside the ListView Item. What I am doing is that, I have added a number of records in SQLite when creating the database, and I have added a plus Icon and an empty as record/row to the database. So I am fetching the data from there. The Plus Button(Widget) is displaying as I expect but when update the data into the database the Button is not Showing at the Expected position, Because I want it to display at the end of all the items.
class CategoriesScreen extends StatefulWidget {
#override
_CategoriesScreenState createState() => _CategoriesScreenState();
}
class _CategoriesScreenState extends State<CategoriesScreen> {
List<Map<String,dynamic>> spendingCategoriesList=[] ;
DatabaseHelper helper=DatabaseHelper();
#override
Widget build(BuildContext context) {
getData();
return Scaffold(
backgroundColor: Color(0xFF343641),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height-100,
margin: EdgeInsets.only(top: 40.0),
child: Column(
children: <Widget>[
Container(
width:MediaQuery.of(context).size.width ,
height: 30.0,
margin: EdgeInsets.only(left: 20.0),
child: Row(
children: [
GestureDetector(
onTap:(){Navigator.pop(context);},
child: Icon(
Icons.close,
color: Color(0xFFE44663),
size: 24.0,
),
),
Padding(
padding: EdgeInsets.only(left:MediaQuery.of(context).size.width*0.3),
child: Text('Categories',style: TextStyle(color: Colors.white,fontWeight: FontWeight.normal,fontSize: 15.0,),),
),
],
),
),
Expanded(
child: GridView.builder(
itemCount: spendingCategoriesList.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), itemBuilder: (context,index){
AddTransactionsModel transactionModel= new AddTransactionsModel(spendingCategoriesList[index]['CategoryImage'],spendingCategoriesList[index]['categoryName']);
return AddTransactionItem(transactionModel);
}),
),
],
),
),
);
}
void getData() async{
spendingCategoriesList=await helper.getNoteMapList();
setState(() {
spendingCategoriesList=spendingCategoriesList;
});
}
Here is the AddTransactionGridItem;
class _AddTransactionItemState extends State<AddTransactionItem> {
var imageSelectIndex;
String categoryName;
String categoryImage;
#override
Widget build(BuildContext context) {
print(
'Hello dear ! icon Number ${widget.transactionModel.iconNumber} and here is Text ${widget.transactionModel.categoryNumber} ');
return Container(
child: Column(
children: <Widget>[
InkWell(
onTap: widget.transactionModel.categoryNumber == ''
? () {
showAddCategoryDialogue();
}
: () {
setState(() {
categoryName=widget.transactionModel.categoryNumber;
categoryImage=widget.transactionModel.iconNumber;
print('categoryName $categoryName And categoryImage $categoryImage');
String cate='$categoryName&$categoryImage';
Navigator.pop(context,cate);
});
},
child: Container(
width: 72.0,
height: 72.0,
decoration: BoxDecoration(
color: Color(0xffC4C4C4).withOpacity(0.2),
borderRadius: BorderRadius.all(Radius.circular(12.0)),
border: widget.transactionModel.categoryNumber == ''
? Border.all(width: 0.3, color: Colors.white)
: Border.all(width: 0.0),
),
child: Center(
child: Image.asset('${widget.transactionModel.iconNumber}')),
),
),
SizedBox(
height: 10.0,
),
Text(
widget.transactionModel.categoryNumber,
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.w600,
fontFamily: 'Rajdhani',
fontStyle: FontStyle.normal),
)
],
),
);
}
AboveContainer is the ListView.Builder() Item .

Related

ListView.builder returns Null check operator used on a null value

I'm developing a job search app that scrapes data from Indeed using Python which is being sent back to my Flutter UI as JSON data. The JSON data is being received successfully, however, Im getting an error of Null check operator used on a null value. The error appears to be stemming from the _jobSearch widget.
The relevant error-causing widget was ListView lib/ui/home_page.dart:256
Exception caught by scheduler library
Null check operator used on a null value
Here is the code:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter_job_portal/theme/colors.dart';
import 'package:flutter_job_portal/theme/images.dart';
import 'package:flutter_job_portal/ui/bottom_menu_bar.dart';
import 'package:flutter_job_portal/ui/job_detail_page.dart';
String job = ""; //user's response will be assigned to this variable
String final_response = "";
final _formkey = GlobalKey<FormState>(); //key created to interact with the form
//function to validate and save user form
Future<void> _savingData() async {
final validation = _formkey.currentState.validate();
if (!validation) {
return;
}
_formkey.currentState.save();
}
Future<List<Job>> _getJobs() async {
final url = 'http://127.0.0.1:5000/job';
final response1 = await http.post(Uri.parse(url), body: json.encode({'job': job}));
final response2 = await http.get(Uri.parse(url));
final decoded = json.decode(response2.body);
List<Job> jobs = [];
for (var i in decoded) {
Job job = Job(i['Title'], i['Company'], i['Location'], i['Salary']);
jobs.add(job);
}
return jobs;
}
class Job {
final String title;
final String company;
final String location;
final String salary;
Job(this.title, this.company, this.location, this.salary);
}
class HomePage extends StatelessWidget {
const HomePage({Key key}) : super(key: key);
Widget _appBar(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
children: [
CircleAvatar(
backgroundImage: AssetImage(Images.user1),
),
Spacer(),
IconButton(
icon: Icon(Icons.notifications_none_rounded),
onPressed: () {},
)
],
),
);
}
Widget _header(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 12),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Hello, Alex!",
style: TextStyle(
fontSize: 15,
color: KColors.subtitle,
fontWeight: FontWeight.w500,
)),
SizedBox(
height: 6,
),
Text("Swipe to find your future",
style: TextStyle(
fontSize: 20,
color: KColors.title,
fontWeight: FontWeight.bold)),
SizedBox(
height: 10,
),
Row(
children: [
Expanded(
child: Container(
height: 45,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: KColors.lightGrey,
borderRadius: BorderRadius.circular(10)),
child: Form(
key: _formkey,
child: TextFormField(
decoration: InputDecoration(
hintText: 'Search job title or keywords',
),
onSaved: (value) {
job =
value; //getting data from the user form and assigning it to job
},
),
),
),
),
SizedBox(
width: 16,
),
Container(
decoration: BoxDecoration(
color: KColors.primary,
borderRadius: BorderRadius.circular(10),
),
height: 40,
child: IconButton(
color: KColors.primary,
icon: Icon(Icons.search, color: Colors.white),
onPressed: () async {
_savingData();
_getJobs();
},
),
)
],
)
],
),
);
}
Widget _recommendedSection(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
margin: EdgeInsets.symmetric(vertical: 12),
height: 200,
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Recommended",
style: TextStyle(fontWeight: FontWeight.bold, color: KColors.title),
),
SizedBox(height: 10),
Expanded(
child: ListView(
scrollDirection: Axis.horizontal,
children: [
_recommendedJob(context,
company: "Google",
img: Images.google,
title: "UX Designer",
sub: "\$45,000 Remote",
isActive: true),
_recommendedJob(context,
company: "DropBox",
img: Images.dropbox,
title: "Research Assist",
sub: "\$45,000 Remote",
isActive: false)
],
),
),
],
),
);
}
Widget _recommendedJob(
BuildContext context, {
String img,
String company,
String title,
String sub,
bool isActive = false,
}) {
return Padding(
padding: const EdgeInsets.only(right: 10),
child: GestureDetector(
onTap: () {
Navigator.push(context, JobDetailPage.getJobDetail());
},
child: AspectRatio(
aspectRatio: 1.3,
child: Container(
decoration: BoxDecoration(
color: isActive ? KColors.primary : Colors.white,
borderRadius: BorderRadius.circular(7),
),
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 40,
width: 40,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: isActive ? Colors.white : KColors.lightGrey,
borderRadius: BorderRadius.circular(7),
),
child: Image.asset(img),
),
SizedBox(height: 16),
Text(
company,
style: TextStyle(
fontSize: 12,
color: isActive ? Colors.white38 : KColors.subtitle,
),
),
SizedBox(height: 6),
Text(
title,
style: TextStyle(
fontSize: 14,
color: isActive ? Colors.white : KColors.title,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 6),
Text(
sub,
style: TextStyle(
fontSize: 12,
color: isActive ? Colors.white38 : KColors.subtitle,
),
),
],
),
),
),
),
);
}
Widget _jobSearch(BuildContext context) {
return new Container(
child: FutureBuilder(
future: _getJobs(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
));
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].location),
);
},
);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: KColors.background,
bottomNavigationBar: BottomMenuBar(),
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_appBar(context),
_header(context),
_recommendedSection(context),
_jobSearch(context)
],
),
),
),
),
);
}
}

How can I search the button I made in ListView with Search Bar?

I created a button shape called 'VocabularyWordsButton' and when I try it under a ListView it works just fine. But when I make 100 buttons under ListView, I want to find them via Search Bar. But I don't know how to do it somehow.
What I want to do: I want to distinguish the buttons by filtering the word 'englishWord' among the buttons listed below. When I enter the word in 'englishWord' in Search Bar, I want the buttons containing that word to be filtered.
If I do something like below, only the texts inside are listed, not the button I made.
VocabularyWordsButton.dart
import 'package:being_moroccan/AdHelper.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:sizer/sizer.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:easy_localization/easy_localization.dart';
class VocabularyWordsButton extends StatefulWidget {
VocabularyWordsButton(
{required this.englishWord,
required this.trasncribedWord,
required this.arabicWord,
required this.sound});
final String englishWord;
final String trasncribedWord;
final String arabicWord;
final String sound;
#override
_VocabularyWordsButtonState createState() => _VocabularyWordsButtonState();
}
class _VocabularyWordsButtonState extends State<VocabularyWordsButton> {
AdHelper adHelper = AdHelper();
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
adHelper.myLargeBanner.load();
}
bool _canShowButton = true;
void hideWidget() {
setState(() {
_canShowButton = !_canShowButton;
});
}
final AudioCache _audioCache = AudioCache(
prefix: 'audio/',
fixedPlayer: AudioPlayer()..setReleaseMode(ReleaseMode.STOP),
);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: !_canShowButton
? Column(
children: [
Container(
height: 195.h / 6,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Container(
height: 100,
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20))),
child: Center(
child: TextButton(
onPressed: () {
hideWidget();
},
child: Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
widget.englishWord,
style: TextStyle(
fontSize: 30.sp / 2,
color: Colors.white),
),
),
),
),
),
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.transparent),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
),
),
onPressed: () {
print('cal');
_audioCache.play('${widget.sound}.mp3');
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'TRANSCRIBED'.tr(),
style: TextStyle(
fontSize: 25.sp / 2,
),
),
Container(
width:
MediaQuery.of(context).size.width /
2,
height: 60.h / 7,
child: Center(
child: Text(
widget.trasncribedWord,
style: TextStyle(
fontSize: 25.sp / 2,
),
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'ARABIC'.tr(),
style: TextStyle(
fontSize: 25.sp / 2,
),
),
Container(
width:
MediaQuery.of(context).size.width /
2,
height: 60.h / 7,
child: Center(
child: Text(
widget.arabicWord,
style: TextStyle(
fontSize: 25.sp / 2,
),
),
),
),
],
),
),
],
),
),
),
],
),
),
),
Container(
height: 100,
child: AdWidget(ad: adHelper.myLargeBanner),
),
],
)
: Container(
width: MediaQuery.of(context).size.width / 2,
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.1),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: Center(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.transparent),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
),
onPressed: () {
hideWidget();
},
child: Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
widget.englishWord,
style:
TextStyle(fontSize: 30.sp / 2, color: Colors.white),
),
),
),
),
),
),
);
}
}
DictionaryScreen.dart
import 'package:sizer/sizer.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'VocabularyWords/VocabularyWordsButton.dart';
class DictionaryScreen extends StatefulWidget {
static const String id = 'Dictionary_Screen';
const DictionaryScreen({Key? key}) : super(key: key);
#override
_DictionaryScreenState createState() => _DictionaryScreenState();
}
class _DictionaryScreenState extends State<DictionaryScreen> {
TextEditingController editingController = TextEditingController();
// final duplicateItems = List<String>.generate(10000, (i) => "Item $i");
// var items = List<String>();
List<VocabularyWordsButton> words = [
VocabularyWordsButton(
englishWord: 'To pray'.tr(),
trasncribedWord: 'Sella',
arabicWord: 'صْلّى',
sound: 'Sella',
),
VocabularyWordsButton(
englishWord: 'To prefer'.tr(),
trasncribedWord: 'Feddel',
arabicWord: 'فْضّلْ',
sound: 'Feddel',
)
];
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
setState(() {});
},
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: words.length,
itemBuilder: (context, index) {
if (editingController.text.isEmpty) {
return ListTile(
title: Text('${words[index].englishWord} '),
);
} else if (words[index]
.englishWord
.toLowerCase()
.contains(editingController.text)) {
return ListTile(
title: Text('${words[index].englishWord} '),
);
} else {
return Container();
}
}),
),
],
),
),
);
}
}

Change state from another widget in flutter?

I am trying to make a cart icon with a text of the number of items in the cart. This requires a state refresh when state refreshes in another widget. Even though not recommended, I tried setState(), but as warned the widget was not mounted so setState() was called on null.
Then I came to know about Value listenable from this post How to set state from another widget?
I tried this, but it says "NoSuchMethodError: the getter 'value' was called on null, maybe my implementation was wrong.
heres my code:
var menuJson = [];
var isLoading = true;
class CartIcon extends StatefulWidget {
const CartIcon({Key key2}) : super(key: key2);
#override
_CartIcon createState() => _CartIcon();
}
class _CartIcon extends State<CartIcon> {
#override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["quantity"] > 0) {
filteredList.add(item);
}
}
return Padding(
padding: const EdgeInsets.only(top: 35, right: 8),
child: Container(
width: AppBar().preferredSize.height - 12,
height: AppBar().preferredSize.height - 12,
color: Colors.pink,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(AppBar().preferredSize.height),
child: Stack(
children: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_cart,
color: Colors.white,
),
onPressed: null,
),
filteredList.length == 0
? Container()
: Positioned(
child: Stack(
children: <Widget>[
Icon(Icons.brightness_1,
size: 20.0, color: Colors.green[800]),
Positioned(
top: 3.0,
right: 4.0,
child: Text(
filteredList.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 11.0,
fontWeight: FontWeight.w500),
))
],
)),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CartPage()),
);
},
),
),
),
);
}
}
class Salads extends StatefulWidget {
const Salads({Key key2}) : super(key: key2);
#override
_Salads createState() => _Salads();
}
class _Salads extends State<Salads> {
final _counter = new ValueNotifier(0);
plus(index) {
var quant = menuJson[index]["quantity"];
quant++;
menuJson[index]["quantity"] = quant;
setState(() {});
}
minus(index) {
var quant = menuJson[index]["quantity"];
quant--;
if (quant < 0) {
quant = 0;
}
menuJson[index]["quantity"] = quant;
setState(() {});
}
#override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["category_name"] == "Salads") {
filteredList.add(item);
}
}
if (isLoading) {
return Center(
child: new CircularProgressIndicator(),
);
} else {
return Container(
color: Colors.green,
child: ListView.builder(
itemCount: filteredList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.only(
left: 5, top: 5, bottom: 30),
child: Text(
filteredList[index]["dish_name"],
style: TextStyle(fontSize: 20),
textAlign: TextAlign.left,
),
),
Container(
padding: EdgeInsets.only(
right: 5, top: 5, bottom: 30),
child: Text(
'\u{20B9} ' +
filteredList[index]["price"]
.toString(),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 20),
textAlign: TextAlign.right,
)),
]),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RawMaterialButton(
onPressed: () =>
plus(filteredList[index]["index"]),
child: new Icon(
Icons.add,
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
),
Text(filteredList[index]["quantity"].toString(),
style: new TextStyle(fontSize: 40.0)),
RawMaterialButton(
onPressed: () =>
minus(filteredList[index]["index"]),
child: new Icon(
const IconData(0xe15b,
fontFamily: 'MaterialIcons'),
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
padding: EdgeInsets.all(0),
)
])
],
)));
}),
);
}
}
}
Since cart icon is in the app bar, it is higher in the widget tree.
How can I make such that when + is pressed in 'Salads' the CartIcon state updates in the appbar? Right now it updates the state when i tap on the cart button.
Maybe use a Global Key?
GlobalKey<_CartIcon> cartKey = GlobalKey<_CartIcon>();
When making your CartIcon insert the globalKey.
Make a new Method inside _CartIcon:
refresh(){
setState((){})
}
and when you want to refresh your CartIcon call:
cartKey.currentState.refresh();

How to add item in a listview from one class to another in Flutter?

I am working on a project in which i have a class which has a row that has two children. Child one contains a TabView with a child class TabViewChild in which i am generating a gridview. On the other hand child two contains a listView. So the problem is, when i click on the gridview item i am passing that item's value to a static list and passing that list to a listview of other class. But i have no idea how to change the state of that class on item clicked or how can i achieve this task in a better way as i am new to Flutter. I want that when a person click on any gridview's item that item appears in the listview simultaneously.
class ItemMenus {
int id;
String code;
String name;
String salePrice;
String photo;
String categoryName;
String percentage;
int quantity;
ItemMenus({this.id, this.code, this.name, this.salePrice, this.photo,
this.categoryName, this.percentage, this.quantity});
ItemMenus.fromJson(Map<String, dynamic> json)
:
id = int.parse(json['id']),
code = json['code'],
name = json['name'],
salePrice = json['sale_price'],
photo = json['photo'],
categoryName = json['category_name'],
percentage = json['percentage'];
#override
String toString() {
return 'ItemMenus{id: $id, code: $code, name: $name, salePrice: $salePrice, photo: $photo, categoryName: $categoryName, percentage: $percentage}';
}
}
import 'package:food_app/model/mdl_item_menus.dart';
class ItemMenuList{
List<ItemMenus> _itmMenuLst = [];
ItemMenuList._();
static final ItemMenuList instanceItmMenuLst = ItemMenuList._();
static ItemMenuList get instance => instanceItmMenuLst;
void addItem(ItemMenus im){
_itmMenuLst.add(im);
}
List<ItemMenus> get list => _itmMenuLst;
#override
String toString() {
return 'ItemMenuList{_itmMenuLst: $_itmMenuLst}';
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_categories.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_categories.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/tab_bar_view.dart';
class EPos extends StatefulWidget{
#override
_EPosState createState() => _EPosState();
}
class _EPosState extends State<EPos> {
final categoryDBHelper = TblCategories.categoriesInstance;
final ItemMenuList instance2 = ItemMenuList.instance;
String _orderType = 'Dine-In', _info = 'Table No. 1', _userName = 'ZiaUddin';
List<Categories> catLst = [];
List<ItemMenus> itmLst = [];
Future getCategories() async {
catLst.clear();
var categories = await categoryDBHelper.getCategories();
categories.forEach((element) {
catLst.add(Categories(
id: element['id'],
categoryName: element['category_name'],
description: element['description'],
userId: element['user_id'],
companyId: element['company_id'],
delStatus: element['del_status']));
});
catLst.forEach((element) {
print(element);
});
return catLst;
}
#override
void initState() {
// TODO: implement initState
super.initState();
// itmLst = instance2.list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
//#region AppBar
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.15,
color: Colors.redAccent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
child: Row(
children: [
Icon(
Icons.arrow_back,
color: Colors.white,
size: 25,
),
Padding(
padding: const EdgeInsets.fromLTRB(4, 8, 10, 8),
child: Text(
_orderType,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 8),
child: Text(
_info,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.amberAccent,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
),
Container(
margin: EdgeInsets.only(top: 15, right: 5),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30),
color: Colors.red,
),
child: Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 8, 8, 8),
child: Text(
_userName,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
CircleAvatar(
backgroundColor: Colors.red,
radius: MediaQuery.of(context).size.height * 0.041,
child: CircleAvatar(
radius: MediaQuery.of(context).size.height * 0.04,
backgroundImage: AssetImage('assets/user.png'),
),
),
],
),
),
],
),
),
//endregion
Expanded(
child: Row(
children: [
//# region Menu
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.yellowAccent,
shape: BoxShape.rectangle,
),
child: Column(
children: [
Expanded(
child: Container(
color: Colors.white,
child: FutureBuilder(
future: getCategories(),
builder: (context, snapShot) {
if (snapShot.connectionState ==
ConnectionState.none &&
snapShot.hasData == null) {
return Center(
child: CircularProgressIndicator());
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: catLst.length,
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize:
Size.fromHeight(kToolbarHeight),
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.1,
child: TabBar(
indicatorColor:
Colors.amberAccent,
isScrollable: true,
tabs: catLst
.map<Widget>((Categories c) {
return Tab(
icon: Icon(
Icons.style,
color: Colors.amberAccent,
size: 15,
),
child: Text(
c.categoryName
.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontWeight:
FontWeight.w400,
),
),
);
}).toList(),
),
),
),
body: TabBarView(
children: catLst.map((Categories c) {
return TabBarViewChild(categoryName:c.categoryName,
callback: (){
setState(() {
instance2.addItem(ItemMenus(name: c.categoryName));
itmLst = instance2.list;
print('I am Callback');
});
},);
}).toList(),
),
),
),
);
}),
),
),
],
),
),
),
//endregion
//# region OrderList
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ListView.builder(
itemCount: itmLst.length,
itemBuilder: (context, index){
return ListTile(
title: Text(itmLst[index].name),
);
},
),
),
),
//endregion
],
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_item_menus.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/new_sale.dart';
class TabBarViewChild extends StatefulWidget {
String categoryName;
VoidCallback callback;
TabBarViewChild({Key key,#required this.categoryName, this.callback}) : super(key:key);
#override
_TabBarViewChildState createState() => _TabBarViewChildState();
}
class _TabBarViewChildState extends State<TabBarViewChild> {
final ItemMenuList instance1 = ItemMenuList.instance;
List<ItemMenus> itmLst = [];
final itemMenus = TblItemMenus.itemMenusInstance;
Future getSpecificItemMenus() async{
var items = await itemMenus.getSpecificItemMenus(widget.categoryName);
itmLst.clear();
items.forEach((e) {
itmLst.add(ItemMenus(id: e['id'], categoryName: e['category_name'], code: e['code'],
name: e['name'], percentage: e['percentage'], photo: e['photo'], quantity: e['quantity'],
salePrice: e['sale_price']));
});
for (var value in itmLst) {
print(value);
}
return itmLst;
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: FutureBuilder(
future: getSpecificItemMenus(),
builder: (context, snapShot) {
if (snapShot.connectionState == ConnectionState.none
&& snapShot.hasData == null) {
return Center(child: CircularProgressIndicator());
}
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
scrollDirection: Axis.vertical,
itemCount: itmLst.length,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(5.0),
child: InkWell(
child: Card(
elevation: 4,
color: Colors.amberAccent,
child: Center(
child: Text(
itmLst[index].name.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.red,
fontSize: 13,
fontWeight: FontWeight.w700,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
),
onTap: (){
// Provider.of<ProItemMenus>(context, listen: false).addNewItemInList(ItemMenus(name: itmLst[index].name.toUpperCase()));
instance1.addItem(ItemMenus(categoryName: itmLst[index].name.toUpperCase()));
print(itmLst[index].name.toUpperCase());
},
),
);
}
);
}
),
);
}
}
So the problem now, there are two stateful widgets.
And as we are going to share the data or the state between them, basically we need to have more one stateful Widget which will the parent of them.
This term of is this problem known as State Management.
Currently there are many reknown State Management , such as Provider and Bloc. Reference.
But personally, I recommend to use Provider, which has simple Syntaxes and Concept.

How to navigate to another page but show information according to the items on my list that was pressed?

I'm trying to create my first app with flutter, it's a basic app to show items on a list and you tap on them to get the information. I've created the list and the contact page, I can navigate from one page to the other but I'm stuck now on how to make flutter show the information according to the contact I choose on the list, so I dont need to write one class for each contact. Is there a way to do it?
import 'package:flutter/material.dart';
import 'package:whatsapp_casimiro/contacts/contact_page.dart';
import 'package:whatsapp_casimiro/listas/lanchonetes.dart';
class LanchonetesScreen extends StatelessWidget {
final List<Lanchonetes> _allLanchonetes =
Lanchonetes.allLanchonetes();
#override
Widget build(BuildContext context) {
return Scaffold(body: getLanchonetesPageBody(context));
}
getLanchonetesPageBody(BuildContext context) {
return ListView.builder(
itemCount: _allLanchonetes.length,
itemBuilder: _getItemUI,
);
}
Widget _getItemUI(BuildContext context, index) {
return Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 20.0),
child: Divider(
color: Colors.black,
indent: 80.0,
height: 8.0,
),
),
ListTile(
contentPadding: EdgeInsets.fromLTRB(15.0, 10.0, 10.0, 10.0),
leading: Container(
width: 55.0,
height: 60.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(
"images/" + _allLanchonetes[index].img)),
),
),
title: Text(
_allLanchonetes[index].name,
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
onTap: () {
_onLanchonetesButtonPressed(context);
},
)
]);
}
}
void _onLanchonetesButtonPressed(BuildContext context) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ContactPage()));
}
class Lanchonetes {
final String name;
final String img;
Lanchonetes({this.name, this.img});
static List<Lanchonetes> allLanchonetes() {
var listOfLanchonetes = List<Lanchonetes>();
listOfLanchonetes.add(
Lanchonetes(name: "Esquina do Açaí",
img: "esquina_do_acai.jpg"));
listOfLanchonetes.add(
Lanchonetes(name: "Lanchonete Água na boca",
img: "esquina_do_acai.jpg"));
listOfLanchonetes.add(
Lanchonetes(name: "Kídelicia", img: "esquina_do_acai.jpg"));
listOfLanchonetes.add(
Lanchonetes(name: "Godinho Lanches", img: "godinho.jpeg" ));
return listOfLanchonetes;
}
}
import 'package:flutter/material.dart';
class ContactPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.blueGrey[100],
body: ListView(children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: Stack(children: <Widget>[
Image.asset("images/esquina_do_acai.jpg"),
Container(
height: 420.0,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: FractionalOffset.center,
end: FractionalOffset.bottomCenter,
colors: [
Colors.grey.withOpacity(0.0),
Colors.black,
])
),
),
Positioned(
bottom: 10.0,
left: 15.0,
child: Text(
"Esquina do Açaí",
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.normal,
color: Colors.white),
),
)
]
),
)
],
),
Padding(
padding: EdgeInsets.only(top: 5.0),
child: GestureDetector(
child: Card(
elevation: 1.0,
child: Container(
height: 100.0,
color: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 30.0, horizontal: 15.0),
child: Text(
"Cardápio",
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold),
),
),
),
),
onTap: () {},
),
),
Card(
elevation: 1.0,
child: Container(
height: 100.0,
color: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 30.0, horizontal: 15.0),
child: Text(
"Pedir",
style: TextStyle(
fontSize: 30.0, fontWeight:
FontWeight.bold),
),
)))
])));
}
}
In your Navigation function you can pass one object
on your onTap you should pass your object like this in navigation function
onTap: () {
_onLanchonetesButtonPressed(context, _allLanchonetes[index]);
}
and receive it at function and pass it to new page
void _onLanchonetesButtonPressed(BuildContext context,Lanchonetes lanchonetes) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ContactPage(lanchonetes)));
}
on new page create constructor
class ContactPage extends StatelessWidget {
Lanchonetes lanchonetes;
ContactPage({this.lanchonetes});
//
Your code
//
}
with this you can use your lanchonetes object in new page