blob: 952b9d12bdc4c7b6253e924a88611d70dc1d1a77 [file]
// 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';
/// Macrobenchmark page reproducing the text shadow scrolling workload from
/// https://github.com/flutter/flutter/issues/190395.
class TextShadowPerfPage extends StatefulWidget {
const TextShadowPerfPage({super.key});
@override
State<TextShadowPerfPage> createState() => _TextShadowPerfPageState();
}
class _TextShadowPerfPageState extends State<TextShadowPerfPage>
with SingleTickerProviderStateMixin {
late final ScrollController _scrollController;
late final AnimationController _animationController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_animationController = AnimationController(vsync: this, duration: const Duration(seconds: 10))
..repeat(reverse: true);
_animationController.addListener(_onAnimationTick);
}
void _onAnimationTick() {
if (_scrollController.hasClients && _scrollController.position.maxScrollExtent > 0) {
_scrollController.jumpTo(
_animationController.value * _scrollController.position.maxScrollExtent,
);
}
}
@override
void dispose() {
_animationController.removeListener(_onAnimationTick);
_animationController.dispose();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
const columnCount = 7;
const groupsPerColumn = 28;
return Scaffold(
backgroundColor: const Color(0xff080808),
body: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: SingleChildScrollView(
controller: _scrollController,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: List<Widget>.generate(columnCount, (int column) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: List<Widget>.generate(groupsPerColumn, (int row) {
return _TextShadowGroup(index: column * groupsPerColumn + row);
}),
),
),
);
}),
),
),
),
);
}
}
class _TextShadowGroup extends StatelessWidget {
const _TextShadowGroup({required this.index});
final int index;
static const List<Shadow> _shadows = <Shadow>[Shadow(blurRadius: 1.0)];
@override
Widget build(BuildContext context) {
return SizedBox(
height: 230,
child: Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Synthetic text item $index',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
shadows: _shadows,
),
),
Row(
children: <Widget>[
Text(
'${8 + index % 14}:30',
style: const TextStyle(
color: Color(0xff43ddff),
fontSize: 9,
fontWeight: FontWeight.bold,
shadows: _shadows,
),
),
const Spacer(),
Text(
'Ep ${1 + index % 24}',
style: const TextStyle(color: Colors.white70, fontSize: 9, shadows: _shadows),
),
],
),
],
),
),
),
);
}
}