| // 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 'recorder.dart'; |
| |
| /// Creates a [PageView] that uses a font style that can't be rendered |
| /// using canvas (switching to DOM). |
| /// |
| /// Since the whole page uses a CustomPainter this is a good representation |
| /// for apps that have pictures with large number of painting commands. |
| class BenchPageViewScrollLineThrough extends WidgetRecorder { |
| BenchPageViewScrollLineThrough() : super(name: benchmarkName); |
| |
| static const String benchmarkName = 'bench_page_view_scroll_line_through'; |
| |
| @override |
| Widget createWidget() => const MaterialApp( |
| title: 'PageView Scroll LineThrough Benchmark', |
| home: _MyScrollContainer(), |
| ); |
| } |
| |
| class _MyScrollContainer extends StatefulWidget { |
| const _MyScrollContainer(); |
| |
| @override |
| State<_MyScrollContainer> createState() => _MyScrollContainerState(); |
| } |
| |
| class _MyScrollContainerState extends State<_MyScrollContainer> { |
| static const Duration stepDuration = Duration(milliseconds: 500); |
| |
| late PageController pageController; |
| final _CustomPainter _painter = _CustomPainter('aa'); |
| int pageNumber = 0; |
| |
| @override |
| void initState() { |
| super.initState(); |
| |
| pageController = PageController(); |
| |
| // Without the timer the animation doesn't begin. |
| Timer.run(() async { |
| while (pageNumber < 25) { |
| await pageController.animateToPage(pageNumber % 5, |
| duration: stepDuration, curve: Curves.easeInOut); |
| pageNumber++; |
| } |
| }); |
| } |
| |
| @override |
| void dispose() { |
| pageController.dispose(); |
| _painter._textPainter.dispose(); |
| super.dispose(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return PageView.builder( |
| controller: pageController, |
| itemBuilder: (BuildContext context, int position) { |
| return CustomPaint( |
| painter: _painter, |
| size: const Size(300, 500), |
| ); |
| }); |
| } |
| } |
| |
| class _CustomPainter extends CustomPainter { |
| _CustomPainter(this.text); |
| |
| final String text; |
| final Paint _linePainter = Paint(); |
| final TextPainter _textPainter = TextPainter(); |
| static const double lineWidth = 0.5; |
| |
| @override |
| void paint(Canvas canvas, Size size) { |
| canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height)); |
| double xPosition, yPosition; |
| final double width = size.width / 7; |
| final double height = size.height / 6; |
| xPosition = 0; |
| const double viewPadding = 5; |
| const double circlePadding = 4; |
| yPosition = viewPadding; |
| _textPainter.textDirection = TextDirection.ltr; |
| _textPainter.textWidthBasis = TextWidthBasis.longestLine; |
| _textPainter.textScaleFactor = 1; |
| const TextStyle textStyle = |
| TextStyle(color: Colors.black87, fontSize: 13, fontFamily: 'Roboto'); |
| |
| _linePainter.isAntiAlias = true; |
| for (int i = 0; i < 42; i++) { |
| _linePainter.color = Colors.white; |
| |
| TextStyle temp = textStyle; |
| if (i % 7 == 0) { |
| temp = textStyle.copyWith(decoration: TextDecoration.lineThrough); |
| } |
| |
| final TextSpan span = TextSpan( |
| text: text, |
| style: temp, |
| ); |
| |
| _textPainter.text = span; |
| |
| _textPainter.layout(maxWidth: width); |
| _linePainter.style = PaintingStyle.fill; |
| canvas.drawRect( |
| Rect.fromLTWH(xPosition, yPosition - viewPadding, width, height), |
| _linePainter); |
| |
| _textPainter.paint( |
| canvas, |
| Offset(xPosition + (width / 2 - _textPainter.width / 2), |
| yPosition + circlePadding)); |
| xPosition += width; |
| if (xPosition.round() >= size.width.round()) { |
| xPosition = 0; |
| yPosition += height; |
| } |
| } |
| |
| _drawVerticalAndHorizontalLines( |
| canvas, size, yPosition, xPosition, height, width); |
| } |
| |
| void _drawVerticalAndHorizontalLines(Canvas canvas, Size size, |
| double yPosition, double xPosition, double height, double width) { |
| yPosition = height; |
| _linePainter.strokeWidth = lineWidth; |
| _linePainter.color = Colors.grey; |
| canvas.drawLine(const Offset(0, lineWidth), Offset(size.width, lineWidth), |
| _linePainter); |
| for (int i = 0; i < 6; i++) { |
| canvas.drawLine( |
| Offset(0, yPosition), Offset(size.width, yPosition), _linePainter); |
| yPosition += height; |
| } |
| |
| canvas.drawLine(Offset(0, size.height - lineWidth), |
| Offset(size.width, size.height - lineWidth), _linePainter); |
| xPosition = width; |
| canvas.drawLine(const Offset(lineWidth, 0), Offset(lineWidth, size.height), |
| _linePainter); |
| for (int i = 0; i < 6; i++) { |
| canvas.drawLine( |
| Offset(xPosition, 0), Offset(xPosition, size.height), _linePainter); |
| xPosition += width; |
| } |
| } |
| |
| @override |
| bool shouldRepaint(CustomPainter oldDelegate) { |
| return true; |
| } |
| } |