This is a continuation for the first post Flutter BLoC & GraphQL
I will modify the code in ./lib/screens/home/home_screen.dart
to add pull-to-refresh functionality.
Make it Stateful
Make the HomeScreen
class extends StatefulWidget
Converting a StatelessWidget
to StatefulWidget
is just a click away
thanks to the Flutter extension for IntelliJ
& VSCode.
Track the list of posts
Create a variable in the _HomeScreenState
class to hold the list of posts,
List<GetPosts$Query$Post> _posts = [];
.
Add BlocListener
The BlocListener
is different from BlocBuilder
;that we used in the previous post;
in the BlocListener
we have
listener
function which will be called once and only once per state change.
In the listener
function we will check if the state is HomeLoadedState
then
set the _posts
variable to state.posts
.
Pull to refresh
Or sometimes called swipe to refresh is as simple as wrapping ListView.builder
with
RefreshIndicator
and in onRefresh
function we will reset _posts
and add a new action
to reload BlocProvider.of<HomeBloc>(context).add(HomeLoadEvent());
.
Final code
Link to full code up to here https://github.com/agent3bood/Flutter-architecture-app/tree/pull-to-refresh
./screens/home/home_screen.dart
import 'package:architecture_app/graphql/graphql_api.graphql.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'bloc.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<GetPosts$Query$Post> _posts = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Architecture demo'),
),
body: Container(
child: BlocListener<HomeBloc, HomeState>(
listener: (context, state) {
if (state is HomeLoadedState) {
_posts.addAll(state.posts);
}
},
child: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
if (state is HomeLoadingState) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else if (state is HomeLoadedState) {
return RefreshIndicator(
onRefresh: () async {
_posts = [];
BlocProvider.of<HomeBloc>(context).add(
HomeLoadEvent(),
);
},
child: ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return ListTile(
key: Key(post.id),
title: Text(post.title),
subtitle: Text('By: ${post.author.name}'),
);
},
),
);
} else {
return Container(
child: Center(
child: Text('You have an error'),
),
);
}
},
),
),
),
);
}
}