Added new constructor RefreshIndicator.noSpinner() (#152075)

This PR adds a new constructor to the RefreshIndicator's class, which is `noSpinner`.
The purpose of this new constructor is to create a RefreshIndicator that doesn't show a spinner when the user arms it by pulling.

The work is based on a partial that is here: https://github.com/flutter/flutter/pull/133507

I addressed the following issues reported in the PR above:
- in the example for `noSpinner`, arming the RefreshIndicator now shows a CircularProgressIndicator, instead of just printing text to the console;
- added a test for the new example;
- added a doc comment on the new constructor;

Fixes https://github.com/flutter/flutter/issues/132775
This commit is contained in:
Pavlo Kochylo
2024-08-23 22:37:24 +02:00
committed by GitHub
parent 5e194383af
commit a4b0d973fb
4 changed files with 360 additions and 91 deletions

View File

@@ -0,0 +1,95 @@
// 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 'package:flutter/material.dart';
/// Flutter code sample for [RefreshIndicator.noSpinner].
void main() => runApp(const RefreshIndicatorExampleApp());
class RefreshIndicatorExampleApp extends StatelessWidget {
const RefreshIndicatorExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: RefreshIndicatorExample(),
);
}
}
class RefreshIndicatorExample extends StatefulWidget {
const RefreshIndicatorExample({super.key});
@override
State<RefreshIndicatorExample> createState() => _RefreshIndicatorExampleState();
}
class _RefreshIndicatorExampleState extends State<RefreshIndicatorExample> {
bool _isRefreshing = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('RefreshIndicator.noSpinner Sample'),
),
body: Stack(
children: <Widget>[
RefreshIndicator.noSpinner(
// Callback function used by the app to listen to the
// status of the RefreshIndicator pull-down action.
onStatusChange: (RefreshIndicatorStatus? status) {
if (status == RefreshIndicatorStatus.done) {
setState(() {
_isRefreshing = false;
});
}
},
// Callback that gets called whenever the user pulls down to refresh.
onRefresh: () async {
// This can be also done in onStatusChange when the status is RefreshIndicatorStatus.refresh.
setState(() {
_isRefreshing = true;
});
// Replace this delay with the code to be executed during refresh
// and return asynchronous code.
return Future<void>.delayed(const Duration(seconds: 3));
},
child: CustomScrollView(
slivers: <Widget>[
SliverList.builder(
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return ListTile(
tileColor: Colors.green[100],
title: const Text('Pull down here'),
subtitle: const Text('A custom refresh indicator will be shown'),
);
}
)
],
),
),
// Shows an overlay with a CircularProgressIndicator when refreshing.
if (_isRefreshing)
ColoredBox(
color: Colors.black45,
child: Align(
child: CircularProgressIndicator(
color: Colors.purple[500],
strokeWidth: 10,
semanticsLabel: 'Circular progress indicator',
),
),
),
]
),
);
}
}

View File

@@ -0,0 +1,26 @@
// 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 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/refresh_indicator/refresh_indicator.2.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Pulling from scroll view triggers a refresh indicator which shows a CircularProgressIndicator', (WidgetTester tester) async {
await tester.pumpWidget(
const example.RefreshIndicatorExampleApp(),
);
// Pull the first item.
await tester.fling(find.text('Pull down here').first, const Offset(0.0, 300.0), 1000.0);
await tester.pump();
await tester.pump(const Duration(seconds: 1));
await tester.pump(const Duration(seconds: 1));
expect(find.byType(RefreshProgressIndicator), findsNothing);
expect(find.bySemanticsLabel('Circular progress indicator'), findsOneWidget);
await tester.pumpAndSettle(); // Advance pending time.
});
}