// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'package:flutter/material.dart'; import '../../gallery/demo.dart'; enum IndicatorType { overscroll, refresh } class OverscrollDemo extends StatefulWidget { const OverscrollDemo({super.key}); static const String routeName = '/material/overscroll'; @override OverscrollDemoState createState() => OverscrollDemoState(); } class OverscrollDemoState extends State { final GlobalKey _refreshIndicatorKey = GlobalKey(); static final List _items = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', ]; Future _handleRefresh() { final completer = Completer(); Timer(const Duration(seconds: 3), () => completer.complete()); return completer.future.then((_) { if (!mounted) { return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('Refresh complete'), action: SnackBarAction( label: 'RETRY', onPressed: () { _refreshIndicatorKey.currentState!.show(); }, ), ), ); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Pull to refresh'), actions: [ MaterialDemoDocumentationButton(OverscrollDemo.routeName), IconButton( icon: const Icon(Icons.refresh), tooltip: 'Refresh', onPressed: () { _refreshIndicatorKey.currentState!.show(); }, ), ], ), body: RefreshIndicator( key: _refreshIndicatorKey, onRefresh: _handleRefresh, child: Scrollbar( child: ListView.builder( primary: true, padding: kMaterialListPadding, itemCount: _items.length, itemBuilder: (BuildContext context, int index) { final String item = _items[index]; return ListTile( isThreeLine: true, leading: CircleAvatar(child: Text(item)), title: Text('This item represents $item.'), subtitle: const Text( 'Even more additional list item information appears on line three.', ), ); }, ), ), ), ); } }