j'ai une application qui affiche un point noir au point où l'utilisateur touche l'écran comme ceci:Comment m'assurer que ma peinture de widget CustomPaint est stockée dans le cache raster?
Le point noir peut être déplacé par l'utilisateur comme il/elle tire son doigt sur la écran. L'arrière-plan est une opération de peinture coûteuse, j'ai donc créé deux widgets séparés dans une pile, en espérant que la peinture du widget d'arrière-plan sera stockée dans le cache raster de Flutter. Mais ce n'est pas stocké - Flutter appelle ma méthode de peinture coûteuse chaque fois que le point noir se déplace.
Qu'est-ce que je fais mal?
Voici mon code:
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
GlobalKey _paintKey = new GlobalKey();
Offset _offset;
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
fit: StackFit.expand,
children: <Widget>[
new CustomPaint(
painter: new ExpensivePainter(),
isComplex: true,
willChange: false,
),
new Listener(
onPointerDown: _updateOffset,
onPointerMove: _updateOffset,
child: new CustomPaint(
key: _paintKey,
painter: new MyCustomPainter(_offset),
child: new ConstrainedBox(
constraints: new BoxConstraints.expand(),
),
),
)
],
),
);
}
_updateOffset(PointerEvent event) {
RenderBox referenceBox = _paintKey.currentContext.findRenderObject();
Offset offset = referenceBox.globalToLocal(event.position);
setState(() {
_offset = offset;
});
}
}
class ExpensivePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
print("Doing expensive paint job");
Random rand = new Random(12345);
List<Color> colors = [
Colors.red,
Colors.blue,
Colors.yellow,
Colors.green,
Colors.white,
];
for (int i = 0; i < 5000; i++) {
canvas.drawCircle(
new Offset(
rand.nextDouble() * size.width, rand.nextDouble() * size.height),
10 + rand.nextDouble() * 20,
new Paint()
..color = colors[rand.nextInt(colors.length)].withOpacity(0.2));
}
}
@override
bool shouldRepaint(ExpensivePainter other) => false;
}
class MyCustomPainter extends CustomPainter {
final Offset _offset;
MyCustomPainter(this._offset);
@override
void paint(Canvas canvas, Size size) {
if (_offset == null) return;
canvas.drawCircle(_offset, 10.0, new Paint()..color = Colors.black);
}
@override
bool shouldRepaint(MyCustomPainter other) => other._offset != _offset;
}
D'ailleurs, pourquoi utilisez-vous 'Listener' pour le Drap/drop? Il y a un widget 'Draggable' à cette fin. – Darky
Merci pour le conseil - Je ne connaissais pas le Draggable, mais ce n'est pas vraiment adapté dans mon cas: Je suis en train d'écrire une application Flutter pour mon webapp collaborative webboard: https://whiteboardfox.com/ – Mark