Why the app is not rebuilding when I call setState? - flutter

I am developing an app with Flutter and I struggle with a problem: when I call the setState() method, the list I want to update does not update at all. I mean, it does not redrawing the widgets.
First of all, I have my list of custom widget, which is initialized with one element:
List<AdvFctPompa> _advFctPompaList = [AdvFctPompa(name: 'Bloc initial', temp: '4748425', imgPath: img2)];
My custom widget looks like this:
import 'package:flutter/material.dart';
class AdvFctPompa extends StatefulWidget {
final String imgPath;
final String name;
final String temp;
BoxConstraints constraint;
AdvFctPompa({
Key key,
this.imgPath,
#required this.name,
#required this.temp,
this.constraint,
}) : super(key: key);
#override
_AdvFctPompaState createState() => _AdvFctPompaState();
}
class _AdvFctPompaState extends State<AdvFctPompa> {
#override
Widget build(BuildContext context) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: <Widget>[
Container(
height: widget.constraint.maxHeight * .6,
width: widget.constraint.maxWidth * .7,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
image: DecorationImage(
image: NetworkImage(widget.imgPath),
fit: BoxFit.cover,
),
),
),
SizedBox(height: 5),
Expanded(
child: Container(
height: widget.constraint.maxHeight,
width: widget.constraint.maxWidth * .7,
padding: const EdgeInsets.only(left: 5, right: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
widget.name,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
Text(
widget.temp + "ºC",
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 15,
color: Colors.grey,
),
),
],
),
),
SizedBox(height: 5),
Container(
height: 30,
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: ExactAssetImage('assets/images/img6.png'),
fit: BoxFit.cover,
),
),
)
],
),
),
)
],
),
);
}
}
Second, I have a button for adding a new element in list:
GestureDetector(
child: Visibility(
visible: _heightAnimation.value > 90,
child: Icon(
Icons.add_to_queue,
color: Colors.white,
size: _iconSizeAnimation.value,
),
),
onTap: _addAdvFct,
)
And here is my method:
void _addAdvFct() {
print(_advFctPompaList.length);
_advFctPompaList.add(
AdvFctPompa(
name: 'Bloc initial',
temp: '4748425',
imgPath: img2,
constraint: constraints,
),
);
setState(() {});
}
I also tried:
void _addAdvFct() {
print(_advFctPompaList.length);
setState(() {
_advFctPompaList.add(
AdvFctPompa(
name: 'Bloc initial',
temp: '4748425',
imgPath: img2,
constraint: constraints,
),
);
});
}
And the way I want to draw my list is through a LayoutBuider:
Expanded(
child: LayoutBuilder(builder: (_, constraint) {
_initConstrains(constraint);
return ListView(
padding: const EdgeInsets.only(right: 20),
scrollDirection: Axis.horizontal,
children: _advFctPompaList,
);
}),
),
The thing is that when I press the button it show me in console that the number of list elements is increasing, but nothing is changing on the screen.
Am I missing something?

Try
void _addAdvFct() {
print(_advFctPompaList.length);
_advFctPompaList.add(
AdvFctPompa(
name: 'Bloc initial',
temp: '4748425',
imgPath: img2,
constraint: constraints,
),
);
setState(() {
_advFctPompaList;
});
}

Related

The argument type 'StateProvider<MainPageDataController?>' can't be assigned to the parameter type 'ProviderBase<Object?, MainPageDataController?>'

I am trying to get the data from API to fetch details of movies.
I am getting two errors on line 31 and 32.
This on line 31 -
The argument type 'StateProvider<MainPageDataController?>' can't be assigned to the parameter type 'ProviderBase<Object?, MainPageDataController?>'
This on line 32, on the "state" word -
The getter 'state' isn't defined for the type 'StateProvider<MainPageDataController?>'.
Try importing the library that defines 'state', correcting the name to the name of an existing getter, or defining a getter or field named 'state'
Here is the code -
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:movie_app/controllers/main_page_data_controller.dart';
import 'package:movie_app/model/main_page_data.dart';
import 'package:movie_app/model/movie.dart';
import 'package:movie_app/model/search_category.dart';
import 'package:movie_app/widgets/movie_tile.dart';
final mainPageDataControllerProvider =
StateProvider<MainPageDataController?>((ref) {
return MainPageDataController();
});
class MainPage extends ConsumerWidget {
double? _deviceHeight;
double? _deviceWidth;
MainPageDataController? _mainPageDataController;
MainPageData? _mainPageData;
TextEditingController? _searchTextFieldController;
#override
Widget build(BuildContext context, ScopedReader watch) {
_deviceHeight = MediaQuery.of(context).size.height;
_deviceWidth = MediaQuery.of(context).size.width;
_searchTextFieldController = TextEditingController();
_mainPageDataController = watch(mainPageDataControllerProvider);
_mainPageData = watch(mainPageDataControllerProvider.state);
return _buildUI();
}
Widget _buildUI() {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.black,
body: Container(
height: _deviceHeight,
width: _deviceWidth,
child: Stack(
alignment: Alignment.center,
children: [
_backgroundWidget() ?? const Text('No image to load'),
_foregroundWidget() ?? const Text('No Foreground to load'),
],
),
),
);
}
Widget? _backgroundWidget() {
return Container(
height: _deviceHeight,
width: _deviceWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: const DecorationImage(
image: NetworkImage(
'https://c4.wallpaperflare.com/wallpaper/474/998/395/cillian-murphy-tom-hardy-dunkirk-best-movies-wallpaper-preview.jpg',
),
fit: BoxFit.cover,
//image: AssetImage('assets/images/logo.png'),
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.2),
),
),
),
);
}
Widget? _foregroundWidget() {
return Container(
padding: EdgeInsets.only(top: _deviceHeight! * 0.02),
width: _deviceWidth! * 0.88,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_topBarWidget() ??
const SizedBox(
child: Text(
"Can't load Bar",
style: TextStyle(color: Colors.white),
),
),
Container(
height: _deviceHeight! * 0.83,
padding: EdgeInsets.symmetric(vertical: _deviceHeight! * 0.01),
child: _moviesListViewWidget(),
),
],
),
);
}
Widget? _topBarWidget() {
return Container(
height: _deviceHeight! * 0.08,
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
searchFieldWidget(),
_categorySelectionWidget(),
],
),
);
}
Widget searchFieldWidget() {
final _border = InputBorder.none;
return Container(
width: _deviceWidth! * 0.5,
height: _deviceHeight! * 0.05,
child: TextField(
controller: _searchTextFieldController,
onSubmitted: (_input) {},
style: const TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
focusedBorder: _border,
border: _border,
prefixIcon: const Icon(
Icons.search,
color: Colors.white24,
),
hintText: "Search....",
hintStyle: const TextStyle(
color: Colors.white54,
),
),
),
);
}
Widget _categorySelectionWidget() {
return DropdownButton<String>(
dropdownColor: Colors.black38,
value: SearchCategory.popular,
icon: const Icon(
Icons.menu,
color: Colors.white24,
),
items: [
DropdownMenuItem(
child: Text(
SearchCategory.popular,
style: const TextStyle(
color: Colors.white,
),
),
value: SearchCategory.popular,
),
DropdownMenuItem(
child: Text(
SearchCategory.upcoming,
style: const TextStyle(
color: Colors.white,
),
),
value: SearchCategory.upcoming,
),
DropdownMenuItem(
child: Text(
SearchCategory.none,
style: const TextStyle(
color: Colors.white,
),
),
value: SearchCategory.none,
),
],
underline: Container(
height: 1,
color: Colors.white24,
),
onChanged: (_value) {},
);
}
Widget? _moviesListViewWidget() {
final List<Movie> _movies = [];
for (var i = 0; i < 10; i++) {
_movies.add(
Movie(
name: "Movie 1",
language: "EN",
isAdult: false,
description: "Nothing for now",
rating: 8.0,
releaseDate: "2021-10-20",
posterPath: "/xGUOF1T3WmPSACQEQJfnG7Ud9f8.jpg",
backdropPath: "/9yBVqNruk6Ykrwc32qrk2TIE5xw.jpg",
),
);
}
if (_movies.isNotEmpty) {
return ListView.builder(
itemCount: _movies.length,
itemBuilder: (BuildContext _context, int _index) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: _deviceHeight! * 0.01, horizontal: 0),
child: GestureDetector(
onTap: () {},
child: MovieTile(
movie: _movies[_index],
height: _deviceHeight! * 0.2,
width: _deviceWidth! * 0.85,
),
),
);
},
);
} else {
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
);
}
}
}
Here is the MainPageDataController class, I declared the state parameter as optional, and I am fetchinf movies in the getMovies function -
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:movie_app/model/main_page_data.dart';
import 'package:movie_app/model/movie.dart';
import 'package:movie_app/services/movie_service.dart';
import 'package:riverpod/riverpod.dart';
class MainPageDataController extends StateNotifier<MainPageData> {
MainPageDataController([MainPageData? state])
: super(state ?? MainPageData.initial()) {
getMovies();
}
final MovieService _movieService = GetIt.instance.get<MovieService>();
Future<void> getMovies() async {
try {
List<Movie> _movies = [];
_movies = await _movieService.getPopularMovies(page: state.page);
} catch (e) {}
}
}
use StateNotifierProvider instead of StateProvider
final mainPageDataControllerProvider =
StateNotifierProvider<MainPageDataController?, MainPageData?>((ref) {
return MainPageDataController();
});

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();
}
}),
),
],
),
),
);
}
}

How to generate new route to the new stfull widget when user created new container?

I am currently developing an app which people can save their receipt in it, I shared home screen below,initial time It will be empty, as soon as user add new menu, it will get full with menu, After user added new menu, the should be able to click the menu container, and access to new screen for example, İn home screen I created container which called "CAKES", the cakes screen should be created, if I created another menu in my home screen It should also created too, I currently menu extanded screen as a statefull widget already, you can see below, but my question is How can I create this page for spesific menu's , How can I store them, in list, in map etc, Lastly, I dont want user information dissapear, I know I have to use database, but I want to use local database, How can I handle with that, Have a nice day...
import 'package:flutter/material.dart';
import 'package:lezzet_kitabi/add_menu_screen.dart';
import 'package:lezzet_kitabi/constants.dart';
import 'package:lezzet_kitabi/widgets.dart';
class HomeScreen extends StatefulWidget {
HomeScreen({this.newMenuName,this.imagePath});
final imagePath;
final newMenuName;
static String id="homeScreen";
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Menü Ekle",route: HomeScreen,);
void initState(){
super.initState();
if (widget.newMenuName!=null && widget.imagePath!=null){
Widget newMenu=MenuCard(newMenuName: widget.newMenuName,imagePath: widget.imagePath);
menuCards.insert(0,newMenu);
}
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: kColorTheme1,
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:TitleBorderedText(title:"SEVIMLI YEMEKLER", textColor: Color(0xFFFFFB00)),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(kCuttedLogoPath),
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(kBGWithLogoOpacity),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GridView.count(
crossAxisCount: 2,
children:menuCards,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
boxShadow:[
BoxShadow(
color: Colors.black.withOpacity(1),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(0,4),
),
],
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",),
);
},
child: TitleBorderedText(title: "LEZZET GRUBU EKLE",textColor: Colors.white,)
),
),
),
],
)
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:lezzet_kitabi/screens/home_screen.dart';
import 'package:lezzet_kitabi/widgets.dart';
import 'constants.dart';
import 'dart:math';
class AddMenuScreen extends StatefulWidget {
AddMenuScreen({#required this.buttonText, #required this.route});
final route;
final String buttonText;
static String id="addMenuScreen";
#override
_AddMenuScreenState createState() => _AddMenuScreenState();
}
class _AddMenuScreenState extends State<AddMenuScreen> {
int selectedIndex=-1;
Color _containerForStickersInactiveColor=Colors.white;
Color _containerForStickersActiveColor=Colors.black12;
final stickerList= List<String>.generate(23, (index) => "images/sticker$index");
String chosenImagePath;
String menuName;
int addScreenImageNum;
void initState(){
super.initState();
createAddScreenImageNum();
}
void createAddScreenImageNum(){
Random random =Random();
addScreenImageNum = random.nextInt(3)+1;
}
#override
Widget build(BuildContext context) {
return Material(
child: Container(
color: kColorTheme9,
child: Container(
height: 400,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft: Radius.circular(40)),
),
child:Padding(
padding:EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: kColorTheme2,
borderRadius: BorderRadius.circular(90)
),
child: TextField(
style: TextStyle(
color: Colors.black,
fontFamily:"Graduate",
fontSize: 20,
),
textAlign: TextAlign.center,
onChanged: (value){
menuName=value;
},
decoration: InputDecoration(
border:OutlineInputBorder(
borderRadius: BorderRadius.circular(90),
borderSide: BorderSide(
color: Colors.teal,
),
),
hintText: "Menü ismi belirleyin",
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.2),
fontFamily: "Graduate",
),
),
),
),
SizedBox(height: 20,),
Text(" yana kadırarak menünüz icin bir resim secin",textAlign: TextAlign.center,
style: TextStyle(fontFamily: "Graduate", fontSize: 12),),
SizedBox(height: 20,),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: stickerList.length,
itemBuilder: (context,index){
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: index == selectedIndex ?
_containerForStickersActiveColor :
_containerForStickersInactiveColor,
),
child:FlatButton(
child: Image(
image: AssetImage("images/sticker$index.png"),
),
onPressed: (){
setState(() {
selectedIndex = index;
});
},
),
);
}
),
),
SizedBox(height: 20,),
Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(90),
),
child: FlatButton(
onPressed: (){
widget.route=="homeScreen"?Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen(newMenuName: menuName,imagePath: "images/sticker$selectedIndex.png")))
:Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtension(menuExtensionName: menuName)),
);
},
child: Text(widget.buttonText, style: TextStyle(fontSize: 20, color: Colors.white,
fontFamily: "Graduate", fontWeight: FontWeight.bold),),
),
),
],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'dart:math';
import 'add_menu_screen.dart';
import 'package:bordered_text/bordered_text.dart';
import 'package:lezzet_kitabi/screens/meal_screen.dart';
import 'constants.dart';
List<Widget> menuExtensionCards=[EmptyMenu()];
List<Widget> menuCards=[EmptyMenu()];
class MenuCard extends StatelessWidget {
MenuCard({this.newMenuName, this.imagePath});
final newMenuName;
final imagePath;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top:15.0),
child: FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtension(menuExtensionName: newMenuName,)));
},
child: Container(
height: 180,
width: 180,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(0.5),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10,),
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
borderRadius: BorderRadius.circular(90),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
newMenuName,
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Graduate',
fontWeight: FontWeight.bold),
),
),
),
Expanded(
child: Padding(
padding:EdgeInsets.all(5),
child: Image(
image: AssetImage(
imagePath
),
),
),
),
],
),
),
),
);
}
}
class EmptyMenu extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top:15.0),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route:"homeScreen"),
);
},
child: Container(
height: 180,
width: 180,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.black12.withOpacity(0.1),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.add_circle_outline_outlined,size: 100,color: Colors.grey.shade400,),
],
),
),
),
);
}
}
class MenuExtension extends StatefulWidget {
MenuExtension({this.menuExtensionName});
final String menuExtensionName;
#override
_MenuExtensionState createState() => _MenuExtensionState();
}
class _MenuExtensionState extends State<MenuExtension> {
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Tarif Ekle",route: MealScreen,);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:BorderedText(
child:Text(
widget.menuExtensionName,
style: TextStyle(
color: Color(0XFFFFFB00),
fontSize: 30,
fontFamily: "Graduate"
),
),
strokeWidth: 5,
strokeColor: Colors.black,
),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage("images/cuttedlogo.PNG"),
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/logoBGopacity.png"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GridView.count(
crossAxisCount: 2,
children:menuExtensionCards,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
boxShadow:[
BoxShadow(
color: Colors.black.withOpacity(1),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(0,4),
),
],
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Tarif Ekle", route:"mealScreen"),
);
},
child: BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text("Tarif Ekle",style: TextStyle(
color: Colors.white,
fontFamily:'Graduate',
fontSize:30,
),
),
),
),
),
),
],
)
],
),
),
),
);
}
}
class TitleBorderedText extends StatelessWidget {
TitleBorderedText({this.title, this.textColor});
final Color textColor;
final String title;
#override
Widget build(BuildContext context) {
return BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text(title,style: TextStyle(
color: textColor,
fontFamily:'Graduate',
fontSize:30,
),
),
);
}
}

image_picker only showing images after hot reload. Flutter

I'm using the image_picker package to read images and take them using the camera.
I'm also using the provider package to manage the changes in results.
The app is about ads for selling stuff, when adding a new ad it is added successfully.
the problem is that the ad main image is not showing until I make a hot reload, and before reloading it shows an error.
Unable to load asset: /storage/emulated/0/Android/data/com.bkh.ads/files/Pictures/d2abeed9-3dfa-44b4-a032-ddefff58762e2465964411313585659.jpg
once I make a hot reload the ad image gets shown correctly and the error vanishes.
This is how I'm using image_picker:
Future _setAdMainImage() async {
String _method;
await showModalBottomSheet(
context: context,
builder: (context) => Container(
height: 105,
child: Column(
children: [
Container(
height: 50,
child: RaisedButton(
color: ColorPalette.PRIMARY_COLOR,
onPressed: () {
_method = 'Camera';
Navigator.of(context).pop();
},
child: Center(
child: Text(
'Image From Camera',
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 18,
color: ColorPalette.WHITE_TEXT_ICONS_COLOR,
),
),
),
),
),
SizedBox(
height: 5,
),
Container(
height: 50,
child: RaisedButton(
color: ColorPalette.PRIMARY_COLOR,
onPressed: () {
_method = 'Gallery';
Navigator.of(context).pop();
},
child: Center(
child: Text(
'Image From Gallery',
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 18,
color: ColorPalette.WHITE_TEXT_ICONS_COLOR,
),
),
),
),
),
],
),
),
);
if (_method != null) {
final _pickedFile = await _imagePicker.getImage(
source: _method == 'Camera' ? ImageSource.camera : ImageSource.gallery,
);
setState(() {
_image = File(_pickedFile.path);
});
_method = null;
}
}
This is how I'm adding the new ad object using the provider:
void addVehicleAd(VehicleAd vehicleAd) {
_vehicleAds.add(vehicleAd);
notifyListeners();
}
This is how I'm showing the results:
#override
Widget build(BuildContext context) {
_data = ModalRoute.of(context).settings.arguments as Map<String, dynamic>;
_ads = Provider.of<VehicleAds>(context).carAds;
return Scaffold(
body: ListView.builder(
itemCount: _ads.length,
itemBuilder: (context, index) => AdCard(
id: _ads[index].id,
image: _ads[index].image,
price: _ads[index].price,
label: _ads[index].label,
date: _ads[index].date,
),
),
);
}
And this is the AdCard widget:
class AdCard extends StatelessWidget {
final int id;
final String label, image;
final int price;
final DateTime date;
AdCard({
#required this.id,
#required this.label,
#required this.price,
#required this.image,
#required this.date,
});
#override
Widget build(BuildContext context) {
var _height = MediaQuery.of(context).size.height;
return InkWell(
child: Card(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: BorderSide(
width: 2,
color: ColorPalette.ACCENT_COLOR,
),
),
child: Stack(
children: <Widget>[
Container(
height: 250,
width: double.infinity,
child: Hero(
tag: id,
child: Image(
image: AssetImage(image),
fit: BoxFit.cover,
),
),
),
Positioned(
right: 10,
bottom: 10,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.black.withOpacity(.5),
),
child: Text(
label,
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
style: TextStyle(
height: 1,
color: ColorPalette.WHITE_TEXT_ICONS_COLOR,
),
),
),
),
Positioned(
left: 10,
bottom: 10,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.black.withOpacity(.5),
),
child: Text(
'$price',
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
style: TextStyle(
color: ColorPalette.WHITE_TEXT_ICONS_COLOR,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.topCenter,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.black.withOpacity(.5),
),
child: Text(
'${date.day}/${date.month}/${date.year}',
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
style: TextStyle(
color: ColorPalette.WHITE_TEXT_ICONS_COLOR,
),
),
),
),
),
],
),
),
);
}
}
I have no idea where the wrong code is...
Any help would be appreciated
AssetImage widget gets from your asset resource.
For images taken by imagepicker, use Image.file.
Image.file(/* your file */, fit: BoxFit.cover,)

Having difficulty adding items to shopping cart - Flutter

I have my Cart model as below
class Cart {
String description;
double unitCost;
double amount;
int quantity;
String color;
String imageURl;
Cart({
this.description,
this.unitCost,
this.amount,
this.color,
this.quantity,
this.imageURl,
});
}
And my CartData notifier class which has a _cartList with pre-loaded data as shown below:
class CartData extends ChangeNotifier {
List<Cart> _cartItems = [
Cart(
imageURl:
'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg',
description: 'Nike Air Max',
quantity: 3,
unitCost: 6000,
),
Cart(
color: 'red',
description: 'Nike Air Max',
quantity: 3,
unitCost: 3000,
),
Cart(
imageURl:
'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg',
description: 'Nike Air Max',
quantity: 6,
unitCost: 6000,
),
Cart(
color: 'purple',
description: 'Nike Air Max',
quantity: 2,
unitCost: 1000,
),
Cart(
color: 'purple',
description: 'Nike Air Max',
quantity: 2,
unitCost: 2000,
),
];
UnmodifiableListView<Cart> get cartItems {
return UnmodifiableListView(_cartItems);
}
int get cartItemsCount {
return _cartItems.length;
}
void addItemToCart(
String color,
double unitCost,
String description,
String imageURL,
int quantity,
) {
_cartItems.insert(
0,
Cart(
color: color,
unitCost: unitCost,
description: description,
imageURl: imageURL,
quantity: quantity,
),
);
notifyListeners();
}
void getTotalSum(Cart cart) {}
double getAmount(int qty, double unitCost) {
return qty * unitCost;
}
void upDateCartItem(Cart cartItem, bool isIncrementing) {
if (isIncrementing == true) {
cartItem.quantity++;
print(
'Cart item purchase quantity is: ${cartItem.quantity}, after incrementing from updateCartItem');
} else {
if (cartItem.quantity >= 1) {
cartItem.quantity--;
print(
'Cart item purchase quantity is: ${cartItem.quantity} after decrementing from updateCartItem');
}
if (cartItem.quantity == 0) {
deleteItemFromCart(cartItem);
}
print(cartItem.quantity);
}
cartItem.amount = cartItem.quantity * cartItem.unitCost;
print('Cart Item amount is: ${cartItem.amount} from updateCartItem');
notifyListeners();
}
void deleteItemFromCart(Cart cartItem) {
_cartItems.remove(cartItem);
notifyListeners();
}
}
I want to be able to add items on the fly to my existing list of Cart Items using my addItemToCart() method, and display them immediately on my shopping cart page.
In my shopping screen, I have a few declarations as below:
String defaultDescription = 'add description';
String paymentDescription = 'add description';
String amount = '0';
int cartTotal = 0;
However, I'm unable to add item(s) to cart from my shopping screen when I call the addItemToCart method as below:
_addToCart() {
if (amount == '' || amount == '0') {
print('add an amount');
_showToast(this.context, 'amount');
} else if (paymentDescription == defaultDescription) {
print('please enter a valid description to proceed');
_showToast(this.context, 'payment description');
} else {
print(amount);
print(paymentDescription);
//do something like add to cart
CartData cartData = Provider.of<CartData>(context, listen: false);
cartData.addItemToCart(
null,
double.parse(output),
paymentDescription,
null,
1,
);
}
setState(() {
paymentDescription = defaultDescription;
amount = '0';
});
}
Here's my checkout screen that displays the cart Items:
class CheckoutScreen extends StatefulWidget {
static const String id = 'checkout_screen';
#override
_CheckoutScreenState createState() => _CheckoutScreenState();
}
class _CheckoutScreenState extends State<CheckoutScreen> {
#override
void initState() {
super.initState();
CustomerNotifier customerNotifier =
Provider.of<CustomerNotifier>(context, listen: false);
customerNotifier.getCustomers(customerNotifier);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ChangeNotifierProvider(
create: (context) => CartData(),
child: Consumer<CartData>(
builder: (context, cartData, child) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black26,
),
onPressed: () => Navigator.pop(context),
),
Text(
'Shopping cart',
style: TextStyle(
fontSize: 21.0,
color: Colors.black26,
fontWeight: FontWeight.bold,
),
),
],
),
Container(
margin: EdgeInsets.only(top: 8.0, bottom: 8.0),
height: MediaQuery.of(context).size.height / 16,
width: MediaQuery.of(context).size.width - 150,
decoration: BoxDecoration(
border: Border.all(color: kThemeStyleButtonFillColour),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Customer drop down',
textAlign: TextAlign.center,
style: kRegularTextStyle,
maxLines: 2,
textDirection: TextDirection.ltr,
softWrap: true,
),
SizedBox(width: 5.0),
Icon(
Icons.keyboard_arrow_down,
color: kThemeStyleButtonFillColour,
size: 25,
),
],
),
),
Expanded(
flex: 4,
child: Container(
height: MediaQuery.of(context).size.height - 225,
padding: const EdgeInsets.only(
left: 16, right: 16, bottom: 8.0),
child: ListView.builder(
itemCount: cartData.cartItems.length,
shrinkWrap: true,
itemBuilder: (context, index) {
final cartItem = cartData.cartItems[index];
return cartData.cartItems.isEmpty
? Container(
child: Align(
alignment: Alignment.center,
child: Text('Your cart is empty')))
: Container(
color: Colors.white,
margin: EdgeInsets.symmetric(vertical: 6.0),
child: Row(
children: <Widget>[
Expanded(
child: Container(
width: 80.0,
height: 70.0,
child: Center(
child: cartItem.imageURl == null
? Container(
padding:
EdgeInsets.all(4.0),
decoration: BoxDecoration(
color: Color((math.Random()
.nextDouble() *
0xFFFFFF)
.toInt())
.withOpacity(1.0),
borderRadius:
BorderRadius.circular(
20.0),
),
)
: Container(
padding:
EdgeInsets.all(4.0),
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
cartItem.imageURl),
),
borderRadius:
BorderRadius.circular(
20.0),
),
),
),
),
),
SizedBox(width: 12.0),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 100.0,
child: Text(
cartItem.description,
style: TextStyle(
fontWeight: FontWeight.bold),
),
),
SizedBox(height: 8.0),
Row(
children: <Widget>[
GestureDetector(
child: Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius:
BorderRadiusDirectional
.circular(4.0),
),
child: Icon(
Icons.remove,
color: Colors.white,
size: 15.0,
),
),
onTap: () {
cartData.upDateCartItem(
cartItem, false);
},
),
Padding(
padding:
const EdgeInsets.symmetric(
horizontal: 15.0),
child: Text(
'${cartItem.quantity}',
style: TextStyle(
fontWeight:
FontWeight.bold,
fontSize: 15.0),
),
),
GestureDetector(
child: Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color:
kThemeStyleButtonFillColour,
borderRadius:
BorderRadiusDirectional
.circular(4.0),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
),
onTap: () {
cartData.upDateCartItem(
cartItem, true);
},
),
],
),
],
),
// Spacer(),
Expanded(
child: Text(
'${cartData.getAmount(cartItem.quantity, cartItem.unitCost)}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0),
),
),
Expanded(
child: GestureDetector(
child: Icon(
Icons.delete_forever,
size: 25.0,
color: kThemeStyleButtonFillColour,
),
onTap: () => cartData
.deleteItemFromCart(cartItem),
),
),
],
),
);
},
),
),
),
],
);
},
),
),
),
);
}
}
What could I be missing here?
Calling your addItemToCart() should rebuild the children inside Consumer<CartData>() because of notifyListeners(). This should help you give some clue on what's happening.
Add a debugPrint('List length: ${cartData.cartItemsCount}') inside the Consumer to check if List _cartItems changes after adding an item.