Flutter how to create Multi Card and select a color - flutter

I am new in flutter, I want to create multi card with some option and select a option then change color. In my code when click one option number but all of color same change, please help to fix it.
link all code
[https://github.com/gunartha/Multi-Question-and-multi-selection-with-color-option]

This is happening because you are using same color for all the 15 questions.
To have each of the 15 card behave independently you need List of size 15. Check the changes made by me below. This should fix your problem.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Click Color Card',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final kSecondaryColor = Color(0xFF8B94BC);
final kPrimaryColor = Color(0xFF748BF5);
final kGreenColor = Color(0xFFAAF39C);
final kRedColor = Color(0xFFF7BCBD);
final kYellowColor = Color(0xFFF0EE8C);
final kGrayColor = Color(0xFFD8D5D5);
final kBlackColor = Color(0xFF101010);
List<Color> colorYes = List.filled(15, Color(0xFFD8D5D5));
List<Color> colorNo = List.filled(15, Color(0xFFD8D5D5));
List<Color> colorNA = List.filled(15, Color(0xFFD8D5D5));
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Click Multi color"),
),
body: ListView.builder(
itemCount: 15,
itemBuilder: (context, index) {
return new Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.95,
height: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
),
child: Card(
child: Column(
children: [
SizedBox(
height: 20,
),
Text("Question $index"),
SizedBox(
height: 10,
),
InkWell(
//yes
onTap: () {
setState(() {
colorYes[index] = kGreenColor;
colorNo[index] = kGrayColor;
colorNA[index] = kGrayColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorYes[index],
),
child: Container(
child: Center(
child: Text(
"Yes",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
setState(() {
colorYes[index] = kGrayColor;
colorNo[index] = kRedColor;
colorNA[index] = kGrayColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorNo[index],
),
child: Container(
child: Center(
child: Text(
"No",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
setState(() {
colorYes[index] = kGrayColor;
colorNo[index] = kGrayColor;
colorNA[index] = kYellowColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorNA[index],
),
child: Container(
child: Center(
child: Text(
"N/A",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
],
),
),
),
);
}));
}
}

You don't need to put extra effort, Simply create question answer bean and store data in that. when you change state then you find same data in bean and you can render card color on specific card.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Click Color Card',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final kSecondaryColor = Color(0xFF8B94BC);
final kPrimaryColor = Color(0xFF748BF5);
final kGreenColor = Color(0xFFAAF39C);
final kRedColor = Color(0xFFF7BCBD);
final kYellowColor = Color(0xFFF0EE8C);
final kGrayColor = Color(0xFFD8D5D5);
final kBlackColor = Color(0xFF101010);
Color colorYes = Color(0xFFD8D5D5);
Color colorNo = Color(0xFFD8D5D5);
Color colorNA = Color(0xFFD8D5D5);
List<QueAnsBean> data = [];
#override
void initState() {
super.initState();
generateBean();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Click Multi color"),
),
body: ListView.builder(
itemCount: 15,
itemBuilder: (context, index) {
QueAnsBean item = data[index];
return new Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.95,
height: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
),
child: Card(
child: Column(
children: [
SizedBox(
height: 20,
),
Text("${item._que}"),
SizedBox(
height: 10,
),
InkWell(
//yes
onTap: () {
item._answer = "1";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: item._answer == "1"
? kGreenColor
: kGrayColor,
),
child: Container(
child: Center(
child: Text(
"Yes",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
item._answer = "2";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color:
item._answer == "2" ? kRedColor : kGrayColor,
),
child: Container(
child: Center(
child: Text(
"No",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
item._answer = "3";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: item._answer == "3"
? kYellowColor
: kGrayColor,
),
child: Container(
child: Center(
child: Text(
"N/A",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
],
),
),
),
);
}));
}
void generateBean() {
for (int i = 0; i < 15; i++) {
data.add(QueAnsBean(que: "Question - $i", answer: ""));
}
}
}
class QueAnsBean {
String? _que;
String? _answer;
String? get que => _que;
String? get answer => _answer;
QueAnsBean({String? que, String? answer}) {
_que = que;
_answer = answer;
}
QueAnsBean.fromJson(dynamic json) {
_que = json["que"];
_answer = json["Answer"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["que"] = _que;
map["Answer"] = _answer;
return map;
}
}

Related

Flutter How to send and show captured image/ video to next page?

I've created a screen where I can use a button to open the camera and take video. And above that button, I made a container to display the video. But I want to show this container containing video to display on the next page. As I am new to flutter, I believe my code is messy. Can you help me with how to do this?
And how to show multiple videos on a screen after taking them through this camera in a loop like this image here?
Here is my code -
class video_record02 extends StatefulWidget {
final Function? onSelectVideo;
const video_record02({Key? key, this.onSelectVideo});
#override
_video_record02State createState() => _video_record02State();
}
class _video_record02State extends State<video_record02> {
String dropdownValue = 'Bedroom';
File? storedVideo;
Future<void> _takeVideo() async {
final picker = ImagePicker();
final videoFile = await picker.pickVideo(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.rear,
maxDuration: Duration(
seconds: 25,
),
);
if (videoFile == null) {
return;
}
final rlyvideoFile = File(videoFile.path);
setState(() {
storedVideo = rlyvideoFile;
});
final appDir = await syspaths.getApplicationDocumentsDirectory();
final fileName = path.basename(rlyvideoFile.path);
final savedVideo = await rlyvideoFile.copy('${appDir.path}/$fileName');
widget.onSelectVideo?.call(savedVideo);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(
shrinkWrap: true,
children: [
Column(
children: [
Container(
width: 150,
height: 100,
decoration: BoxDecoration(
border: Border.all(
width: 0.5,
color: Colors.grey,
),
),
child: storedVideo != null
? VideoWidget(storedVideo!)
: Text(
'No Video Taken',
textAlign: TextAlign.center,
),
alignment: Alignment.center),
Align(
alignment: Alignment.center,
child: Column(
children: [
IconButton(
icon: Icon(Icons.play_circle_fill),
color: Colors.red,
iconSize: 100.0,
onPressed: _takeVideo,
),
],
),
),
Text(
'Click to start',
style: TextStyle(
fontSize: 25.0,
color: Colors.red,
fontWeight: FontWeight.w300,
),
),
Container(
margin: EdgeInsets.fromLTRB(125, 0, 125, 0),
height: 50,
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: TextButton(
child: Text(
'< Back',
style: TextStyle(fontSize: 17, color: Colors.black),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => video_record01()),
);
},
),
),
],
),
],
),
),
),
);
}
}

Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?

I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
My Code :
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_clipboard_manager/flutter_clipboard_manager.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Shortener',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: StartPage(),
);
}
}
class StartPage extends StatefulWidget {
#override
_StartPageState createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
bool visibilityTag = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "tag") {
visibilityTag = visibility;
}
});
}
final GlobalKey<ScaffoldState> _globalKey = GlobalKey<ScaffoldState>();
String shortUrl = "";
String value = "";
String buttonText = "COPY!";
bool isChanged = true;
TextEditingController urlcontroller = TextEditingController();
getData() async {
var url = 'https://api.shrtco.de/v2/shorten?url=${urlcontroller.text}';
var response = await http.get(url);
var result = jsonDecode(response.body);
if (result['ok']) {
setState(() {
shortUrl = result['result']['short_link'];
});
} else {
print(response);
}
}
copy(String url) {
FlutterClipboardManager.copyToClipBoard(url).then((value) {});
}
buildRow(String data, bool original) {
return SingleChildScrollView(
child: original
? Container(
alignment: Alignment.center,
child: Text(
data,
))
: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
data,
),
ElevatedButton(
child: Text(buttonText),
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(300, 40),
),
onPressed: () {
copy(shortUrl);
setState(() {
if (isChanged == true) {
buttonText = "COPIED!";
}
});
},
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: ListView(
children: [
SvgPicture.asset(
'assets/logo.svg',
),
SvgPicture.asset(
'assets/illustration.svg',
),
Center(
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
SizedBox(
height: 130,
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.centerRight,
color: Color.fromRGBO(59, 48, 84, 1),
child: SvgPicture.asset(
'assets/shape.svg',
color: Color.fromRGBO(75, 63, 107, 1),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 40,
child: TextField(
onChanged: (text) {
value = "URL : " + text;
},
controller: urlcontroller,
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
SizedBox(
height: 10,
),
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: getData,
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow(value, true),
buildRow(shortUrl, false),
],
),
),
)
],
),
);
}
}
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
On State create a bool like
bool showCopyButton = false;
Change to true at
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: ()async {
print("Button Click");
await getData();
setState(() {
showCopyButton = true;
});
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
And wrap with Visibility Like
Visibility(
visible: showCopyButton,
child: Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
)
or you can just if like
if (showCopyButton)
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
Btw you need to use await before making it true.
Hope this helps:
import 'package:flutter/material.dart';
class Screen extends StatefulWidget {
#override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
bool _paddingVisible = false;
#override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 10), () {
// Check if mounted == true, because the screen might closed
// before 10 seconds pass
if (mounted) {
// Setting padding visibility to true after 10 seconds
setState(() {
_paddingVisible = true;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
// All your widgets
// When _paddingVisible becomes true it will be displayed
if (_paddingVisible) SizedBox(height: 10),
],
),
);
}
}

flutter app on restart not showing home page after hot reload it works

I'm beginner at flutter app development.i'm trying to fetch more then ten pages from api with for loop and addall results in list.for that i created future function and statefulwidget
here my code is
import 'dart:convert';
import 'package:MovieAPi/infopage.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
List data = [];
Future<void> _getMovies() async {
for (var i = 1; i < 10; i++) {
var url =
"https://api.themoviedb.org/3/trending/movie/week?api_key=1dce78a9836cf6fbc01190431d9443fe&page=$i";
http.Response response = await http.get(url);
var JsonBody = json.decode(response.body);
data.addAll(JsonBody['results']);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(
title: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
subtitle: TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MovieTile(),
);
}
}
class MovieTile extends StatefulWidget {
#override
_MovieTileState createState() => _MovieTileState();
}
class _MovieTileState extends State<MovieTile> {
void initState() {
super.initState();
setState(() {
_getMovies();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Movies", style: Theme.of(context).textTheme.title),
backgroundColor: Colors.white,
bottomOpacity: 0.0,
shadowColor: Colors.white,
automaticallyImplyLeading: false,
),
body: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
String image = data[index]['poster_path'];
String title = data[index]['title'];
String release_date = data[index]['overview'];
String id = data[index]['id'].toString();
String vote = data[index]['vote_average'].toString();
return GestureDetector(
onTap: () {
return Navigator.push(context,
MaterialPageRoute(builder: (context) => InfoMovie(id)));
},
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 8.0, horizontal: 10),
child: Container(
width: MediaQuery.of(context).size.width,
height: 500.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: CachedNetworkImageProvider(
"https://image.tmdb.org/t/p/original$image",
),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
offset: Offset(1, 9),
blurRadius: 10,
color: Colors.black26,
)
],
),
child: Stack(
children: [
Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(20),
),
),
Positioned(
bottom: 0,
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
padding: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width * 0.95,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context)
.textTheme
.title
.copyWith(color: Colors.white),
),
SizedBox(height: 5),
Text(
release_date,
style: Theme.of(context)
.textTheme
.subtitle
.copyWith(
color: Colors.white.withOpacity(0.9)),
textAlign: TextAlign.left,
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true,
),
],
),
),
),
Positioned(
top: 20,
left: 10,
child: Container(
height: 50,
width: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.white.withOpacity(0.6),
width: 1)),
child: Center(
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: Center(
child: Text(
vote,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
),
),
),
),
],
),
),
),
);
},
));
}
}
frist when i open app showing nothing
like this
only blank screen
and when i hot reload then showing results
here
First, setState is not necessary in initState. Secondly, since ListView.builder is the root element of your page body, you cannot directly see the data content because it's empty data = [] at app startup.
To solve this, better you try something like this
return Scaffold(
body: data.length > 0 ? ListView.builder(
// ...
) : Center(
child: CircularProgressIndicator(),
),
)
Also, it's better you put your List data variable and _getMovies function in _MovieTileState like this
class _MovieTileState extends State<MovieTile> {
List data;
void initState() {
super.initState();
data = [];
_getMovies();
}
Future<void> _getMovies() async {
for (var i = 1; i < 10; i++) {
var url = "https://api.themoviedb.org/3/trending/movie/week?api_key=1dce78a9836cf6fbc01190431d9443fe&page=$i";
http.Response response = await http.get(url);
var JsonBody = json.decode(response.body);
setState(() {
data.addAll(JsonBody['results']);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// ...
),
body: data.length > 0 ? ListView.builder(
// ...
) : Center(
child: CircularProgressIndicator(),
),
);
}
}

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.

CustomScrollView object does not update with input from StatefulBuilder

I have a CustomScrollView that gets updated upon user input. The actual items in the ListView are in a SliverChildBuilderDelegate inside the CustomScrollView which is inside the body of the Scaffold object (see the code below). If a user adds an item in the form that is inside the StatefulBuilder which is inside a showDialog object, the item does not get added to the planets list which thus does not update the ListView. I think the problem is caused by the StatefulBuilder which I need to update my DropdownButton.
My code:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() {
runApp(MaterialApp(
home: HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class Planet {
final String id;
final String name;
final String location;
final String distance;
final String gravity;
final String image;
const Planet({this.id, this.name, this.location, this.distance, this.gravity, this.image});
}
class Coin {
int id;
String name;
Coin(this.id, this.name);
static List<Coin> getCoins() {
return <Coin>[
Coin(1, 'coin1'),
Coin(2, 'coin2'),
Coin(3, 'coin3'),
Coin(4, 'coin4'),
Coin(5, 'coin5'),
];
}
}
class MenuItem {
String title;
String icon;
Color color;
Function func;
MenuItem(this.title, this.icon, this.color, this.func);
}
class _HomePageState extends State<HomePage> {
List<Coin> _coins = Coin.getCoins();
List<DropdownMenuItem<Coin>> _dropdownMenuItems;
Coin _selectedCoin;
#override
void initState() {
_dropdownMenuItems = buildDropdownMenuItems(_coins);
_selectedCoin = _dropdownMenuItems[0].value;
super.initState();
_menuItems = createMenuItems();
_selectedMenuItem = _menuItems.first;
}
MenuItem _selectedMenuItem;
List<MenuItem> _menuItems;
List<Widget> _menuOptionWidgets = [];
List<MenuItem> createMenuItems() {
final menuItems = [
new MenuItem("Dashboard", 'assets/images/dashboard.png', Colors.black, () => new Dashboard()),
new MenuItem("Cows", 'assets/images/cow.png', Colors.green, () => new Cows()),
];
return menuItems;
}
_onSelectItem(MenuItem menuItem) {
setState(() {
_selectedMenuItem = menuItem;
});
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
Navigator.of(context).pop(); // close side menu
}
List<DropdownMenuItem<Coin>> buildDropdownMenuItems(List coins) {
List<DropdownMenuItem<Coin>> items = List();
for (Coin coin in coins) {
items.add(
DropdownMenuItem(
value: coin,
child:
Text(
coin.name,
style: TextStyle(
fontSize: 18.0,
color: Colors.black87,
fontWeight: FontWeight.bold
),
),
),
);
}
return items;
}
onChangeDropdownItem(Coin selectedCoin, StateSetter setState) {
setState(() {
_selectedCoin = selectedCoin;
print('${_selectedCoin.name}');
});
}
final coinController = TextEditingController();
final amountController = TextEditingController();
final purposeController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
coinController.dispose();
amountController.dispose();
purposeController.dispose();
super.dispose();
}
List<Planet> planets = [];
#override
Widget build(BuildContext context) {
_menuOptionWidgets = [];
DateTime now = DateTime.now();
String formattedDate = DateFormat('yyyy-MM-dd kk:mm').format(now);
for (var menuItem in _menuItems) {
_menuOptionWidgets.add(new Container(
decoration: new BoxDecoration(
color: menuItem == _selectedMenuItem
? Colors.grey[200]
: Colors.white),
child: new ListTile(
leading: new Image.asset(menuItem.icon),
onTap: () => _onSelectItem(menuItem),
title: Text(
menuItem.title,
style: new TextStyle(
fontSize: 20.0,
color: menuItem.color,
fontWeight: menuItem == _selectedMenuItem
? FontWeight.bold
: FontWeight.w300),
))));
_menuOptionWidgets.add(
new SizedBox(
child: new Center(
child: new Container(
margin: new EdgeInsetsDirectional.only(start: 20.0, end: 20.0),
height: 0.3,
color: Colors.grey,
),
),
),
);
}
double screenHeight;
screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
backgroundColor: Color.fromRGBO(53, 73, 94, 0.9),
elevation: 0.0,
// leading: Container(),
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new Container(
child: new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.black,
radius: 40.0,
child: Text(
"L",style: TextStyle(
color: Colors.orange,
fontSize: 46.0),
),
),
title: Text("Welcome",style: TextStyle(fontSize: 46.0),)
),
margin: new EdgeInsetsDirectional.only(top: 20.0),
color: Colors.white,
constraints: BoxConstraints(maxHeight: 90.0, minHeight: 90.0)),
new SizedBox(
child: new Center(
child: new Container(
margin:
new EdgeInsetsDirectional.only(start: 10.0, end: 10.0),
height: 0.3,
color: Colors.black,
),
),
),
new Container(
color: Colors.white,
child: new Column(children: _menuOptionWidgets),
),
],
),
),
floatingActionButton: new Container(
width: 120.0,
height: 120.0,
padding: const EdgeInsets.only(bottom:40.0),
child: FloatingActionButton(
child: Icon(Icons.add,size: 50.0),
elevation: 0.0,
onPressed: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
margin: EdgeInsets.only(
top: screenHeight / 5,
bottom: screenHeight / 4
),
padding: EdgeInsets.only(left: 10, right: 10),
child: Card(
color: Color.fromRGBO(53, 73, 94, 0.9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 8,
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Text(
"Create",
style: Style.headerTextStyle
),
),
Divider(
color: Colors.white
),
SizedBox(
height: 15,
),
DropdownButton(
value: _selectedCoin,
items: _dropdownMenuItems,
onChanged: (selectedCoin) {
setState(() {
_selectedCoin = selectedCoin;
print('${_selectedCoin.name}');
});
}, //onChangeDropdownItem(_selectedCoin, setState),
),
SizedBox(
height: 15,
),
TextFormField(
decoration: InputDecoration(
labelText: "Amount",
hasFloatingPlaceholder: true,
labelStyle: Style.commonTextStyle
),
controller: amountController,
),
SizedBox(
height: 20,
),
TextFormField(
decoration: InputDecoration(
labelText: "What is it for?",
hasFloatingPlaceholder: true,
labelStyle: Style.commonTextStyle
),
controller: purposeController,
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment
.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(),
),
ButtonTheme(
minWidth: 150.0,
child: RaisedButton(
padding: EdgeInsets.all(8.0),
child: Text('Share',
style: TextStyle(
fontSize: 24,
color: Colors.black87,
fontWeight: FontWeight.bold
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
18.0)
),
color: Colors.white,
splashColor: Colors.blueGrey,
onPressed: () {
setState(() {
planets.add(Planet(
id: '1',
// TODO need to adjust this
name: purposeController.text,
location: '€' + amountController.text,
distance: formattedDate,
gravity: 'test',
image: _setImage(), // TODO might have to pass _selectedCoin as parameter
)
);
});
Navigator.pop(context);
},
),
),
],
),
],
),
),
),
);
}
);
},
);
},
),
),
body: Column(
children: <Widget>[
new Expanded(
child: new Container(
color: Color.fromRGBO(53, 73, 94, 0.9),
child: new CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 0.0),
sliver: new SliverFixedExtentList(
itemExtent: 152.0,
delegate: new SliverChildBuilderDelegate(
(context, index) => new PlanetRow(planets[index]),
childCount: planets.length,
),
),
),
],
),
),
),
],
),
);
}
}
The expected result is that the object from user input gets added to the planets list. The Sliver object then gets the updated planets list which shows the user input in a Planet Card. Any help will be greatly appreciated!