When I try to take a object in my home page I don't get an error, but even if I use the same method in the next screen to display my object from the database, FutureBuilder can't take any value.
#override
Widget build(BuildContext context) {
return WillPopScope(
child: SafeArea(
child: Scaffold(
backgroundColor: kColorTheme1,
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 20,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:TitleBorderedText(title:"Sevimli Yemekler", textColor: Color(0xFFFFFB00)),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(kCuttedLogoPath),
),
],
),
body: FutureBuilder<Map>(
future: HiveHelper().getCategoryModels(),
builder: (BuildContext context,AsyncSnapshot<Map> snapshot){
if(snapshot.hasData) {
_list = snapshot.data.values.toList();
}
Future.delayed(Duration(milliseconds: 200));
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(kBGWithLogoOpacity),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child:GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: _list.length+1,
itemBuilder: (context,index){
if(_list.length==0){
return EmptyCard(where: "homeScreen",);
}
if(_flag==1){
return EmptyCard(where: "homeScreen",);
}
if(index==_list.length-1){
_flag=1;
CategoryModel categoryModel = _list[index];
return CategoryCard(category: categoryModel);
}
else{
CategoryModel categoryModel =_list[index];
return CategoryCard(category: categoryModel);
}
}
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: TextButton(
onPressed: (){
showModalBottomSheet(
isDismissible: false,
enableDrag: false,
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",),
);
},
child: TitleBorderedText(title: "LEZZET GRUBU EKLE",textColor: Colors.white,)
),
),
),
],
)
],
),
);
},
),
),
),
onWillPop: ()async{
var response = await showAlertDialog(context);
print(response);
return response;
},
);
}
I can display my object here without any error. I use the same database and same builder below, but I can take a value.
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder<Map>(
future: HiveHelper().getCategoryModel(widget.categoryId),
builder: (BuildContext context,AsyncSnapshot<Map> snapshot) {
if(snapshot.hasData) {
_list=snapshot.data.values.toList();
}
Future.delayed(Duration(milliseconds: 200));
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
title: BorderedText(
child:Text(
_list[4],
style: TextStyle(
color: Color(0XFFFFFB00),
fontSize: 30,
fontFamily: "OpenSans"
),
),
strokeWidth: 5,
strokeColor: Colors.black,
),
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
Navigator.pop(context);
},
iconSize: 40,
color: Color(0xFFA2000B),
),
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.builder(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount:_list[5].length+1,
itemBuilder: (context,index){
if(_list[5].length==0){
return EmptyCard(where: "subCategoryScreen",categoryId: widget.categoryId,);
}
if(_flag==1){
return EmptyCard(where: "homeScreen",);
}
if(index==_list[5].length-1){
_flag=1;
SubCategoryModel subCategoryModel =SubCategoryModel();
return SubCategoryCard(subCategoryCardId:index,subCategoryId:subCategoryModel.subCategoryId,subcategoryName: subCategoryModel.subCategoryName,
subCategoryImagePath:subCategoryModel.subCategoryImagePath,
subCategoryCardColor: subCategoryModel.categoryColor,);
}
else{
SubCategoryModel subCategoryModel =SubCategoryModel();
return SubCategoryCard(subCategoryCardId:index,subCategoryId:subCategoryModel.subCategoryId,subcategoryName: subCategoryModel.subCategoryName,
subCategoryImagePath:subCategoryModel.subCategoryImagePath,
subCategoryCardColor: subCategoryModel.categoryColor,);
}
}
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: TextButton(
onPressed: (){
showModalBottomSheet(
isDismissible: false,
enableDrag: false,
context: context,
builder: (BuildContext context)=> AddMenuScreen(categoryId:widget.categoryId,buttonText: "Tarif Ekle", route:"subCategoryScreen"),
);
},
child: BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text("Tarif Ekle",style: TextStyle(
color: Colors.white,
fontFamily:'OpenSans',
fontSize:30,
),
),
),
),
),
),
],
)
],
),
),
);
}
),
),
);
}
class HiveHelper{
void addCategoryModel(CategoryModel categoryModel)async{
var box = await Hive.openBox('categoryModelsInBox');
await box.add(categoryModel);
await Hive.close();
}
Future <Map> getCategoryModels()async{
var box = await Hive.openBox('categoryModelsInBox');
var boxToMap=box.toMap();
return boxToMap;
}
Future <Map> getCategoryModel(int index) async {
var box = await Hive.openBox('categoryModelsInBox');
var boxToMap=box.toMap();
return boxToMap[index];
}
void addSubCategory(SubCategoryModel subCategoryModel, key)async{
var box = await Hive.openBox('categoryModelsInBox');
box.put(subCategoryModel,key);
}
}
Here is my hive class. How can I fix this problem?
Don't create the future in the "future:" parameter of a FutureBuilder. As the first large paragraphs of the Fine Manual says:
The future must have been obtained earlier, e.g. during State.initState, State.didUpdateWidget, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.
A general guideline is to assume that every build method could get called every frame, and to treat omitted calls as an optimization.
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
I am not sure, but you could try:
Future <Map> getCategoryModel(int index) async {
var box = await Hive.openBox('categoryModelsInBox');
var boxToMap=box.toMap();
return boxToMap["$index"];
}
Related
I have a working filter button in search page of my app
I need to add it as floating button in other pages such as category, view all products etc
Here is the working filter button code for searchscreen.
class SearchProductWidget extends StatelessWidget {
final bool isViewScrollable;
final List<Product> products;
SearchProductWidget({this.isViewScrollable, this.products});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(Dimensions.PADDING_SIZE_SMALL),
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
'Search result for \"${Provider.of<SearchProvider>(context).searchText}\" (${products.length} items)',
style: titilliumRegular.copyWith(
fontSize: Dimensions.FONT_SIZE_DEFAULT),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
InkWell(
onTap: () => showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (c) => SearchFilterBottomSheet()),
child: Container(
padding: EdgeInsets.symmetric(
vertical: Dimensions.PADDING_SIZE_EXTRA_SMALL,
horizontal: Dimensions.PADDING_SIZE_SMALL),
decoration: BoxDecoration(
color: ColorResources.getLowGreen(context),
borderRadius: BorderRadius.circular(5),
border: Border.all(
width: 1, color: Theme.of(context).hintColor),
),
child: Row(children: [
///Image.asset(Images.filter_image, width: 10, height: 10, color: ColorResources.getPrimary(context)),
SizedBox(width: Dimensions.PADDING_SIZE_EXTRA_SMALL),
Text('Filter'),
]),
),
),
],
),
SizedBox(height: Dimensions.PADDING_SIZE_SMALL),
Expanded(
child: StaggeredGridView.countBuilder(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(0),
crossAxisCount: 2,
itemCount: products.length,
//shrinkWrap: true,
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
itemBuilder: (BuildContext context, int index) {
return ProductWidget(productModel: products[index]);
},
),
),
],
),
);
}
}
I'm trying to create a floating action button to work as a filter in different screens
Here is one of the screen which I need the filter button working-
class AllProductScreen extends StatelessWidget {
final ScrollController _scrollController = ScrollController();
final ProductType productType;
AllProductScreen({#required this.productType});
// Future<void> _loadData(BuildContext context, bool reload) async {
// String _languageCode = Provider.of<LocalizationProvider>(context, listen: false).locale.countryCode;
// await Provider.of<BrandProvider>(context, listen: false).getBrandList(reload, context);
// await Provider.of<ProductProvider>(context, listen: false).getLatestProductList('1', context, _languageCode, reload: reload);
//
//
//
// }
#override
Widget build(BuildContext context) {
// _loadData(context, false);
return Scaffold(
backgroundColor: ColorResources.getHomeBg(context),
resizeToAvoidBottomInset: false,
appBar: AppBar(
backgroundColor: Provider.of<ThemeProvider>(context).darkTheme
? Colors.black
: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(5),
bottomLeft: Radius.circular(5))),
leading: IconButton(
icon:
Icon(Icons.arrow_back_ios, size: 20, color: ColorResources.WHITE),
onPressed: () => Navigator.of(context).pop(),
),
title: Text(
productType == ProductType.FEATURED_PRODUCT
? 'Featured Product'
: 'Latest Product',
style: titilliumRegular.copyWith(
fontSize: 20, color: ColorResources.WHITE)),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (c) => SearchFilterBottomSheet()),
icon: const Icon(Icons.filter_list),
label: const Text('Filter'),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
body: SafeArea(
child: RefreshIndicator(
backgroundColor: Theme.of(context).primaryColor,
onRefresh: () async {
// await _loadData(context, true);
return true;
},
child: CustomScrollView(
controller: _scrollController,
slivers: [
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.all(Dimensions.PADDING_SIZE_SMALL),
child: ProductView(
isHomePage: false,
productType: productType,
scrollController: _scrollController),
),
),
],
),
),
),
);
}
}
The exception I'm getting is
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by gesture ═══════════════════════════════════════════
The getter 'iterator' was called on null.
Receiver: null
Tried calling: iterator
I am trying to show two future builders with gridview in the column widget, but it is showing me one future builder of the department and not showing the other future builder when scrolling it. how to show the future builder of hot product? it will be helpful for me
import 'dart:convert';
import 'package:apipractice/Models/Category_model.dart';
import 'package:apipractice/Models/Department_model.dart';
import 'package:apipractice/Models/HotProduct_model.dart';
import 'package:apipractice/Screens/Department.dart';
import 'package:apipractice/Screens/cart.dart';
import 'package:apipractice/Screens/categorry.dart';
import 'package:apipractice/Screens/products.dart';
import 'package:apipractice/Screens/selected_Category.dart';
import 'package:apipractice/Screens/subCategory.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
Future<HotProductModel> getHotProducts() async {
var data = jsonDecode(response.body);
if (response.statusCode == 200) {
return HotProductModel.fromJson(data[0]);
} else {
throw Exception('Failed to load album');
}
}
List images = [
"assets/Image1.jpeg",
"assets/Image2.jpeg",
"assets/Image3.jpeg",
"assets/Image4.jpeg",
"assets/Image5.jpeg",
"assets/Image6.jpeg",
];
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
child: ListTile(
leading: CircleAvatar(
child: Image(image: AssetImage("images/user.png")),
radius: 25,
),
title: Text(
"Username",
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text("abcuser#gmail.com"),
),
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Show Product'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Products()),
);
},
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Show Category'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Categorry()),
);
},
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Department'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Department()),
);
},
),
],
),
),
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 24, 119, 197),
title: Text("Dubai Super Store"),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => Cart()),
),
);
},
icon: Icon(Icons.shopping_cart))
],
),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: EdgeInsets.all(10),
height: 35,
width: double.infinity,
child: TextField(
decoration: InputDecoration(
hoverColor: Colors.blue,
prefixIconColor: Colors.blue,
labelText: "Search Product",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
),
Text(
"Note: Free Delivery Above Rs.2000",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red.shade700,
fontSize: 17),
),
Container(
height: 200,
width: double.infinity,
child: CarouselSlider.builder(
itemCount: images.length,
options: CarouselOptions(
height: 400,
viewportFraction: 1,
autoPlay: true,
),
itemBuilder: (context, index, realindex) {
final urlImages = images[index];
return buildImage(urlImages, index);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Categorry()),
);
},
child: Image(
height: 70,
width: 70,
image: AssetImage("assets/Categories.jpeg"),
),
),
Text("Categories")
],
),
),
Container(
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SubCategory()),
);
},
child: Image(
height: 70,
width: 70,
image: AssetImage("assets/SubCategory.jpeg")),
),
Text("Sub Category")
],
),
)
],
),
SizedBox(height: 20),
Text(
"Department",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: Color.fromARGB(255, 16, 113, 192)),
),
FutureBuilder<DepartmentModel>(
future: getDepartment(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: snapshot.data!.sKUDepartmentDetail!.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
var fetchid =
"${snapshot.data!.sKUDepartmentDetail![index].sKUDeptId}";
fetchCategory = fetchid;
setState(() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SelectedCategory()),
);
});
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
),
elevation: 10.0,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
child: Stack(children: [
CachedNetworkImage(
imageUrl: snapshot
.data!
.sKUDepartmentDetail![index]
.imageUrl1!,
height: 150,
width: 200,
fit: BoxFit.fitWidth,
errorWidget: (context, url, error) {
return Image(
image: AssetImage(
"assets/placeholder.jpg"));
},
),
]),
),
Text(
snapshot
.data!.sKUDepartmentDetail![index].name!,
style: TextStyle(fontWeight: FontWeight.bold),
)
],
),
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
// SizedBox(height: 20),
Text(
"Hot Product",
style: TextStyle(fontSize: 20),
),
FutureBuilder<HotProductModel>(
future: getHotProducts(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data!.productDetail!.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 3,
offset: Offset(1.0, 1.0),
)
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CachedNetworkImage(
imageUrl: snapshot.data!.productDetail![index]
.sKUImageURL1!,
height:
MediaQuery.of(context).size.height * 0.12,
width: double.infinity,
fit: BoxFit.fitWidth,
errorWidget: (context, url, error) {
return Image(
image: AssetImage(
"assets/placeholder.jpg"));
},
),
SizedBox(
height: 10,
),
Text(
"${snapshot.data!.productDetail![index].sKUName!}"),
Text(
"Rs: ${snapshot.data!.productDetail![index].salePrice!}",
style: TextStyle(
color: Colors.blue,
fontSize: 20,
fontWeight: FontWeight.bold),
),
Text(
"Rs: ${snapshot.data!.productDetail![index].retailPrice!}",
style: TextStyle(
decoration: TextDecoration.lineThrough,
color: Colors.red),
),
ElevatedButton(
onPressed: () {
var product = snapshot
.data!.productDetail![index].sKUId;
if (cartList.contains(product)) {
print("already exist");
} else {
cartList.add({
"Id": snapshot
.data!.productDetail![index].sKUId
});
}
},
child: Text("Add to Cart"))
],
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return CircularProgressIndicator();
}
})
],
),
),
);
}
This is the output of the code
[![output image][1]][1]
The problem is solved it is only not showing because of screen navigation bar now its fine
i am working with PageView but if i swipe to change it will change the page But if i put onPageChanged to setState for me to get to current index it will not change the page.
here is my code
int _indicatorsPages = 0;
final PageController controller =
PageController(initialPage: 0);
change(int page) {
setState(() {
_indicatorsPages = page;
}); }
code from build
Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
leading: Row(
children: [
SizedBox(
width: 10,
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SettingsFMC(),
),
);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 1, blurRadius: 2,
offset: Offset(0, 3), // i change position of shadow
),
],
),
child: Center(
child: Icon(
FontAwesomeIcons.slidersH,
size: 20,
color: Colors.black,
)),
),
),
],
),
elevation: 0,
backgroundColor: Colors.transparent,
actions: [
GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Actitvities(),
),
);
final doc = await firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.get();
if (doc.docs.isNotEmpty) {
firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.get()
.then((value) {
value.docs.forEach((doc) {
doc.reference.update({'seen': true});
});
});
}
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 1, blurRadius: 2,
offset: Offset(0, 3), // i change position of shadow
),
],
),
child: StreamBuilder(
stream: firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.where('seen', isEqualTo: false)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
));
}
if (snapshot.data.docs.isEmpty) {
return Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
));
}
return Badge(
animationType: BadgeAnimationType.scale,
badgeContent: Text('${snapshot.data.docs.length}'),
position: BadgePosition.topStart(),
showBadge: true,
child: Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
)),
);
}),
),
),
SizedBox(
width: 10,
),
],
),
extendBodyBehindAppBar: true,
body: userProfileLoading
? Center(
child: CircularProgressIndicator(),
)
: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height / 1.6,
child: StreamBuilder(
stream: firestore
.collection('Image')
.doc(widget.viewId)
.collection('Photos')
.orderBy('timestap', descending: false)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
int idx = 0;
List<Widget> list = [];
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
if (!snapshot.hasData) {
return Center(
child: Text("No image Found, Add images"),
);
} else {
if (snapshot.hasError) {
return Center(child: Text("fetch error"));
} else {
for (int i = 0;
i < snapshot.data.docs.length;
i++) {
// print('the lent of the document is $idx');
list.add(
FullScreenWidget(
child: Hero(
tag: "customTag",
child: Image.network(
snapshot.data.docs[idx]
.data()['picture'],
fit: BoxFit.cover,
),
),
),
);
idx++;
}
return Stack(
children: [
PageView(
key: _key,
scrollDirection: Axis.horizontal,
controller: controller,
onPageChanged: change,
// onImageChange: (pre, current) {
// print('this current : $current');
// setState(() {
// indicatorsPages = current;
// });
// },
// boxFit: BoxFit.cover,
// autoplay: false,
// animationCurve: Curves.fastOutSlowIn,
// animationDuration:
// Duration(milliseconds: 1000),
// dotIncreasedColor: Colors.orange,
// dotBgColor: Colors.transparent,
// dotPosition: DotPosition.bottomCenter,
// dotVerticalPadding:
// MediaQuery.of(context).size.height / 15,
//showIndicator: false,
// indicatorBgPadding: 7.0,
children: list,
),
Positioned(
right:
MediaQuery.of(context).size.width / 2,
bottom: 75,
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20),
color: Colors.white),
child: indicat.DotsIndicator(
dotsCount: list.length,
position: _indicatorsPages.toDouble(),
decorator: DotsDecorator(
color:
Colors.grey, // Inactive color
activeColor: Colors.black,
),
)),
)
],
);
}
}
}),
),
You are wrong. When you use pageView, it will call onPageChnaged function after page changed. If you want to change page programmatically, you should use pageView.animateToPage() function.
import 'package:flutter/material.dart';
class OnBoarding extends StatefulWidget {
#override
_OnBoardingState createState() => _OnBoardingState();
}
class _OnBoardingState extends State<OnBoarding> {
PageController controller;
int currentIndex = 0;
#override
void initState() {
controller = PageController();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent[200],
body: Stack(
children: [
PageView(
onPageChanged: onchahged,
controller: controller,
children: [
Container(
child: Image.asset('assets/fierceninja.png'),
),
Container(
child: Image.asset('assets/ninja.png'),
),
Container(
child: Image.asset('assets/ninjahead.jpg'),
),
],
),
],
),
);
}
onchahged(int index) {
setState(() {
currentIndex = index;
});
}
}
Here's a complete example.
import 'package:flutter_event_app/constant/color.dart';
import 'package:flutter_event_app/network/models/categories.dart';
import 'package:flutter_event_app/network/models/event_model.dart';
import 'package:flutter_event_app/network/models/time.dart';
import 'package:flutter_event_app/network/services/event_api.dart';
import 'package:flutter_event_app/pages/event_detail_page.dart';
import 'package:flutter_event_app/pages/search/home_search.dart';
import 'package:flutter_event_app/widgets/event_card.dart';
import 'package:flutter_event_app/widgets/no_events.dart';
import 'package:flutter_event_app/widgets/onload.dart';
class SelectedCategory extends StatefulWidget {
// SelectedCategory(Categories categories);
final Categories categories;
final Time time;
SelectedCategory(this.categories, [this.time]);
#override
_SelectedCategoryState createState() => _SelectedCategoryState();
}
class _SelectedCategoryState extends State<SelectedCategory> {
Categories categories;
Time timing;
String timeselect;
// Event event;
void viewEventDetail(Events event) {
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 300),
pageBuilder: (BuildContext context, animation, __) {
return FadeTransition(
opacity: animation,
child: EventDetailPage(event),
);
},
),
);
}
bool isLoading = false;
List<Events> upcomingEvents;
List categorizedupcomingEvents = [];
List categorizedPaidupcomingEvents = [];
List categorizedFreeupcomingEvents = [];
#override
void initState() {
_fetchData();
categories = widget.categories;
timing = widget.time;
// print(timing.id);
super.initState();
}
Future _fetchData() async {
setState(() => isLoading = true);
upcomingEvents = await getEventss();
categorizedupcomingEvents = upcomingEvents
.where((category) => category.category == categories.id)
.toList();
categorizedPaidupcomingEvents = categorizedupcomingEvents
.where((paid) => paid.is_paid == true)
.toList();
categorizedFreeupcomingEvents = categorizedupcomingEvents
.where((free) => free.is_paid == false)
.toList();
setState(() => isLoading = false);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(
MediaQuery.of(context).size.height / 9.5,
),
child: AppBar(
title: Text(categories.categoryName),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.sort,
),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
showFilterByTimeDialog(context);
// )
// );
}),
IconButton(
icon: Icon(
Icons.more_vert,
),
onPressed: () {})
],
bottom: TabBar(
tabs: [
Text('All'),
Text('Paid'),
Text('Free'),
],
),
),
),
body: TabBarView(
children: <Widget>[
// All
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount: categorizedupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Paid
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedPaidupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedPaidupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedPaidupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Free
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedFreeupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedFreeupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedFreeupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
],
),
));
}
void showFilterByTimeDialog(BuildContext context) {
Dialog fancyDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SingleChildScrollView(
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.5,
// alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
// color: Colors.greenAccent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
),
),
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.05,
child: Text(
"Time",
style: TextStyle(
color: Colors.deepPurple,
fontSize: 20,
fontWeight: FontWeight.w600),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
// color: Colors.red,
width: double.infinity,
child: ListView.builder(
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
itemCount: times.length,
itemBuilder: (context, int index) {
Time time = times[index];
return RaisedButton(
onPressed: () {
debugPrint('I am Awesome');
},
textColor: Colors.red,
// color: Colors.blueAccent,
disabledColor: Colors.grey,
disabledTextColor: Colors.white,
highlightColor: Colors.orangeAccent,
child: Text(time.name),
);
}),
),
),
),
],
),
),
),
);
showDialog(
context: context, builder: (BuildContext context) => fancyDialog);
}
}
Within the same page I have a dialog box as shown below
On the method showFilterByTimeDialog where I select an item and have to go back to the same page below the dialogue .Am still learning flutter and my issue is I need help when I select an item from the dialogue box,i refresh the same page and display a new filtered lst from the current list displayed on that page with a condition of the item selected from the dialogue box.
i need help to build a quiz app with flutter,
i use firestore for my data, and i want to add a multi choices question, so when a user tap on one choice, this one is highlighted, like this example
(i use this gif from another question, because i didn't know how to explain)
this is what i have for now
this is my code :
Widget _buildListItem(BuildContext context, DocumentSnapshot document) {
return ListTile(
title: Container(
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.fromLTRB(210, 0.0, 0.0, 0.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.pink[800], // set border color
width: 3.0), // set border width
borderRadius: BorderRadius.all(
Radius.circular(10.0)), // set rounded corner radius
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black,
offset: Offset(0.5, 1))
] // make rounded corner of border
),
child: Row(
children: <Widget>[
Container(
child: Text(
document['rep'],
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
)
]
),
),
onTap: () {
Firestore.instance.runTransaction(
(transaction) async {
DocumentSnapshot freshSnap =
await transaction.get(document.reference);
await transaction.update(freshSnap.reference, {
'votes': freshSnap['votes'] + 1,
});
});
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: StreamBuilder(
stream: Firestore.instance.collection('questions').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('Loading ...');
return ListView.builder(
padding: EdgeInsets.fromLTRB(50.0, 300.0, 50.0, 0.0),
itemExtent: 100.0,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_buildListItem(context, snapshot.data.documents[index]),
);
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => new Home()));
},
child: Text("Home"),
),
);
}
thank you so much !
Wrap list tile with colored container :
itemBuilder: (context, index){
return Container(
color: isSelected[index] ? Colors.blue : null,
child: ListTile(title:'test'),
);
}
Change selection status when item is taped.
ListTile(
title: Text('test'),
selected: isSelected[index],
onTap: () {
setState(() {
isSelected[index] = !isSelected[index];
});
},
),
final List<bool> isSelected;
Try it on DartPad