How to add RefreshIndicator with FutureBuilder on Flutter - android

I need to implement the pull to refresh action, on a future builder using refresh indicator widget. First of all, i know there are multiple threads on this topic. But I still couldn't. Here are my codes on the subject:
final QuerySnapshot<Map<String, dynamic>> querySnapshot =
snapshot.data as QuerySnapshot<Map<String, dynamic>>;
return ListView(
physics: const BouncingScrollPhysics(),
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 28.8, bottom: 16.8),
height: 714.8,
child: FutureBuilder<List<FirabaseWeatherModel>>(
future: chnageList(querySnapshot),
builder: (BuildContext context,
AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
ListView.builder(
itemCount: firabseModelList.length,
padding:
const EdgeInsets.only(left: 28.8, right: 12),
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
height: 214.8,
width: 188.4,
margin: const EdgeInsets.only(
right: 16.8, bottom: 50),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
querySnapshot.docs[index]
.data()['image'],
maxHeight: 200,
maxWidth: 200),
),),
child: Stack(
children: <Widget>[
GestureDetector(
onTap: () => gotoPage(querySnapshot
.docs[index]
.data()['title'])),
],),);},);
} else if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);}
return ListView.builder(
itemCount: firabseModelList.length,
padding: const EdgeInsets.only(left: 28.8, right: 12),
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
height: 214.8,
width: 188.4,
margin: const EdgeInsets.only(
right: 16.8, bottom: 50),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
querySnapshot.docs[index].data()['image'],
maxHeight: 200,
maxWidth: 200),
),),
child: Stack(
children: <Widget>[
GestureDetector(
onTap: () => gotoPage(querySnapshot
.docs[index]
.data()['title'])),
Positioned(
child: ClipRRect(
child: Container(
height: 80,
alignment: Alignment.centerLeft,
child: Column(
children: [
Align(
child: Container(
alignment: Alignment.topCenter,
child: Text(
querySnapshot.docs[index]
.data()['tr'],
style: const TextStyle(
fontSize: 15,
),),),),
Row(
children: <Widget>[
Expanded(
child: getImage(
querySnapshot.docs[index]
.data()['zposition1']
.toString(),
150),
),],),],),),),),],),);},);}),),],);
I have uploaded all the code in case you want to try it yourself using all the codes. Where should i use these refresh indicator codes:
RefreshIndicator(
onRefresh: () {},),

add key
GlobalKey _key = GlobalKey();
Then assign the previous key to the top widget
return RefreshIndicator(
onRefresh: _refresh,
child: Container(
key: _key,
child: ListView(
physics: AlwaysScrollableScrollPhysics(),
children: [
// do your stuff
],
),
),
);
Then refresh function, as you should update the key
Future<void> _refresh() async {
if (mounted) {
_key = GlobalKey();
setState(() {});
}
Future.value(null);
}

Related

How to get dynamically FormFiledWidget values on button click in flutter

I want to get all the input field values from the listTilewidget on the button click how can I do this?
I have provided the image as well which is here...
we can easily do this with this javascript but is there any way to achieve this type of functionality?
I looked for the solution to this problem on the internet but did not find any solution for that problem.
FutureBuilder(
future: SupervisorAttendanceServices.getAttendancesDetailsList(
widget.attendanceId),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var data = snapshot.data['hamal'];
return ListView.builder(
itemCount: data.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
width: 10,
height: 50,
),
const Icon(FeatherIcons.user),
const SizedBox(
width: 20,
),
Text(
data[index]['worker_name'],
style: const TextStyle(fontSize: 18),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
SizedBox(
width: 150,
height: 50,
child: TextFormField(
cursorHeight: 25,
controller: _mainWagesController,
// onChanged: _onChangeHandler,
// initialValue: _mainWagesController.text,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: "Wages",
prefixIcon: Icon(
Icons.wallet,
color: Colors.blue,
)),
)),
],
)
]),
),
);
});
} else if (snapshot.hasError) {
return const Center(
child: Text("Something went wrong !"),
);
} else {
return const Center(child: LinearProgressIndicator());
}
},
),

Flutter DraggableScrollableSheet Lock One Part on top

I Had Question For how create Scroll List Like this
Flutter Scroll List Over Header
According to the answers given, I used DraggableScrollableSheet for implementing this scroll view
but now i have new problem
The Result is here:
now I need to when im scrolling the top Child Stay On Top, like a header
how can do this?
Here is my Code
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
AppController appController = Provider.of<AppController>(context);
HomeController homeController = Provider.of<HomeController>(context);
String selectedCategory = homeController.selectedCategory;
return SafeArea(
child: Container(
//height: 450,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/home_header.png'),
alignment: Alignment.topCenter,
)),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
flexibleSpace: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ChiscoAppbar(
icon: MENU,
iconAlignment: Alignment.centerLeft,
title: 'خانه',
onClick: () {
Navigator.pushNamed(context, '/account');
},
),
),
),
backgroundColor: Colors.transparent,
body: Stack(
children: [
Positioned(
child: Container(
color: Colors.transparent,
height: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Expanded(
flex: 3,
child: Align(
alignment: Alignment.center,
child: ChiscoText(
text: 'دستگاه‌های هوشمند چیسکو',
fontWeight: FontWeight.w500,
textColor: Colors.white,
fontSize: 16,
)),
),
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
HeaderItem(
titleText: 'کنترلر',
icon: COOLER,
counterText: '2',
),
HeaderItem(
titleText: 'سه راهی',
icon: SOCKET,
counterText: '2',
)
],
),
)),
],
),
),
),
Positioned(
child: DraggableScrollableSheet(
expand: true,
minChildSize: 0.70,
maxChildSize: 0.95,
initialChildSize: 0.70,
builder: (context, scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Container(
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25))),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListHandlerView(),
Container(
margin: const EdgeInsets.fromLTRB(20, 8, 20, 10),
height: 30,
child: ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: appController
.listOfDevicesCategory.length,
scrollDirection: Axis.horizontal,
primary: true,
addSemanticIndexes: false,
itemBuilder: (context, index) {
String category = appController
.listOfDevicesCategory[index];
return CategoryListItem(
isSelected: selectedCategory == category,
category: category,
);
}),
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
],
),
),
);
},
),
)
],
),
floatingActionButton: Container(
margin: const EdgeInsets.only(bottom: 16),
child: const ChiscoSpeedDial()),
floatingActionButtonLocation:
FloatingActionButtonLocation.startDocked,
),
),
);
}
}
I think it is better to use bottom from SliverAppBar. Run below widget to see the result
class DAX extends StatefulWidget {
DAX({Key? key}) : super(key: key);
#override
State<DAX> createState() => _DAXState();
}
class _DAXState extends State<DAX> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 200,
pinned: true,
backgroundColor: Colors.blue,
elevation: 0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(60),
child: ColoredBox(
color: Colors.blue,
child: Container(
clipBehavior: Clip.hardEdge,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
color: Colors.white,
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
12,
(index) => Chip(
label: Text("chip $index"),
),
),
),
),
),
)),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
alignment: Alignment.center,
height: 100,
child: Text("$index"),
),
),
),
],
),
),
);
}
}

how to flutter getx make a 13 different controller with search function

class IlacProductController extends GetxController {
final IlacProductRepo ilacProductRepo;
IlacProductController({required this.ilacProductRepo});
List<dynamic> _ilacproductList = [];
List<dynamic> get ilacproductList => _ilacproductList;
bool _isLoaded = false;
bool get isLoaded => _isLoaded ;
Future<void> getIlacProductList() async {
Response response = await ilacProductRepo.getIlacProductList();
if (response.statusCode == 200) {
print("got ilaç");
_ilacproductList = [];
_ilacproductList.addAll(Product.fromJson(response.body).products);
_isLoaded=true;
update();
} else {return print("something wrong");}
}
}
I have 13 different controller codes similar to the above code, each representing a different category
#override
Widget buildResults(BuildContext context) {
return GetBuilder<HalkSagligiProductController>(builder: (allProduct) {
return allProduct.isLoaded
? ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: allProduct.halksagligiproductList.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Get.toNamed(RouteHelper.getHalkProduct(index));
},
child: Container(
margin: EdgeInsets.only(
left: Dimensions.width20,
right: Dimensions.width10,
bottom: Dimensions.height15),
child: Row(
children: [
//image section
Container(
width: Dimensions.listViewImgSize,
height: Dimensions.listViewImgSize,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
Dimensions.radius20),
color: Colors.white38,
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(AppConstans
.BASE_URL +
AppConstans.UPLOAD_URL +
allProduct
.halksagligiproductList[index]
.img!))),
),
//text section
Expanded(
child: Container(
height: Dimensions.listViewTextContSize,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(
Dimensions.radius20),
bottomRight: Radius.circular(
Dimensions.radius20)),
color: Colors.white),
child: Padding(
padding: EdgeInsets.only(
left: Dimensions.width10,
right: Dimensions.width10),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
BigText(
text: allProduct
.halksagligiproductList[index]
.name!,
),
SizedBox(
height: Dimensions.height10,
),
ExpandableProductText(
text: allProduct
.halksagligiproductList[index]
.description!),
SizedBox(
height: Dimensions.height10,
),
],
),
),
),
)
],
)),
);
})
: const CircularProgressIndicator(
color: AppColor.mainColor,
);
});
}
In the above code, I am pulling the image name and description with getx.
My question is: How can I search 13 different controllers with Getx, both by name and by the words in the description, on the search screen?
final searchController = Get.find<SearchController>();
You can use multiple time, this function in different screens.
Declare final ilacProductController = Get.put(IlacProductController());
into the screen and use object ilacProductController for access.

How to make a separate view if there is no item in Dart Flutter listTile?

I have an application:
The listTile items here come from the database.
Codes:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
Calling items from database:
dynamic listUpload() async {
final prefences = await SharedPreferences.getInstance();
final getTests = prefences.getStringList("tests"); // get item
debugPrint(getTests.toString());
return Future.value(getTests);
}
If there is no data in the database, I want the listTile to say "not found" in its footprint.
For example, I want to make the system in the picture above. You already understand the system, if there is no data from the database, listTile will say not found in its place.
The listTile in my app looks like this when there is no data:
How can I do that? Thanks in advance for the help.
I think you can just have a check for empty data.
if (!snapshot.hasData){
return myEmptyWidget
}
please try:
items.isEmpty ? const SizedBox() : View(),
Code:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: items.isEmpty ? const SizedBox() : ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
You're facing this issue because you're not fully using the power of the FutureBuilder !
It'll "emit" states during Load and Success/Error. Whenever a state is emitted, it'll redraw the widget.
Therefore, you can return a Widget matching every state of your FutureBuilder like this
...
child: FutureBuilder(
future: listUpload(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState ==
ConnectionState.waiting) {
return YourLoaderWidget();
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
if (items.isEmpty) {
return YourEmptyWidget();
} else {
return YourScrollBar();
}
} else {
return YourErrorWidget();
}
...

The method 'MaterialPageRoute' isn't defined

I have been learning to make an app in flutter for 2 weeks using flutter documentation. Today, I have come to this problem regarding Navigator.push(). This was working fine, but it is not after I restart my laptop. And I can't find a solution, I tried
flutter clean
reinstalled flutter and dart plugins
These solutions didn't help.
Code:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_foodybite/screens/trending.dart';
import 'package:flutter_foodybite/util/categories.dart';
import 'package:flutter_foodybite/util/friends.dart';
import 'package:flutter_foodybite/util/restaurants.dart';
import 'package:flutter_foodybite/widgets/category_item.dart';
import 'package:flutter_foodybite/widgets/search_card.dart';
import 'package:flutter_foodybite/widgets/slide_item.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: buildSearchBar(context),
body: Padding(
padding: EdgeInsets.fromLTRB(10.0, 0, 10.0, 0),
child: ListView(
children: <Widget>[
SizedBox(height: 20.0),
buildCategoryRow('Trending Restaurants', context),
SizedBox(height: 10.0),
buildRestaurantList(context),
SizedBox(height: 10.0),
buildCategoryRow('Category', context),
SizedBox(height: 10.0),
buildCategoryList(context),
SizedBox(height: 20.0),
buildCategoryRow('Friends', context),
SizedBox(height: 10.0),
buildFriendsList(),
SizedBox(height: 30.0),
],
),
),
);
}
buildCategoryRow(String category, BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"$category",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w800,
),
),
FlatButton(
child: Text(
"Trending",
style: TextStyle(
color: Theme.of(context).accentColor,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Trending();
},
),
);
},
),
],
);
}
buildSearchBar(BuildContext context) {
return PreferredSize(
child: Padding(
padding: EdgeInsets.only(
top: Platform.isAndroid ? 30.0 : 50.0,
left: 10.0,
right: 10.0,
),
child: SearchCard(),
),
preferredSize: Size(
MediaQuery.of(context).size.width,
60.0,
),
);
}
buildCategoryList(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 6,
child: ListView.builder(
primary: false,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: categories == null ? 0 : categories.length,
itemBuilder: (BuildContext context, int index) {
Map cat = categories[index];
return CategoryItem(
cat: cat,
);
},
),
);
}
buildRestaurantList(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 2.4,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
primary: false,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: restaurants == null ? 0 : restaurants.length,
itemBuilder: (BuildContext context, int index) {
Map restaurant = restaurants[index];
return Padding(
padding: EdgeInsets.only(right: 10.0),
child: SlideItem(
img: restaurant["img"],
title: restaurant["title"],
address: restaurant["address"],
rating: restaurant["rating"],
),
);
},
),
);
}
buildFriendsList() {
return Container(
height: 50.0,
child: ListView.builder(
primary: false,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: friends == null ? 0 : friends.length,
itemBuilder: (BuildContext context, int index) {
String img = friends[index];
return Padding(
padding: EdgeInsets.only(right: 5.0),
child: CircleAvatar(
backgroundImage: AssetImage(
img,
),
radius: 25.0,
),
);
},
),
);
}
}
Please have a look at the attached picture below for the highlighted error.
Here is error encountered
This is an error
Try this
flutter upgrade --force
You should use like this
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (BuildContext context) => Trending(),
),
);

Categories

Resources