Flutter: Textfield controller on a nested listview.builder - flutter

hello can someone help me on nested listview.
as you can see from the image below, i made two listview.builders.
first listview.builder(context, i) is for the headers "ChildWO:" and a description below.
Than another listview.builder(context, index) for under it that contains data about it (shown in card widgets).
My problem is, whenever I input a value inside the textfield.
every textfield that have the same position will be filled up.
for example "55". every first card of it will be filled with "55".
Is there a way wherein I can set the controller of the textfield to have it like,
"controller: _qtyInputtedList[i][index]"?
for now, my controller is set at controller: _qtyInputtedList[index].
Thank you.
Expanded(
child: Container(
decoration: BoxDecoration(color: Colors.white),
child: ListView.separated(
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder: (context, index) => SizedBox(
height: 1,
),
itemCount: mainParent.CHILDREN?.length ?? 0,
itemBuilder: (context, i) {
// _qtyInputtedList.add(new TextEditingController());
return Padding(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
child: Column(
children: <Widget>[
Text(
'Child WO: ${mainParent.CHILDREN![i].WONUM}',
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'NunitoLight'),
),
Padding(
padding:
EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Text(
'${mainParent.CHILDREN![i].WODESC}',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'NunitoLight'),
),
),
ListView.builder(
itemCount: mainParent
.CHILDREN![i].MATERIALS!.length,
itemBuilder: (context, index) {
_qtyInputtedList.add(new TextEditingController());
final post = mainParent
.CHILDREN![i].MATERIALS![index];
//tileKey.add(GlobalKey(debugLabel: "index :$i"));
return Padding(
padding: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? const EdgeInsets.fromLTRB(
10, 4, 10, 4)
: const EdgeInsets.fromLTRB(
20, 4, 10, 4),
child: GestureDetector(
onLongPress: () {
//itemNum will be used for component list endpoint
itemNum =
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMNUM}';
mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? _displayDialogListMaterials(
context)
: null;
},
child: ExpansionTileCard(
//key: tileKey[i],
//key: tileKey[i],
//baseColor: Colors.grey[800],
baseColor: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? Color(0xff3A3845)
: Color(0xff826F66),
// baseColor: Colors.red[700],
expandedTextColor:
Colors.black,
expandedColor: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? Color(0xff3A3845)
: Colors.grey[600],
trailing: Transform.scale(
scale: 2.5,
child: Theme(
data: ThemeData(
unselectedWidgetColor:
Colors.grey[
700], // Your color
),
child: Container(
margin:
EdgeInsets.all(10),
width: 14,
height: 14,
color: Colors.white,
child: Checkbox(
hoverColor:
Colors.white,
activeColor: Colors
.green[700],
value:
selectedItems.contains(mainParent
.CHILDREN![i]
.MATERIALS![index]),
onChanged:
(bool? value) {
if(selectedItems.contains(mainParent
.CHILDREN![i]
.MATERIALS![index])) {
selectedItems.remove(mainParent
.CHILDREN![i]
.MATERIALS![index]);
selectedItems.remove(mainParent
.CHILDREN![i]
.MATERIALS![index].ITEMNUM);
selectedItems.remove(mainParent
.CHILDREN![i]
.WONUM);
selectedItems.remove(_qtyInputtedList[index].text);
} else {
selectedItems.add(mainParent
.CHILDREN![i]
.MATERIALS![index]);
selectedItems.add(mainParent
.CHILDREN![i]
.MATERIALS![index].ITEMNUM);
selectedItems.add(mainParent
.CHILDREN![i]
.WONUM);
selectedItems.add(_qtyInputtedList[index].text);
}
setState(() {
print(selectedItems.toString());
//if you want to reload loadparent2
// dataFuture = loadParent2();
});
}),
),
),
),
// leading: Icon(
// Icons.warning_amber,
// color: Colors.white,
// size: 60.0,
// ),
leading: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"0"
? Container(
width: 60.0,
child: TextField(
controller: _qtyInputtedList[index],
keyboardType:
TextInputType
.number,
style: TextStyle(
fontSize: 20),
decoration:
InputDecoration(
filled: true,
fillColor:
Colors.white,
border:
InputBorder
.none,
),
),
)
: null,
title: Text(
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMNUM}',
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(
fontSize: 25,
color: Colors.white,
fontWeight:
FontWeight
.bold),
),
subtitle: Text(
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMDESCRIPTION}',
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(
fontSize: 16,
color:
Colors.white),
),
children: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"0"
? <Widget>[
Divider(
thickness: 3.0,
height: 3.0,
),
Align(
alignment: Alignment
.centerLeft,
child: Padding(
padding:
const EdgeInsets
.symmetric(
horizontal:
16.0,
vertical: 5.0,
),
child: Text(
"Planned QTY: ${mainParent.CHILDREN![i].MATERIALS![index].QUANTITYPLAN}"
"\n"
"Warehouse Balance: 30",
style: Theme.of(
context)
.textTheme
.bodyText2!
.copyWith(
fontSize:
22),
),
),
),
ButtonBar(
alignment:
MainAxisAlignment
.start,
buttonHeight: 52.0,
buttonMinWidth:
90.0,
children: <
Widget>[],
),
]
: <Widget>[])),
);
},
shrinkWrap: true,
physics: ClampingScrollPhysics(),
)
],
),
);
}),
),
),

I recommend you to split your code to reuseable widgets, by this way you don't need to care about controller and how to declare it they are differences, code look short and clearly, below is example.
Example:
import 'package:flutter/material.dart';
class Student {
int id;
String name;
Student(this.id, this.name);
}
class Class {
String name;
List<Student> students;
Class(this.name, [this.students = const []]);
}
class RenderStudent extends StatefulWidget {
const RenderStudent({required this.student, Key? key}) : super(key: key);
final Student student;
#override
RenderStudentState createState() => RenderStudentState();
}
class RenderStudentState extends State<RenderStudent> {
Student get student => widget.student;
late TextEditingController controller;
#override
void initState() {
controller = TextEditingController(text: widget.student.name);
controller.addListener(() => setState(() {}));
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return TextField(
controller: controller,
decoration: InputDecoration(
labelText: "Student id: ${student.id}",
border: const OutlineInputBorder(),
),
);
}
}
class RenderClass extends StatelessWidget {
const RenderClass({required this.clas, Key? key}) : super(key: key);
final Class clas;
#override
Widget build(BuildContext context) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Class ${clas.name}", style: const TextStyle(fontSize: 40)),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: clas.students.length,
itemBuilder: (context, i) => Padding(
padding: const EdgeInsets.all(4),
child: RenderStudent(
student: clas.students[i],
),
),
),
],
),
);
}
}
void main() {
final items = [
Class('A1', [Student(1, "Carter")]),
Class('B1', [Student(2, "Join"), Student(2, "Smith"), Student(2, "Lara")]),
];
return runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, i) => RenderClass(clas: items[i]),
),
),
),
);
}

Related

Flutter : Get Value of Selected Container

I am trying to get the Text value of the selected container in a GridView. I am able to print the selected index. But I need to get the text value of the selected container so that I can save it in sharedPreferences and later get it and store it on the server.
Please assist. Your help will be gladly appreciated.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class QuickSurveyScreen extends StatefulWidget {
const QuickSurveyScreen({super.key});
#override
State<QuickSurveyScreen> createState() => _QuickSurveyScreenState();
}
class _QuickSurveyScreenState extends State<QuickSurveyScreen> {
int selectedIndex = -1;
List<String> gasUsage = [
"Heater",
"Stove",
"Geyser",
"Fireplace",
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(top: 120.0, right: 30, left: 30),
child: Column(
children: const [
Text(
"What do you use \nLP Gas for?",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 20,
),
child: Text(
"Please choose one or more options from below",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
),
],
),
))
];
},
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
crossAxisSpacing: 20.0,
mainAxisSpacing: 20.0,
),
physics: const NeverScrollableScrollPhysics(),
itemCount: gasUsage.length,
itemBuilder: (BuildContext context, int index) {
return gasUsageContainer("", gasUsage[index], index);
}),
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
minimumSize: const Size(double.infinity, 65.0),
backgroundColor: const Color(0xFFF0A202),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
),
textStyle: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
child: const Text('Continue'),
),
],
),
),
),
),
);
}
gasUsageContainer(String image, String name, int index) {
return GestureDetector(
onTap: () {
setState(() {
if (selectedIndex == index) {
selectedIndex = -1;
} else {
selectedIndex = index;
}
if (kDebugMode) {
print(selectedIndex);
}
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: selectedIndex == index
? Colors.amber.shade50
: Colors.grey.shade200,
border: Border.all(
color: selectedIndex == index
? Colors.amber
: Colors.blue.withOpacity(0),
width: 2.0,
),
borderRadius: BorderRadius.circular(22.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: selectedIndex == index
? Colors.amber.shade800
: Colors.black,
),
)
]),
),
);
}
}
You can get it from List with index. Checkout the change I did for onTap in gasUsageContainer
onTap: () {
setState(() {
String? selected;
if (selectedIndex == index) {
selectedIndex = -1;
selected = null;
} else {
selectedIndex = index;
selected = gasUsage[index];//Here you get the value
}
if (kDebugMode) {
print('selectedIndex:$selectedIndex, selected: $selected');
}
});
}
Edited
class _QuickSurveyScreenState extends State<QuickSurveyScreen> {
final selectedItems = <String>[];
...
gasUsageContainer(String image, String name, int index) {
String item = gasUsage[index];
return GestureDetector(
onTap: () {
setState(() {
if (selectedItems.contains(item)) {
selectedItems.remove(item);
} else {
selectedItems.add(item);
}
if (kDebugMode) {
print('selectedItems: $selectedItems');
}
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: selectedItems.contains(item)
? Colors.amber.shade50
: Colors.grey.shade200,
border: Border.all(
color: selectedItems.contains(item)
? Colors.amber
: Colors.blue.withOpacity(0),
width: 2.0,
),
borderRadius: BorderRadius.circular(22.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: selectedItems.contains(item)
? Colors.amber.shade800
: Colors.black,
),
)
]),
),
);
}
}

Search Bar Shows Result if Search Term is not Contained Inside Names

I'm working on a big company project and a screen needed search bar but it works ok when you type one Letter or two but then if you continue to type in search it shows the whole names in it how do i fix this i want the list to show nothing when search term is wrong
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:reports/core/locale/locale_helper.dart';
import 'package:reports/core/util/constants.dart';
import 'package:reports/core/util/my_icons.dart';
import 'package:reports/core/util/responsive.dart';
import 'package:reports/features/reports/presentation/widgets/report_app_bar.dart';
import '../../../../../core/util/my_colors.dart';
class Marketer extends Equatable {
Marketer({
required this.name,
required this.code,
});
late String name;
final int code;
#override
List<Object?> get props => [code];
}
class Marketerselect extends StatefulWidget {
Marketer? selectedValue;
Marketerselect({
Key? key,
this.selectedValue,
}) : super(key: key);
#override
State<Marketerselect> createState() => _MarketerselectState();
}
class _MarketerselectState extends State<Marketerselect> {
final TextEditingController _controller = TextEditingController();
List<Marketer> marketerInfo = [
Marketer(name: 'امیررضا مرادی', code: 1),
Marketer(name: 'محمد علی سالان', code: 2),
Marketer(name: 'مهدی قلیزاده ', code: 3),
Marketer(name: 'آرش نوری', code: 4),
Marketer(name: 'نعیم لطفعلی', code: 5),
];
List<Marketer> searchList = [];
#override
void initState() {
_controller.addListener(() {
setState(() {
if (_controller.text.isNotEmpty) {
searchList.clear();
for (var marketer in marketerInfo) {
if (marketer.name.contains(_controller.text)) {
searchList.add(marketer);
}
}
} else {
searchList.clear();
}
});
});
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return ResponsiveWidget(
context: context,
mobile: Directionality(
textDirection: getDirection(context),
child: Scaffold(
appBar: ReportAppBar(
title: 'بازایاب',
hasLeadingWidget: true,
controller: _controller,
isDialog: true,
),
body: Card(
elevation: 8.0,
shadowColor: Colors.grey,
margin: const EdgeInsetsDirectional.only(top: 16),
child: ListView.builder(
itemCount: searchList.isEmpty ? marketerInfo.length : searchList.length,
itemBuilder: (context, index) {
return RadioListTile<Marketer?>(
value: searchList.isNotEmpty ? searchList[index] : marketerInfo[index],
groupValue: widget.selectedValue,
tileColor: Colors.white,
onChanged: (value) {
setState(() {
widget.selectedValue = value!;
Navigator.of(context).pop(value);
});
},
title: Text(
searchList.contains(marketerInfo[index]) ? searchList[index].name : searchList[index].name,
style: const TextStyle(
fontSize: 15.0,
color: MyColor.mine,
fontFamily: Constants.fontFamily,
),
),
);
}),
),
)),
web: Directionality(
textDirection: getDirection(context),
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
title: const Text(
'بازاریاب',
style: TextStyle(
fontSize: 15.0,
color: MyColor.mine,
fontFamily: Constants.fontFamily,
),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(50),
child: TextField(
keyboardType: TextInputType.text,
controller: _controller,
decoration: InputDecoration(
suffixIcon: Padding(
padding: const EdgeInsetsDirectional.only(end: 16.0),
child: Image.asset(MyIcons.search, color: Colors.black, alignment: AlignmentDirectional.centerEnd)),
hintText: 'جستوجو در لیست بازاریاب ها',
hintStyle: const TextStyle(
fontFamily: Constants.fontFamily,
fontWeight: FontWeight.w400,
fontSize: 12.0,
),
filled: true,
fillColor: Colors.white,
),
style: const TextStyle(
fontSize: 18.0,
color: MyColor.mine,
fontFamily: Constants.fontFamily,
))),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: searchList.isEmpty ? marketerInfo.length : searchList.length,
itemBuilder: (context, index) {
return RadioListTile<Marketer?>(
value: searchList.isNotEmpty ? searchList[index] : marketerInfo[index],
groupValue: widget.selectedValue,
tileColor: Colors.white,
onChanged: (value) {
setState(() {
widget.selectedValue = value!;
});
},
title: Text(
searchList.isNotEmpty ? searchList[index].name : marketerInfo[index].name,
style: const TextStyle(
fontSize: 15.0,
color: MyColor.mine,
fontFamily: Constants.fontFamily,
),
),
);
}),
),
const Divider(
color: MyColor.mercury,
thickness: 1.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsetsDirectional.only(bottom: 8.0, end: 8.0),
child: MaterialButton(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
onPressed: () {
Navigator.of(context).pop(widget.selectedValue);
},
color: MyColor.main,
child: const Text(
'تأیید',
style: TextStyle(
fontSize: 14.0,
color: Colors.white,
fontFamily: Constants.fontFamily,
),
),
),
)
],
),
],
),
))).get();
}
}
This is the whole page with data and search bar in it
It would be appreciated if anyone could help me

how to store the name of the container in an array

hi i am new to flutter can anyone tell me how to save the preferences in an array
what are the methods used in storing the value
class PrefPage extends StatefulWidget {
#override
_PrefPageState createState() => _PrefPageState();
}
class _PrefPageState extends State<PrefPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: Container(
color: Theme.of(context).backgroundColor,
padding: EdgeInsets.fromLTRB(10, 10, 30, 10),
height: 80,
child: Spring.bubbleButton(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Home()));
},
child: Text(
"👉",
style: TextStyle(fontSize: 30),
textAlign: TextAlign.end,
),
),
),
backgroundColor: Theme.of(context).backgroundColor,
appBar: AppBar(
centerTitle: false,
leadingWidth: 0,
elevation: 0,
backgroundColor: Theme.of(context).backgroundColor,
title: Text(
"Swoken",
style: GoogleFonts.niconne(
textStyle: TextStyle(
fontSize: 30,
color: Theme.of(context).primaryColor,
),
),
),
),
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
" What are your",
style: TextStyle(fontSize: 40, fontWeight: FontWeight.w100),
),
Text(
" Interests ?",
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
SizedBox(
height: 20,
),
GridView.count(
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
childAspectRatio: 2.3,
crossAxisCount: 2,
padding: EdgeInsets.all(5),
shrinkWrap: true,
children: List.generate(
intr.length,
(index) {
return PrefCont(
child: AutoSizeText(
intr[index]["icon"] + " " + intr[index]["title"],
minFontSize: 16,
maxLines: 1,
style: TextStyle(fontSize: 40),
),
);
},
),
),
],
),
),
),
);
}
}
class PrefCont extends StatefulWidget {
PrefCont({this.child});
final child;
#override
_PrefContState createState() => _PrefContState();
}
class _PrefContState extends State<PrefCont> {
List<String> sel = [];
bool isSelected = false;
#override
Widget build(BuildContext context) {
var themeId = DynamicTheme.of(context)!.themeId;
var kContColor = Color(0Xfff6f6f6);
themeId == 0
? kContColor = Color(0Xfff6f6f6)
: kContColor = Color(0xff272727);
return InkWell(
onTap: () {
setState(() {
isSelected = !isSelected;
});
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: isSelected ? kContInactColor : kContColor,
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
child: widget.child,
),
);
}
}
...........................................................................................................................................................................................................................................................................
First you need to modelize your elements as objects then, you need to create a data set containing all of your tiles:
class PreferencesData {
final String name;
final String assetName;
PreferencesData({required this.name, required this.assetName});
}
list _dataSet = [
PreferencesData(name: "Football", assetName: "/assets/icons/football.png"),
PreferencesData(name: "Food", assetName: "/assets/icons/food.png"),
...
];
Now that you have all your objects in a dataset you can use it in your grid to display them correctly:
children: [for (PreferencesData pref in _dataSet)
PrefCont(...) // access your data with pref.name
]

How to fetch specific data from API into flutter app

I am a beginner in flutter.
I have created two ListView Builder where one ListView.builder is inside another builder as given below.
I have a list of categories which is inside one listview.builder and other are the list of products which also listview.builder Wrapped inside the above listview build>
So now i need to display the only items belonging to the 1st listview builder which means If I have a categories named soup (1st ListView.builder) Now i need to display only the products that belongs to soup categories from 2nd Listview.Builder but all the products are listed inside all the categories list. So, Please help me to find solution any help would be appriciated.Thank you in advance.
Below are the codes.
//lib/routes/menu_description.dart(File name)
import 'package:flutter/material.dart';
import '../api_service.dart';
import 'package:html/parser.dart';
import 'package:percent_indicator/percent_indicator.dart';
class MenuDescription extends StatefulWidget {
MenuDescription({Key key}) : super(key: key);
#override
_MenuDescriptionState createState() => _MenuDescriptionState();
}
int itemspressed;
class _MenuDescriptionState extends State<MenuDescription> {
#override
Widget build(BuildContext context) {
return Container(
// color: Colors.grey[200],
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.separated(
separatorBuilder: (context, index) => Divider(
height: 20.0,
color: Colors.black,
),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wpcategoriespost = snapshot.data[index];
return Container(
color: Colors.grey[200],
child: InkWell(
splashColor: Colors.grey[800],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 5, right: 5, bottom: 5, top: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
"${wpcategoriespost['name']}",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900],
),
),
),
Center(
child: Text(
parse(("${wpcategoriespost['description']}")
.toString())
.documentElement
.text,
style:
TextStyle(fontSize: 14, color: Colors.black),
),
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: Categories(),)
],
),
),
),
);
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
class Categories extends StatefulWidget {
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wppost = snapshot.data[index];
return Card(
margin: const EdgeInsets.only(
left: 15,
right: 15,
bottom: 15,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 3,
child: InkWell(
splashColor: Colors.grey[300],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 12, right: 5, bottom: 12, top: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${wppost['name']}",
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900]),
),
Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(color: Colors.grey[350]),
color: itemspressed == index
? Colors.grey[350]
: null,
),
child: IconButton(
iconSize: 22,
icon: Icon(
Icons.add,
color: Colors.blueAccent[400],
),
onPressed: () {
setState(() {});
print('Add to cart');
},
),
),
],
),
Text(
parse(("${wppost['description']}").toString())
.documentElement
.text,
style: TextStyle(fontSize: 14, color: Colors.black),
),
Text(
parse(("${wppost['price']} €").toString())
.documentElement
.text,
style: TextStyle(
fontSize: 15,
color: Colors.amber[700],
fontWeight: FontWeight.bold),
),
],
),
),
),
) ;
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
//lib/api_service.dart
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List> fetchWpPosts() async{
final response = await http.get('https://word.tkco.in/wp-json/wc/v3/products?consumer_key=ck_94114a31e4576e61a9292f961489e7701029753e&consumer_secret=cs_dd4dc6e7945d8dcd14d888bc1d0ea0806b116dfb');
var convertDatatoJson = jsonDecode(response.body);
if (response.statusCode == 200) {
}
return convertDatatoJson;
}

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.