| // 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:ui' as ui; |
| import 'package:flutter/material.dart'; |
| |
| // Various tests to verify that animated image filtered layers do not |
| // dirty children even without explicit repaint boundaries. These intentionally use |
| // text to ensure we don't measure the opacity peephole case. |
| class AnimatedBlurBackdropFilter extends StatefulWidget { |
| const AnimatedBlurBackdropFilter({ super.key }); |
| |
| @override |
| State<AnimatedBlurBackdropFilter> createState() => _AnimatedBlurBackdropFilterState(); |
| } |
| |
| class _AnimatedBlurBackdropFilterState extends State<AnimatedBlurBackdropFilter> with SingleTickerProviderStateMixin { |
| late final AnimationController controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 5000)); |
| late final Animation<double> animation = controller.drive(Tween<double>(begin: 0.0, end: 1.0)); |
| ui.ImageFilter imageFilter = ui.ImageFilter.blur(); |
| |
| @override |
| void initState() { |
| super.initState(); |
| controller.repeat(); |
| animation.addListener(() { |
| setState(() { |
| imageFilter = ui.ImageFilter.blur( |
| sigmaX: animation.value * 16, |
| sigmaY: animation.value * 16, |
| tileMode: TileMode.decal, |
| ); |
| }); |
| }); |
| } |
| |
| @override |
| void dispose() { |
| controller.dispose(); |
| super.dispose(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return MaterialApp( |
| home: Scaffold( |
| body: Stack( |
| children: <Widget>[ |
| ListView( |
| children: <Widget>[ |
| for (int i = 0; i < 30; i++) |
| Center( |
| child: Transform.scale(scale: 1.01, child: const ModeratelyComplexWidget()), |
| ), |
| ], |
| ), |
| BackdropFilter( |
| filter: imageFilter, |
| child: const SizedBox.expand(), |
| ), |
| ], |
| ), |
| ), |
| ); |
| } |
| } |
| |
| class ModeratelyComplexWidget extends StatelessWidget { |
| const ModeratelyComplexWidget({ super.key }); |
| |
| @override |
| Widget build(BuildContext context) { |
| return const Material( |
| elevation: 10, |
| clipBehavior: Clip.hardEdge, |
| child: ListTile( |
| leading: Icon(Icons.abc, size: 24), |
| title: DecoratedBox(decoration: BoxDecoration(color: Colors.red), child: Text('Hello World')), |
| trailing: FlutterLogo(), |
| ), |
| ); |
| } |
| } |