RepaintBoundary In Flutter
Flutter paints widgets to the screen. If the substance of a widget ought to be updated, it’s anything but a repaint. Notwithstanding, Flutter may likewise repaint different widgets whose content remaining parts unaltered. It can influence the application execution and at times it’s very huge. If you are searching for an approach to forestall unnecessary repaints, you can think about utilizing RepaintBoundary.
In this blog, we will explore RepaintBoundary In Flutter. We will see how to implement a demo program of the repaint boundary and how to use it in your flutter applications.
Table Of Contents::
Why Need to Use RepaintBoundary
RepaintBoundary:
RepaintBoundary class Null safety. To start with, you need to realize what is RepaintBoundary in Flutter. It’s anything but’s a widget that makes a different presentation list for its child. As indicated by Wikipedia, a showcase list is a progression of illustrations commands that characterize an output picture. This widget makes a different presentation list for its child, Flutter proposes you use RepaintBoundary if a subtree repaints at unexpected times in comparison to its encompassing parts to further develop performance.
Why Need to Use RepaintBoundary:
Flutter widgets are related to RenderObjects
. A RenderObject has a technique called paint which is utilized to perform painting. Be that as it may, the paint
the method can be conjured regardless of whether the related widget occasions don’t change. That is because Flutter may perform repaint to other RenderObjects in a similar Layer if one of them is set apart as filthy. At the point when a RenderObject should be repainted utilizing RenderObject.markNeedsPaint, it advises its closest predecessor to repaint. The progenitor does likewise to its predecessor, perhaps until the root RenderObject. At the point when a RenderObject’s paint strategy is set off, the entirety of its relative RenderObjects in a similar layer will be repainted.
At times, when a RenderObject
should be repainted, the other RenderObjects in a similar layer shouldn’t be repainted because their delivered substance stays unaltered. As such, it would be better if we would just repaint certain RenderObjects. Utilizing RepaintBoundary
can be helpful to restrict the engendering of markNeedsPaint up the render tree and paintChild down the render tree.
RepaintBoundary can decouple the predecessor render objects from the relative render objects. In this way, it’s feasible to repaint just the subtree whose content changes. The utilization of RepaintBoundary may altogether further develop the application execution, particularly if the subtree that shouldn’t be repainted requires broad work for repainting.
How to implement code in dart file :
You need to implement it in your code respectively:
Create a new dart file called home_page.dart
inside the lib
folder.
We will make a straightforward demo application where the background is painted utilizing CustomPainter and there are 10,000 ovals drawn. There is likewise a cursor that moves following the last position of the client touches the screen. The following is the code without RepaintBoundary.
In the body, we will create a Stack widget. Inside, we will add a StackFit.expand, and add two widgets was _buildBackground(), and _buildCursor(),. We will define the below code.
Stack(
fit: StackFit.expand,
children: <Widget>[
_buildBackground(),
_buildCursor(),
],
),
We will describe _buildBackground() widget:
In the _buildBackground() widget. We will return CustomPaint() widget. Inside, we will add BackgroundColor class on a painter. We will define below. Also, we will add is complex as true means whether to hint that this layer’s painting should be cached and willChange was false means whether the raster cache should be told that this painting is likely to change in the next frame.
Widget _buildBackground() {
return CustomPaint(
painter: BackgroundColor(MediaQuery.of(context).size),
isComplex: true,
willChange: false,
);
}
We will describe BackgroundColor class:
We will create a BackgroundColor was extend CustomPainter.
import 'dart:math';
import 'package:flutter/material.dart';
class BackgroundColor extends CustomPainter {
static const List<Color> colors = [
Colors.orange,
Colors.purple,
Colors.blue,
Colors.green,
Colors.purple,
Colors.red,
];
Size _size;
BackgroundColor(this._size);
@override
void paint(Canvas canvas, Size size) {
final Random rand = Random(12345);
for (int i = 0; i < 10000; i++) {
canvas.drawOval(
Rect.fromCenter(
center: Offset(
rand.nextDouble() * _size.width - 100,
rand.nextDouble() * _size.height,
),
width: rand.nextDouble() * rand.nextInt(150) + 200,
height: rand.nextDouble() * rand.nextInt(150) + 200,
),
Paint()
..color = colors[rand.nextInt(colors.length)].withOpacity(0.3)
);
}
}
@override
bool shouldRepaint(BackgroundColor other) => false;
}
We will describe _buildCursor() widget:
In this widget, we will return the Listener widget. We will add _updateOffset () widget at onPointerDown/Move and add CustomPaint widget. Inside, we will add a key and CursorPointer class. We will define below. Also, we will add ConstrainedBox().
Widget _buildCursor() {
return Listener(
onPointerDown: _updateOffset,
onPointerMove: _updateOffset,
child: CustomPaint(
key: _paintKey,
painter: CursorPointer(_offset),
child: ConstrainedBox(
constraints: BoxConstraints.expand(),
),
),
);
}
We will describe CursorPointer class:
We will create a CursorPointer was extend CustomPainter.
import 'package:flutter/material.dart';
class CursorPointer extends CustomPainter {
final Offset _offset;
CursorPointer(this._offset);
@override
void paint(Canvas canvas, Size size) {
canvas.drawCircle(
_offset,
10.0,
new Paint()..color = Colors.green,
);
}
@override
bool shouldRepaint(CursorPointer old) => old._offset != _offset;
}
When we run the application, we ought to get the screen’s output like the underneath screen video. If you try to move the pointer on the screen, the application will be so laggy because it repaints the background, requiring expensive computation.
Presently, we will add RepaintBoundary. The answer to the above problem is wrapping the CustomPaint widget as the child of a RepaintBoundary.
Widget _buildBackground() {
return RepaintBoundary(
child: CustomPaint(
painter: BackgroundColor(MediaQuery.of(context).size),
isComplex: true,
willChange: false,
),
);
}
When we run the application, we ought to get the screen’s output like the underneath screen video. With that simple change, now the background doesn’t need to be repainted when Flutter repaints the cursor. The application should not be laggy anymore.
Code File:
import 'package:flutter/material.dart';
import 'package:flutter_repaint_boundary_demo/background_color.dart';
import 'package:flutter_repaint_boundary_demo/cursor_pointer.dart';
class HomePage extends StatefulWidget {
@override
State createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
final GlobalKey _paintKey = new GlobalKey();
Offset _offset = Offset.zero;
Widget _buildBackground() {
return RepaintBoundary(
child: CustomPaint(
painter: BackgroundColor(MediaQuery.of(context).size),
isComplex: true,
willChange: false,
),
);
}
Widget _buildCursor() {
return Listener(
onPointerDown: _updateOffset,
onPointerMove: _updateOffset,
child: CustomPaint(
key: _paintKey,
painter: CursorPointer(_offset),
child: ConstrainedBox(
constraints: BoxConstraints.expand(),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.cyan,
title: const Text('Flutter RepaintBoundary Demo'),
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
_buildBackground(),
_buildCursor(),
],
),
);
}
_updateOffset(PointerEvent event) {
RenderBox? referenceBox = _paintKey.currentContext?.findRenderObject() as RenderBox;
Offset offset = referenceBox.globalToLocal(event.position);
setState(() {
_offset = offset;
});
}
}
Conclusion:
In the article, I have explained the basic structure of the RepaintBoundary in a flutter; you can modify this code according to your choice. This was a small introduction to RepaintBoundary On User Interaction from my side, and it’s working using Flutter.
I hope this blog will provide you with sufficient information on Trying up the RepaintBoundary in your flutter projects. We will make a demo program for working Custom Chat Bubble and you should use RepaintBoundary a subtree repaint at different times than its surrounding parts. To make sure that a RepaintBounary
is useful in your flutter applications. So please try it.
❤ ❤ Thanks for reading this article ❤❤
If I got something wrong? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.