我有一個顯示該點處的黑點,其中用戶觸摸屏幕像這樣的應用程序:如何確保我的CustomPaint小部件繪畫存儲在柵格緩存中?
黑點可以由用戶移動他/她拖動他的手指上屏幕。
背景是一個昂貴的繪畫操作,所以我在堆棧中創建了兩個單獨的小部件,希望背景小部件繪畫將存儲在Flutter柵格緩存中。但它不存儲 - 每次黑點移動時,Flutter都會調用我昂貴的繪畫方法。
我在做什麼錯?
這裏是我的代碼:
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;
}
順便說一句,你爲什麼用'Listener'爲DRAP /下降?爲此,有一個'Draggable'小部件。 – Darky
感謝您的提示 - 我沒有意識到Draggable,但它並不適合我的情況:我實際上爲我的協作白板webapp寫了一個Flutter應用程序:https://whiteboardfox.com/ – Mark