Related
I'm a beginner in Flutter.
I designed this page:
Instead of repeating the entire Listview.builder. I would like to use two instances of custom Listview.builder with two lists, one list for fruits, and the other for vegetables.
As appeared in the above screen, I tried to display vegetables in the vegetables section through the following:
Listview.builder Widget:
import 'package:flutter/material.dart';
import 'package:grocery_store/models/products_list.dart';
import '../utilities/add_product.dart';
import '../utilities/constants.dart';
class ProductsListView extends StatelessWidget {
final String? productImage;
final String? productName;
final String? productCategory;
final String? productPrice;
const ProductsListView({
Key? key,
this.productImage,
this.productName,
this.productCategory,
this.productPrice,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: fruitsList.length,
itemBuilder: (BuildContext context, int index) {
return ClipRect(
child: Container(
width: 140.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white,
boxShadow: const [
BoxShadow(
blurRadius: 10,
color: Colors.black,
),
],
),
margin: const EdgeInsets.all(10.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 10),
child: Column(
children: [
Image.asset(
fruitsList[index].fruitImage!,
height: 80.0,
width: 90.0,
),
const SizedBox(
height: 15,
),
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
fruitsList[index].fruitName!,
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
Text(
fruitsList[index].fruitCategory!,
textAlign: TextAlign.left,
style: const TextStyle(
height: 1.5,
color: kDarkGrey,
fontSize: 12.5,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
Row(
children: [
Text(
fruitsList[index].fruitPrice!,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
const AddProduct(),
],
)
],
),
),
),
);
},
);
}
}
Fruits and vegetables lists:
import '../utilities/constants.dart';
class Fruits {
final String? fruitImage;
final String? fruitName;
final String? fruitCategory;
final String? fruitPrice;
Fruits(
{this.fruitImage, this.fruitName, this.fruitCategory, this.fruitPrice});
}
final Fruits bananas = Fruits(
fruitImage: '${kFruitsImagesAsset}bananas.png',
fruitName: 'Bananas',
fruitCategory: 'Organic',
fruitPrice: '\$4.99',
);
final Fruits apples = Fruits(
fruitImage: '${kFruitsImagesAsset}apples.png',
fruitName: 'Apples',
fruitCategory: 'Organic',
fruitPrice: '\$5.00',
);
final Fruits chikku = Fruits(
fruitImage: '${kFruitsImagesAsset}chikku.png',
fruitName: 'Chikku',
fruitCategory: 'Organic',
fruitPrice: '\$9.00',
);
final Fruits peaches = Fruits(
fruitImage: '${kFruitsImagesAsset}peaches.png',
fruitName: 'Peaches',
fruitCategory: 'Organic',
fruitPrice: '\$12.00',
);
List<Fruits> fruitsList = [bananas, apples, chikku, peaches];
class Vegetables {
final String? vegetableImage;
final String? vegetableName;
final String? vegetableCategory;
final String? vegetablePrice;
Vegetables(
{this.vegetableImage,
this.vegetableName,
this.vegetableCategory,
this.vegetablePrice});
}
final Vegetables okra = Vegetables(
vegetableImage: '${kVegetablesImagesAsset}okra.png',
vegetableName: 'Okra',
vegetableCategory: 'Organic',
vegetablePrice: '\$6.99',
);
final Vegetables peas = Vegetables(
vegetableImage: '${kVegetablesImagesAsset}peas.png',
vegetableName: 'Peas',
vegetableCategory: 'Organic',
vegetablePrice: '\$10.50',
);
final Vegetables potatoes = Vegetables(
vegetableImage: '${kVegetablesImagesAsset}potatoes.png',
vegetableName: 'Potatoes',
vegetableCategory: 'Organic',
vegetablePrice: '\$5.99',
);
final Vegetables taro = Vegetables(
vegetableImage: '${kVegetablesImagesAsset}taro.png',
vegetableName: 'Taro',
vegetableCategory: 'Organic',
vegetablePrice: '\$5.50',
);
List<Vegetables> vegetablesList = [okra, peas, potatoes, taro];
Homepage where I want to display the two lists:
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:grocery_store/models/product_cards_column.dart';
import 'package:grocery_store/utilities/constants.dart';
import 'package:grocery_store/utilities/grocery_text_field.dart';
import '../models/products_cards.dart';
import '../models/products_list.dart';
class GroceryPage extends StatelessWidget {
const GroceryPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
var discountPortrait =
MediaQuery.of(context).orientation == Orientation.portrait;
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 1, 0),
child: Row(
children: [
const Text(
'Grocery',
style: kTitleTextStyle,
),
const Spacer(),
ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Image.asset(
'images/apple.jpg',
width: 46.0,
height: 46.0,
fit: BoxFit.cover,
),
),
],
),
),
const SizedBox(height: 10.0),
Row(children: [
GroceryTextField.groceryTextField(
groceryText: 'Search...',
),
const SizedBox(width: 5.0),
Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18.0),
color: kLightGrey,
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: SvgPicture.asset(
'images/funnel.svg',
semanticsLabel: 'Funnel',
color: kDarkGrey,
),
),
),
]),
const SizedBox(height: 10.0),
Container(
height: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: const Color(0xFFE9F9F2),
),
width: double.infinity,
child: Stack(
children: [
Positioned(
bottom: -150,
right: discountPortrait ? -30 : 30,
height: 290,
width: 430,
child: Image.asset(
'${kProductsImagesAsset}lettuce.png',
),
),
Positioned(
top: discountPortrait ? 35 : 15,
left: discountPortrait ? 25 : 100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Get Up To',
style: kGreenTitleStyle.copyWith(
fontSize: discountPortrait ? 20 : 60,
),
),
Text(
'%10 off',
style: kGreenTitleStyle.copyWith(
fontSize: 40.0,
),
),
],
),
),
],
),
),
Column(
children: const [
ProductCardsRow(
groceryType: 'Fruits',
),
SizedBox(
height: 215,
width: double.infinity,
child: ProductsListView(
),
),
],
),
Column(
children: const [
ProductCardsRow(
groceryType: 'Vegetables',
),
SizedBox(
height: 215,
width: double.infinity,
child: ProductsListView(
),
),
],
),
],
),
),
),
),
);
}
}
Hope someone can help
You can set an other variable in constructor and call it list and pass your Vegetables and Fruits to it like this:
class ProductsListView extends StatelessWidget {
final List list;
const ProductsListView({
Key? key,
required this.list,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return ClipRect(
child: Container(
width: 140.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white,
boxShadow: const [
BoxShadow(
blurRadius: 10,
color: Colors.black,
),
],
),
margin: const EdgeInsets.all(10.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 10),
child: Column(
children: [
Image.asset(
list is List<Fruits> ? (list[index] as Fruits).fruitImage! : (list[index] as Vegetables).vegetableImage!,
height: 80.0,
width: 90.0,
),
const SizedBox(
height: 15,
),
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
list is List<Fruits> ? (list[index] as Fruits).fruitName! : (list[index] as Vegetables).vegetableName!,
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
Text(
list is List<Fruits> ? (list[index] as Fruits).fruitCategory! : (list[index] as Vegetables).vegetableCategory!
textAlign: TextAlign.left,
style: const TextStyle(
height: 1.5,
color: kDarkGrey,
fontSize: 12.5,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
Row(
children: [
Text(
list is List<Fruits> ? (list[index] as Fruits).fruitPrice! : (list[index] as Vegetables).vegetablePrice!,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
const AddProduct(),
],
)
],
),
),
),
);
},
);
}
}
and use it like this:
SizedBox(
height: 215,
width: double.infinity,
child: ProductsListView(
list: vegetablesList,
),
),
SizedBox(
height: 215,
width: double.infinity,
child: ProductsListView(
list: fruitsList,
),
),
Yeah it is pretty straightfroward, just click on the listview.builder method in your project and then click on FLutter Outline on the right hand side of the Android Studio IDE window, like this :
Once you have done that the ListView.Builder will be visible in this tree of widgets. What you need to do is to right click on the widget you want to extract and then click on extract method.
you'll get a dialog asking for the name of the newly created widget :
and a new widget will be created at the bottom of your file.
Just change the parameters for both the listview.builders and it'll look something like this :
Widget build(BuildContext context) {
return CommonList(typeList: fruitslist); // use this to change the list
}
And in the newly created widget you'd need to do the same:
class CommonList extends StatelessWidget {
final List typeList; //add a list parameter
const CommonList({
Key? key, required this.typeList, //request that list parameter
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: typeList.length, // change the list type
itemBuilder: (BuildContext context, int index) {
return ClipRect(
child: Container(
width: 140.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white,
boxShadow: const [
BoxShadow(
blurRadius: 10,
color: Colors.black,
),
],
),
margin: const EdgeInsets.all(10.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 10),
child: Column(
children: [
Image.asset(
typeList[index].fruitImage!, //update list to use it everywhere
height: 80.0,
width: 90.0,
),
const SizedBox(
height: 15,
),
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
typeList[index].fruitName!, //like here
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
Text(
typeList[index].fruitCategory!, //here
textAlign: TextAlign.left,
style: const TextStyle(
height: 1.5,
color: kDarkGrey,
fontSize: 12.5,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
Row(
children: [
Text(
typeList[index].fruitPrice!, //and here again
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
const AddProduct(),
],
)
],
),
),
),
);
},
);
}
'
I am a beginner in flutter dev and was trying to implement the screen but then cannot seem to get my head around the error thrown
This code below is supposed to display an onboarding screen but it seems to throw an error with the emulator regarding the title and cannot seem to find any solution on the web any help?'
class OnBoardingScreen extends StatefulWidget {
#override
_OnBoardingScreenState createState() => _OnBoardingScreenState();
}
class _OnBoardingScreenState extends State<OnBoardingScreen> {
final int _numPages = 5;
final PageController _pageController = PageController(initialPage: 0);
int _currentPage =0;
void _onIntroEnd(context) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => SignUpScreen()));
}
void _onIntroSkip(context) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => LoginScreen()));
}
_buildPageIndicator(){
List<Widget> list =[];
for (int i=0;i<_numPages;i++){
list.add(i == _currentPage ? _indicator(true) : _indicator(false) );
}
return list;
}
_indicator (bool isActive){
return AnimatedContainer(duration: Duration(milliseconds: 150),
margin: EdgeInsets.symmetric(horizontal: 8.0),
height: 8.0,
width: isActive ? 24.0 : 16.0,
decoration: BoxDecoration(color: isActive ? Colors.white:Color(0xF385AD5),
borderRadius:BorderRadius.all(Radius.circular(12))
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: AnnotatedRegion(
value: null,
child: Container(
decoration: BoxDecoration(
gradient:LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.1,0.4,0.7,0.9],
colors: [
Color(0xF3C5DD7),
Color(0xF092458),
Color(0xF1B5695),
Color(0xF4664A0)
]
)
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: (){
_onIntroSkip(context);
},
child: Text(
'Skip',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
),
),
Container(
height: 600.0,
child: PageView(
physics :ClampingScrollPhysics(),
controller: _pageController,
onPageChanged: (int page){
setState(() {
_currentPage =page;
});
},
children: [
Padding(
padding: EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image(
image: AssetImage('assets/rooms.webp'
),
height: 300,
width: 300,
),
),
SizedBox(
height: 30.0,
),
Text('Lorem Ipsum',
style: TextStyle(
fontWeight: FontWeight.w800
),
),
SizedBox(height: 15.0,),
Text('Lorem IpSsum',style:TextStyle(
fontWeight: FontWeight.w300
),
)
],
),
),
Padding(
padding: EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image(
image: AssetImage('assets/thoughts.webp'
),
height: 300,
width: 300,
),
),
SizedBox(
height: 30.0,
),
Text('Lorem Ipsum',
style: TextStyle(
fontWeight: FontWeight.w800
),
),
SizedBox(height: 15.0,),
Text('Lorem IpSsum',style:TextStyle(
fontWeight: FontWeight.w300
),
)
],
),
),
Padding(
padding: EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image(
image: AssetImage('group.jpg'
),
height: 300,
width: 300,
),
),
SizedBox(
height: 30.0,
),
Text('Lorem Ipsum',
style: TextStyle(
fontWeight: FontWeight.w800
),
),
SizedBox(height: 15.0,),
Text('Lorem IpSsum',style:TextStyle(
fontWeight: FontWeight.w300
),
)
],
),
),
],
),
),
Row(
mainAxisAlignment:MainAxisAlignment.center ,children: [
_buildPageIndicator() ,
],
),
_currentPage != _numPages - 1 ?
Expanded(
child: Align(
alignment: FractionalOffset.bottomRight,
child: TextButton(
onPressed: () {
_pageController.nextPage(duration: Duration(milliseconds: 500), curve: Curves.ease);
}, child:Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text('Next',style: TextStyle(color: Colors.white,
fontSize: 22.0),),
SizedBox(
width: 10.0,
),
Icon(
Icons.arrow_forward,
color: Colors.white,
size: 30,
)
],
),
),
),
)
:
Text("")
],
),
),
),
),
bottomSheet:_currentPage == _numPages -1 ? Container(
height: 100.0,
width: double.infinity,
color: Colors.white,
child: GestureDetector(
onTap: (){
_onIntroEnd(context);
},
child: Center(
child: Padding(padding: EdgeInsets.only(bottom: 30.0),child:
Text(
'Get Started',
style: TextStyle(
color: Color(0xF3C5DD7),
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
)),
),
),
) :
Text(''),
);
}
}
'This is supposed to display an Onboarding Screen but throws an error . This is shown with the image attached '
Change these parts of your code to look like this:
List<Widget> _buildPageIndicator(){
List<Widget> list =[];
for (int i=0;i<_numPages;i++){
list.add(i == _currentPage ? _indicator(true) : _indicator(false) );
}
return list;
}
.
.
.
.
Row(
mainAxisAlignment:MainAxisAlignment.center,
children: _buildPageIndicator() ,
),
Replace this part of your code:
...
Row(
mainAxisAlignment:MainAxisAlignment.center ,children: [
_buildPageIndicator() ,
],
),
...
with
...
Row(
mainAxisAlignment:MainAxisAlignment.center, children: _buildPageIndicator(),
),
...
or with
...
Row(
mainAxisAlignment:MainAxisAlignment.center ,children: [
..._buildPageIndicator(),
],
),
...
I want to navigate to detail page. But i get invalid argument error. In detail page, i try to get detail information from my online server. If i click on Hot reload button in android studio, the error disappear. Please, How can i do to fix this error ? Screenshoot of error
the error log :
════════ (2) Exception caught by widgets library ═══════════════════════════════════════════════════
Invalid argument(s): The source must not be null
The relevant error-causing widget was:
DetailArticlePage file:///C:/Users/abiboo/FlutterProject/projectname/lib/miledoo_widget/home.dart:515:39
//home.dart
return new Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
height: 240.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: articledata.length,
itemBuilder: (BuildContext context,int index) {
return Padding(
padding: EdgeInsets.all(4),
child: InkWell(
onTap: (){
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
DetailArticlePage(int.parse(articledata[index].idArt), articledata[index].designation)));
},
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
This is a piece of code for detail page who contain a method to get detail informaation from server
//detailpage.dart
import 'package:cached_network_image/cached_network_image.dart';
import 'package:f_miledoo/miledoo_widget/detail_boutique_page.dart';
import 'package:f_miledoo/miledoo_widget/panier_page.dart';
import 'package:f_miledoo/models/detail_article_models.dart';
import 'package:f_miledoo/models/panier_models.dart';
import 'package:f_miledoo/shared/constants.dart';
import 'package:f_miledoo/utils/database_helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../localisation_internationnalisation/localisation.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
class DetailArticlePage extends StatefulWidget{
final int id_art;
final String art_desgnation;
DetailArticlePage(this.id_art, this.art_desgnation);
DetailArticlePages createState() => DetailArticlePages();
}
class DetailArticlePages extends State<DetailArticlePage> {
DatabaseHelper helper = DatabaseHelper();
PanierModel _panier = new PanierModel.withempty();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
int qtecompter = 1;
double prixTotal = 0.0;
String aAfficher = "";
int taillePanier = 0;
String idArt;
String designation;
String descrip;
String prixUnit;
String prixUnit2;
String qteStock;
String idBou;
String lienPhoto;
String nomBou;
#override
void initState() {
// TODO: implement initState
super.initState();
getpanierTaille();
this.getRecapArticleData(widget.id_art, widget.art_desgnation);
}
getpanierTaille() async => taillePanier = await helper.getCount();
getRecapArticleData(int id_article, String nom_article) async {
final response = await http.get(BASE + "xxxxxxx?id_art="+ id_article.toString() +"&nom_art="+ nom_article);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
TheDetailData myData = new TheDetailData.fromJson(jsonResponse);
for (var i = 0; i < myData.articledetail.list_recap_article.length; i++) {
idArt = myData.articledetail.list_recap_article[i].idArt;
designation = myData.articledetail.list_recap_article[i].designation;
descrip = myData.articledetail.list_recap_article[i].descrip;
prixUnit = myData.articledetail.list_recap_article[i].prixUnit;
prixUnit2 = myData.articledetail.list_recap_article[i].prixUnit2;
qteStock = myData.articledetail.list_recap_article[i].qteStock;
lienPhoto = myData.articledetail.list_recap_article[i].lienPhoto;
idBou = myData.articledetail.list_recap_article[i].idBou;
print("id_art = " + idArt + " designation = " + designation +
" prixUnit2 = " + prixUnit2 + " Qté = " + qteStock);
}
} else {
throw Exception("Failed to load Data");
}
}
Future<List<ListArtMemeCate>> _getSameArticleData(int id_article, String nom_article) async {
final response = await http.get(BASE + "xxxxxxx?id_art="+ id_article.toString() +"&nom_art="+ nom_article);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
TheDetailData myData = new TheDetailData.fromJson(jsonResponse);
List<ListArtMemeCate> datas = [];
for (var i = 0; i < myData.articledetail.list_art_meme_cate .length; i++) {
datas.add(myData.articledetail.list_art_meme_cate[i]);
}
return datas;
} else {
throw Exception("Failed to load Data");
}
}
#override
Widget build(BuildContext context) {
int localStockQte = int.parse(qteStock);
double localPrixUnit2 = double.parse(prixUnit2.toString());
Widget article_afficher333 = FutureBuilder(
future: _getSameArticleData(widget.id_art, widget.art_desgnation),
builder: (context, snapshot) {
//if(snapshot.data != null){
if (snapshot.hasData) {
List<ListArtMemeCate> articledata = snapshot.data;
return new Container(
child: GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 0.7,
padding: EdgeInsets.only(top: 8, left: 6, right: 6, bottom: 12),
children: List.generate(articledata.length, (index){
return Container(
child: Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
DetailArticlePage(int.parse(articledata[index].idArt) , articledata[index].designation)));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: (MediaQuery.of(context).size.width / 2 - 40),
width: double.infinity,
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: BASEIMAGES+articledata[index].lienPhoto,
placeholder: (context, url) => Center(
child: CircularProgressIndicator()
),
errorWidget: (context, url, error) => new Icon(Icons.image),
),
),
Padding(
padding: const EdgeInsets.only(top: 2.0),
child: ListTile(
title: Text((() {
if(articledata[index].designation.length >12){
return "${articledata[index].designation.substring(0, 12)}...";}
return "${articledata[index].designation}";
})(), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0, fontFamily: "Questrial")),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 2.0, bottom: 1),
child: Text(articledata[index].prixUnit2+" F CFA", style: TextStyle(
color: Theme.of(context).accentColor,
fontWeight: FontWeight.w700,
fontFamily: 'Questrial'
)),
),
],
),
],
),
),
)
],
),
),
),
);
}),
),
);
} else if (snapshot.hasError) {
return Container(
child: Center(
child: Text(
"Erreur de chargement. Verifier votre connexion internet"),
),
);
}
return new Center(
child: CircularProgressIndicator(),
);
},
);
setState(() {
_panier.nom_article = designation;
_panier.prixUnit2 = double.parse(prixUnit2);
_panier.image_article = lienPhoto;
_panier.prixTot = qtecompter*double.parse(prixUnit2);
_panier.quantite = qtecompter ;
_panier.id_article = int.parse(idArt);
});
void _incrementeQte(){
setState((){
if(qtecompter >= localStockQte){
qtecompter = localStockQte;
}
qtecompter++;
});
}
void _decrementeQte(){
setState((){
if(qtecompter <=1){
qtecompter = 1;
}else{
qtecompter--;
}
});
}
String _getPrixTotal(){
setState((){
prixTotal = qtecompter*localPrixUnit2;
aAfficher = prixTotal.toString();
});
return aAfficher;
}
void _ajouterPanier() async {
//s.addToCart(widget.article);
var result = await helper.addCart(_panier);
var result3 = await helper.getCount();
/*int result;
result = await helper.addCart(_panier);
if(result != 0)
print('STATUS Panier Save Successfully');*/
}
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("designation", style: TextStyle(color: Colors.white),),
iconTheme: new IconThemeData(color: Colors.white),
actions: <Widget>[
Stack(
children: <Widget>[
IconButton(
icon: Icon(Icons.shopping_cart, color: Colors.white, ),
onPressed: () {
//showAlertDialog(context);
Navigator.push(context, new MaterialPageRoute(builder: (context) => PanierPage()));
},
),
Container(
width: 25,
height: 25,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(30),
),
alignment: Alignment.center,
child: Text(taillePanier.toString(),
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 12
),)
),
],
),
],
),
body: new ListView(
children: <Widget>[
new Container(
height: 240,
child: new Hero(tag: lienPhoto, child: new Material(
child: InkWell(
child: new Image.network(
BASEIMAGES + lienPhoto,
fit: BoxFit.cover),
),
)),
),
new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 10,left: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(designation.toString(), style: new TextStyle(fontSize: 20.0, color: Colors.black, fontFamily: 'Questrial'),),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: const EdgeInsets.only(left: 280),
child: new Text(prixUnit2.toString()+" F CFA", style: new TextStyle(fontSize: 15.0, color: Colors.black54, fontFamily: 'Questrial', fontWeight: FontWeight.bold),),
),
SizedBox(height: 10.0),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 10),
child: new Text(descrip.toString(), style: new TextStyle(fontSize: 15.0, color: Colors.grey, fontFamily: 'Questrial'),),
),
SizedBox(height: 10.0),
new Container(
height: 100,
child: Column(
children: <Widget>[
Container(
height: 1.0,
color: Colors.grey,
),
Padding(
padding: const EdgeInsets.only(left: 25, right: 25, top: 20),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(AppLocalizations.of(context)
.translate('_QUANTITY'), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15, fontFamily: 'Questrial'),),
Text(AppLocalizations.of(context)
.translate('_TOTAL_PRICE'), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15, fontFamily: 'Questrial'), ),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 10, right: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
children: <Widget>[
new IconButton(
icon: Icon(Icons.remove_circle_outline, color: Colors.amber, ),
onPressed: _decrementeQte,
),
new Text("$qtecompter"),
new IconButton(
icon: Icon(Icons.add_circle_outline, color: Colors.amber, ),
onPressed: _incrementeQte,
),
],
),
new Text(_getPrixTotal()+" F CFA", style: new TextStyle(fontSize: 20.0, color: Colors.grey),),
],
),
),
Container(
height: 1.0,
color: Colors.grey,
),
],
),
),
//articleMemeCategorie()
],
),
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 25, ),
child: Text(AppLocalizations.of(context)
.translate('_ITEMS_OF_SAME_QUATEGORY'), style: TextStyle(fontFamily: 'Questrial', fontSize: 15, fontWeight: FontWeight.bold),),
),
article_afficher333,
],
),
bottomNavigationBar: new Container(
color: Colors.white,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(child: new MaterialButton(
onPressed: (){showAlertDialog(context);},
child: new Row(
//crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
IconButton(
//widget.article
icon: Icon(Icons.store, color: Colors.white,),
onPressed: () {
//showAlertDialog(context);
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
DetailBoutiquePage(int.parse(idBou)))); },
),
],
),
color: Color(0xFFFFC23A),
),),
Expanded(
flex: 2,
child: new MaterialButton(
onPressed: (){
_ajouterPanier();
},
child: new Container(
child: new Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.add_shopping_cart, color: Colors.white,),
),
Text(AppLocalizations.of(context)
.translate('_ADD_TO_CART'), style: TextStyle(color: Color(0xFFFFFFFF)))
],
),
),
color: Color(0xFFFFC23A),
),),
Expanded(child: new MaterialButton(
onPressed: (){showAlertDialog(context);},
child: new Text(AppLocalizations.of(context)
.translate('_BUY_NOW'), style: TextStyle(color: Color(0xFFFFFFFF)),),
color: Color(0xFFFFC23A),
),),
],
),
)
);
}
}
Without seeing your full detail page and error log it is difficult to tell exactly what your error is.
From the information you have given it sounds like you are trying to retrieve data from an Http request, and then use that information for the display of your page. Have you tried using a FutureBuilder in the detail page? This will allow you to display a page while waiting for the data from the server, and will then display the data from the server once it has been retrieved.
I'm creating a double listView app, its going well so far but I've hit a snag that I can't seem to fix.
I'm getting the error[dart] 2 required argument(s) expected, but 0 found.
In my eyes this should be an easy fix, I thought I just needed to change...
body: _cryptoWidget(),
to...
body: _cryptoWidget(currency, color),
This hasn't worked, and I still get the error stated above.
This is the code I'm using to stimulate the error;
import 'package:flutter/material.dart';
import 'background.dart';
import 'package:flutter/foundation.dart';
import 'package:cryptick_nice_ui/data/crypto_data.dart';
import 'package:cryptick_nice_ui/modules/crypto_presenter.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> implements CryptoListViewContract {
CryptoListPresenter _presenter;
List<Crypto> _currencies;
bool _isLoading;
final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];
List<String> items = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8"
];
_HomePageState() {
_presenter = new CryptoListPresenter(this);
}
#override
void initState() {
super.initState();
_isLoading = true;
_presenter.loadCurrencies();
}
#override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
),
child: new Stack(
children: <Widget>[
new Scaffold(
appBar: new AppBar(
title: new Text("cryp"),
elevation: 0.0,
backgroundColor: Colors.transparent,
),
backgroundColor: Colors.transparent,
body: _cryptoWidget(),
)
],
),
);
}
Widget _cryptoWidget(Crypto currency, MaterialColor color) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
final headerList = new ListView.builder(
itemBuilder: (context, index) {
EdgeInsets padding = index == 0?const EdgeInsets.only(
left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);
_getHtmlUI();
return new Padding(
padding: padding,
);
},
scrollDirection: Axis.horizontal,
itemCount: items.length,
);
new Scaffold(
appBar: new AppBar(
title: new Text('hello'),
elevation: 0.0,
backgroundColor: Colors.transparent,
),
backgroundColor: Colors.transparent,
body: new Container(
child: new Stack(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top: 10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.centerLeft,
child: new Padding(
padding: new EdgeInsets.only(left: 8.0),
child: new Text(
'Your Feed',
style: new TextStyle(color: Colors.white70),
)),
),
new Container(
height: 300.0, width: _width, child: headerList),
new Expanded(child:
ListView.builder(
itemBuilder:
(context, index) {
_getCryptoUI(currency, color);
}
)
)
],
),
),
],
),
),
);
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
),
child: new Stack(
children: <Widget>[
new CustomPaint(
size: new Size(_width, _height),
painter: new Background(),
),
],
),
);
}
Container _getHtmlUI() {
return new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10.0),
color: Colors.lightGreen,
boxShadow: [
new BoxShadow(
color: Colors.black.withAlpha(70),
offset: const Offset(3.0, 10.0),
blurRadius: 15.0)
],
image: new DecorationImage(
image: new ExactAssetImage(
'assets/img_0.jpg'),
fit: BoxFit.fitHeight,
),
),
// height: 200.0,
width: 200.0,
child: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.bottomCenter,
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
borderRadius: new BorderRadius.only(
bottomLeft: new Radius.circular(10.0),
bottomRight: new Radius.circular(10.0))),
height: 30.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'hello',
style: new TextStyle(color: Colors.white),
)
],
)),
)
],
),
);
}
ListTile _getCryptoUI(Crypto currency, MaterialColor color) {
return new ListTile(
title: new Column(
children: <Widget>[
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
height: 72.0,
width: 72.0,
decoration: new BoxDecoration(
color: Colors.lightGreen,
boxShadow: [
new BoxShadow(
color:
Colors.black.withAlpha(70),
offset: const Offset(2.0, 2.0),
blurRadius: 2.0)
],
borderRadius: new BorderRadius.all(
new Radius.circular(12.0)),
image: new DecorationImage(
image: new ExactAssetImage(
"cryptoiconsBlack/"+currency.symbol.toLowerCase()+"#2x.png",
),
fit: BoxFit.cover,
)),
),
new SizedBox(
width: 8.0,
),
new Expanded(
child: new Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
currency.name,
style: new TextStyle(
fontSize: 14.0,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
_getSubtitleText(currency.price_usd, currency.percent_change_1h),
],
)),
new Icon(
Icons.shopping_cart,
color: const Color(0xFF273A48),
)
],
),
new Divider(),
],
),
);
}
Widget _getSubtitleText(String priceUSD, String percentageChange) {
TextSpan priceTextWidget = new TextSpan(
text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
String percentageChangeText = "1 hour: $percentageChange%";
TextSpan percentageChangeTextWidget;
if (double.parse(percentageChange) > 0) {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText,
style: new TextStyle(color: Colors.green));
} else {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText, style: new TextStyle(color: Colors.red));
}
return new RichText(
text: new TextSpan(
children: [priceTextWidget, percentageChangeTextWidget]));
}
#override
void onLoadCryptoComplete(List<Crypto> items) {
// TODO: implement onLoadCryptoComplete
setState(() {
_currencies = items;
_isLoading = false;
});
}
#override
void onLoadCryptoError() {
// TODO: implement onLoadCryptoError
}
}
For more information on other files I use in this app, for instance crypto_data.dart, please see this GitHub repo that I'm using to model certain sections of my code.
The reason why you're getting the error [dart] 2 required argument(s) expected, but 0 found. is because no arguments were passed. The another example you've provided: _cryptoWidget(currency, color) - you're trying to pass a List, which doesn't match the required arguments.
As mentioned in the comments, what you can do here is to define the index for the List to fetch the required values: _cryptoWidget(_currencies[index], _colors[index])
Hi I have designed a screen in flutter. I have AlertDialog on which I want to close the dialog and screen on pressing. Right now AlertDialog dismiss on press but screen is not closing.
Does anyone know how to do this ?
class ForgotPasswordScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return ForgotPasswordScreenState();
}
}
class ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
var emailController = new TextEditingController();
var authHandler = new Auth();
bool isLoading = false;
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white,
),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Row(
children: <Widget>[
new Expanded(
child: isLoading
? Center(child: CircularProgressIndicator())
: new Container()),
],
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text(
"EMAIL",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.redAccent,
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin:
const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.redAccent,
width: 0.5,
style: BorderStyle.solid),
),
),
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextField(
controller: emailController,
textAlign: TextAlign.left,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'PLEASE ENTER YOUR EMAIL',
hintStyle: TextStyle(color: Colors.grey),
),
),
),
],
),
),
Divider(
height: 24.0,
),
new Container(
width: MediaQuery.of(context).size.width,
margin:
const EdgeInsets.only(left: 30.0, right: 30.0, top: 20.0),
alignment: Alignment.center,
child: new Row(
children: <Widget>[
new Expanded(
child: new FlatButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: Colors.redAccent,
onPressed: () {
setState(() {
isLoading = true;
});
authHandler
.sendPasswordResetEmail(emailController.text)
.then((void nothing) {
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
content: new Text(
"Password reset email has been sent."),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
setState(() {
isLoading = false;
});
}).catchError((e) => print(e));
},
child: new Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Text(
"FORGOT PASSWORD",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
],
),
),
],
)));
}
}
Ideally, you'll want to call pop more than once. One for the modal, another for the actual route.
There are a few ways to achieve this. But ideally you'll want to await the close of the dialog before triggering another close:
foo() async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
actions: [
new FlatButton(
child: new Text("OK"),
onPressed: () => Navigator.pop(context),
),
],
),
);
Navigator.pop(context);
}
This way, both the route and the modal can handle their close however they like.
This is how i did with mine
bool _logout = false;
and then at the start of build Widget
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
_onBackPressed(context);
return _logout;
},
child: Container(),
);
}
and the method _onBackPressed returns a custom dialog Class like so
void _onBackPressed(BuildContext c) async {
await showDialog(
barrierColor: CustomColors.darkGrey.withOpacity(0.8),
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return CustomDialogBox(
title: 'Logout',
description: 'Are you sure you want to logout?',
rightButtonText: 'Yes',
onPClick: () {
_logout = true;
if (_logout == true) {
Get.back();
}
},
onNClick: () {
_logout = false;
Get.back();
},
);
});
if (_logout == true) {
Get.back();
}
}
and my custom Dialog class is here
class CustomDialogBox extends StatefulWidget {
final String? title, description, leftButtonText, rightButtonText;
final VoidCallback? onPClick, onNClick;
final Image? image;
const CustomDialogBox({
Key? key,
this.title,
this.description,
this.leftButtonText,
this.rightButtonText,
this.image,
this.onPClick,
this.onNClick,
}) : super(key: key);
#override
_CustomDialogBoxState createState() =>
// ignore: no_logic_in_create_state
_CustomDialogBoxState(onPClick!, onNClick!);
}
class _CustomDialogBoxState extends State<CustomDialogBox> {
final VoidCallback onPClick, onNClick;
_CustomDialogBoxState(this.onPClick, this.onNClick);
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Dimensions.BORDER_RADIUS_4),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Container(
//height: 200,
padding: const EdgeInsets.only(
left: 10,
right: 0,
bottom: 10,
),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: CustomColors.darkGrey,
offset: const Offset(0, 30),
blurRadius: 20,
),
]),
child: Wrap(children: <Widget>[
dialogBody(context),
]),
),
);
}
Widget dialogBody(context) {
return Column(children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Image.asset(
Images.LOGO,
height: MediaQuery.of(context).size.height * 0.035,
),
IconButton(
//padding: const EdgeInsets.all(0),
onPressed: () {
Get.back();
},
icon: const CircleAvatar(
radius: 12.5,
child: Icon(
Icons.close,
color: Colors.white,
),
backgroundColor: Colors.red,
),
),
]),
Padding(
padding: const EdgeInsets.only(
right: 10,
),
child: Column(children: [
//----//
customText(
text: widget.title ?? '',
fontFamily: 'black',
fontSize: 16,
),
//----//
const Space(0, 0.01),
//----//
customText(
text: widget.description ?? '',
fontSize: 14,
),
]),
),
//----//
const Space(0, 0.03),
//----//
Padding(
padding: const EdgeInsets.only(
right: 10,
),
child:
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
//----//
raisedButton(
text: widget.leftButtonText ?? 'Cancel',
fontFamily: 'roman',
height: 35,
width: 105,
buttonColor: CustomColors.red,
onClick: () {
return onNClick();
},
context: context,
),
//----//
raisedButton(
text: widget.rightButtonText ?? 'Okay',
fontFamily: 'roman',
height: 35,
width: 105,
buttonColor: CustomColors.green,
onClick: () {
return onPClick();
},
context: context,
),
//----//
]),
),
]);
}
}
the buttons and texts are custom so feel free to change them. and where you see Get.back(); is GetX code.. you can replace with Navigator.of(context).pop();
try this
showPop() async {
await showDialog(
context: context,
barrierDismissible: true,
builder: (context) => AlertDialog(
actions: [
new FlatButton(
child: new Text("Close"),
onPressed: () => Navigator.pop(context),
),
],
),
);
}