Update Material 3 LinearProgressIndicator for new visual style (#154817)

Related to [Update both `ProgressIndicator` for Material 3 redesign](https://github.com/flutter/flutter/issues/141340)

### Code sample

<details>
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool isRTL = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(

        body: Directionality(
          textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr,
          child: Center(
            child: Column(
              spacing: 2.0,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text('Default LinearProgressIndicator'),
                const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.45,
                  ),
                ),
                const Text('Default indefinite LinearProgressIndicator'),
                const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(),
                ),
                const Text('Updated height and border radius'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.25,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                  ),
                ),
                const Text('Updated stop indicator color and radius'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.74,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                    stopIndicatorColor: Theme.of(context).colorScheme.error,
                    stopIndicatorRadius: 32.0,
                  ),
                ),
                const Text('Track gap and stop indicator radius set to 0'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.50,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                    trackGap: 0,
                    stopIndicatorRadius: 0,
                  ),
                ),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton.extended(
          onPressed: () {
            setState(() {
              isRTL = !isRTL;
            });
          },
          label:  const Text('Toggle Direction'),
        ),
      ),
    );
  }
}
```

</details>

### Preview

<img width="824" alt="Screenshot 2024-09-09 at 13 53 10" src="https://github.com/user-attachments/assets/d12e56a5-f196-4011-8266-c7ab96be96b2">
This commit is contained in:
Taha Tesser
2024-10-30 20:14:11 +02:00
committed by GitHub
parent cf4a4b8162
commit b8dcb0c3c5
10 changed files with 754 additions and 93 deletions

View File

@@ -6,10 +6,10 @@ import 'package:flutter/material.dart';
/// Flutter code sample for [LinearProgressIndicator].
void main() => runApp(const ProgressIndicatorApp());
void main() => runApp(const ProgressIndicatorExampleApp());
class ProgressIndicatorApp extends StatelessWidget {
const ProgressIndicatorApp({super.key});
class ProgressIndicatorExampleApp extends StatelessWidget {
const ProgressIndicatorExampleApp({super.key});
@override
Widget build(BuildContext context) {
@@ -23,24 +23,26 @@ class ProgressIndicatorExample extends StatefulWidget {
const ProgressIndicatorExample({super.key});
@override
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
State<ProgressIndicatorExample> createState() =>
_ProgressIndicatorExampleState();
}
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample> with TickerProviderStateMixin {
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
with TickerProviderStateMixin {
late AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
setState(() {});
})
..repeat(reverse: true);
}
@override
@@ -55,16 +57,13 @@ class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample> wit
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
spacing: 16.0,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Linear progress indicator with a fixed color',
style: TextStyle(fontSize: 20),
),
LinearProgressIndicator(
value: controller.value,
semanticsLabel: 'Linear progress indicator',
),
const Text('Determinate LinearProgressIndicator'),
LinearProgressIndicator(value: controller.value),
const Text('Indeterminate LinearProgressIndicator'),
const LinearProgressIndicator(),
],
),
),

View File

@@ -6,16 +6,15 @@ import 'package:flutter/material.dart';
/// Flutter code sample for [LinearProgressIndicator].
void main() => runApp(const ProgressIndicatorApp());
void main() => runApp(const ProgressIndicatorExampleApp());
class ProgressIndicatorApp extends StatelessWidget {
const ProgressIndicatorApp({super.key});
class ProgressIndicatorExampleApp extends StatelessWidget {
const ProgressIndicatorExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4)),
home: const ProgressIndicatorExample(),
return const MaterialApp(
home: ProgressIndicatorExample(),
);
}
}
@@ -24,25 +23,27 @@ class ProgressIndicatorExample extends StatefulWidget {
const ProgressIndicatorExample({super.key});
@override
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
State<ProgressIndicatorExample> createState() =>
_ProgressIndicatorExampleState();
}
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample> with TickerProviderStateMixin {
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
with TickerProviderStateMixin {
late AnimationController controller;
bool determinate = false;
@override
void initState() {
super.initState();
controller = AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 2),
)..addListener(() {
setState(() {});
});
controller.repeat();
super.initState();
setState(() {});
})
..repeat(reverse: true);
}
@override
@@ -65,7 +66,7 @@ class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample> wit
),
const SizedBox(height: 30),
LinearProgressIndicator(
value: controller.value,
value: determinate ? controller.value : null,
semanticsLabel: 'Linear progress indicator',
),
const SizedBox(height: 10),
@@ -73,7 +74,7 @@ class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample> wit
children: <Widget>[
Expanded(
child: Text(
'determinate Mode',
'${determinate ? 'Determinate' : 'Indeterminate'} Mode',
style: Theme.of(context).textTheme.titleSmall,
),
),

View File

@@ -2,23 +2,39 @@
// 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/progress_indicator/linear_progress_indicator.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Finds LinearProgressIndicator', (WidgetTester tester) async {
testWidgets('Determinate and Indeterminate LinearProgressIndicators',
(WidgetTester tester) async {
await tester.pumpWidget(
const example.ProgressIndicatorApp(),
const example.ProgressIndicatorExampleApp(),
);
expect(
find.bySemanticsLabel('Linear progress indicator'),
findsOneWidget,
);
expect(find.text('Determinate LinearProgressIndicator'), findsOneWidget);
expect(find.text('Indeterminate LinearProgressIndicator'), findsOneWidget);
expect(find.byType(LinearProgressIndicator), findsNWidgets(2));
// Test if LinearProgressIndicator is animating.
// Test determinate LinearProgressIndicator.
LinearProgressIndicator determinateIndicator = tester.firstWidget(
find.byType(LinearProgressIndicator).first,
);
expect(determinateIndicator.value, equals(0.0));
// Advance the animation by 2 seconds.
await tester.pump(const Duration(seconds: 2));
expect(tester.hasRunningAnimations, isTrue);
determinateIndicator = tester.firstWidget(
find.byType(LinearProgressIndicator).first,
);
expect(determinateIndicator.value, equals(0.4));
// Test indeterminate LinearProgressIndicator.
final LinearProgressIndicator indeterminateIndicator = tester.firstWidget(
find.byType(LinearProgressIndicator).last,
);
expect(indeterminateIndicator.value, null);
});
}

View File

@@ -8,9 +8,10 @@ import 'package:flutter_api_samples/material/progress_indicator/linear_progress_
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Finds LinearProgressIndicator', (WidgetTester tester) async {
testWidgets('Can control LinearProgressIndicator value',
(WidgetTester tester) async {
await tester.pumpWidget(
const example.ProgressIndicatorApp(),
const example.ProgressIndicatorExampleApp(),
);
expect(