the circular progress indicator dont disappear after loading the data .
this is my code where im using the progress indicator
and when i reach the end of the grid view it should load the other data but
the progress indicator makes the same thing it loads and dont disappear after getting data .
i tried to make a boolean isLoading and tried to change it true or false but couldnt find the place where i can do this
int pageNumber = 1;
String filterName = '';
class ShowsListDesign extends StatefulWidget {
@override
_ShowsListDesignState createState() => _ShowsListDesignState();
}
class _ShowsListDesignState extends State<ShowsListDesign> {
ScrollController controller = ScrollController();
ServicesClass service = ServicesClass();
bool isLoading = false;
@override
void initState() {
controller.addListener(listenScrolling);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: service.getFilms('posts/$pageNumber/$filterName'),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
GridView.builder(
itemCount: snapshot.data.length,
gridDelegate: const
SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250,
crossAxisSpacing: 24,
mainAxisSpacing: 24,
childAspectRatio: (3 / 5),
),
controller: controller,
itemBuilder: (context, index) {
return FilmsCard(
image: snapshot.data[index]['thumbnailUrl'],
title: snapshot.data[index]['title'],
year: snapshot.data[index]['year'],
);
},
),
FloatingActionButton(
onPressed: () {
scrollUp();
},
elevation: 24,
backgroundColor: PRIMARY,
child: const Text(
'Scroll Up',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
),
),
),
],
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
);
}
void scrollUp() {
const double start = 0;
controller.animateTo(start,
duration: const Duration(seconds: 1, milliseconds: 50),
curve: Curves.easeIn);
}
void listenScrolling() {
if (controller.position.atEdge) {
final isTop = controller.position.pixels == 0;
if (isTop) {
} else {
setState(() {
pageNumber ;
ShowsListDesign();
});
}
}
}
}
CodePudding user response:
It is possible to get errors or no data on future, it will be better with handling those states.
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
return Stack(
alignment: Alignment.bottomCenter,
children: [...],
);
} else if (!snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
return const Text("couldn't find any data");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return const Text(" any other");
}
},
More about FutureBuilder class.
CodePudding user response:
You can't use FutureBuilder if it's not a one page load. Try this: (I don't understand your scrolling mechanism though), also call super.initState when you override
String filterName = '';
class ShowsListDesign extends StatefulWidget {
@override
_ShowsListDesignState createState() => _ShowsListDesignState();
}
class _ShowsListDesignState extends State<ShowsListDesign> {
ScrollController controller = ScrollController();
ServicesClass service = ServicesClass();
bool isLoading = false;
// New
int pageNumber = 1;
List? data;
Future<void> load() async {
setState(() {
isLoading = true;
});
data = await service.getFilms('posts/1/$filterName');
setState(() => isLoading = false);
}
@override
void initState() {
// Make sure you call super.initState() when you override
controller.addListener(listenScrolling);
super.initState();
load();
}
// Also call dispose to remove listener
@override
void dispose() {
controller.removeListener(listener);
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Builder(
builder: (BuildContext context) {
if (data != null) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
GridView.builder(
itemCount: data!.length,
gridDelegate: const
SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250,
crossAxisSpacing: 24,
mainAxisSpacing: 24,
childAspectRatio: (3 / 5),
),
controller: controller,
itemBuilder: (context, index) {
return FilmsCard(
image: data![index]['thumbnailUrl'],
title: data![index]['title'],
year: data![index]['year'],
);
},
),
FloatingActionButton(
onPressed: () {
scrollUp();
},
elevation: 24,
backgroundColor: PRIMARY,
child: const Text(
'Scroll Up',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
),
),
),
],
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
);
}
void scrollUp() {
const double start = 0;
controller.animateTo(start,
duration: const Duration(seconds: 1, milliseconds: 50),
curve: Curves.easeIn);
}
Future<void> listenScrolling() async {
// Change this depending on the scrolling works ?!
if (controller.position.pixels == controller.position.maxScrollExtent && data != null) {
List new_data = await service.getFilms('posts/${pageNumber 1}/$filterName');
data.addAll(new_data);
setState(() {
pageNumber ;
});
}
}
}