I'm currently create chat in flutter and get the last messages , I want to handle when scrolling to top to load more messages how can I create that ?
CodePudding user response:
If you want to implement swipe to refresh kind of behaviour, you can use RefreshIndicator. See the example and usage in this YouTube video.
All you have to do is wrap your scrollable widget (it can be ListView
or SingleChildScrollView
) in a RefreshIndicator
and provide onRefresh
method:
class PullToRefresh extends StatelessWidget {
const PullToRefresh({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: _refreshData,
child: ListView.builder( // or SingleChildScrollView
...
),
);
}
Future<void> _refreshData() async {
// load more items
}
}
CodePudding user response:
You can use https://pub.dev/packages/infinite_scroll_pagination to development function load more. And you can set listview reverse = true.
CodePudding user response:
ListView reverse: true
displays the List from the bottom to the top.
and this is how to implement pagination
class HomeState extends State<Home> {
ScrollController? controller;
final _all = <WordPair>[];
final _saved = Set<WordPair>();
final _biggerFont = const TextStyle(fontSize: 18.0);
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
bool isLoading = false;
@override
void initState() {
super.initState();
_all.addAll(generateWordPairs().take(20));
controller = ScrollController()..addListener(_scrollListener);
}
@override
void dispose() {
super.dispose();
controller?.dispose();
}
void _scrollListener() {
if (controller!.position.pixels == controller!.position.maxScrollExtent) {
startLoader();
}
}
void startLoader() {
setState(() {
isLoading = !isLoading;
fetchData();
});
}
fetchData() async {
var _duration = const Duration(seconds: 2);
return Timer(_duration, onResponse);
}
void onResponse() {
setState(() {
isLoading = !isLoading;
_all.addAll(generateWordPairs().take(20));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: const Text(
"List load more example",
style: TextStyle(color: Colors.white),
),
),
body: Stack(
children: <Widget>[
_buildSuggestions(),
_loader(),
],
),
);
}
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return Column(
children: <Widget>[
ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.check : Icons.check,
color: alreadySaved ? Colors.deepOrange : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
),
const Divider(),
],
);
}
Widget _buildSuggestions() {
return ListView.builder(
reverse: true,
padding: const EdgeInsets.all(16.0),
controller: controller,
itemCount: _all.length,
itemBuilder: (context, i) {
return _buildRow(_all[i]);
});
}
Widget _loader() {
return isLoading
? const Align(
child: SizedBox(
width: 70.0,
height: 70.0,
child: Padding(
padding: EdgeInsets.all(5.0),
child: Center(child: CircularProgressIndicator())),
),
alignment: FractionalOffset.topCenter,
)
: const SizedBox(
width: 0.0,
height: 0.0,
);
}
}
You can get full code from Github HERE