How to ensure my CustomPaint widget painting is stored in the raster cache? : <p>I have an app that displays a black dot at the point where the user touches the screen like this:</p>

<p><a href="https://i.stack.imgur.com/YpTDS.png" rel="noreferrer"><img src="https://i.stack.imgur.com/YpTDS.png" alt="enter image description here"></a></p>

<p>The black dot can be moved by the user as he/she drags his finger on the screen.</p>

<p>The background is an expensive paint operation, so I have created two separate widgets in a stack, hoping that the background widget painting will be stored in the Flutter raster cache.  But it's not stored - Flutter calls my expensive paint method every time the black dot moves.</p>

<p>What am I doing wrong?</p>

<p>Here's my code:</p>

<pre><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() =&gt; new MyHomePageState();
}

class MyHomePageState extends State&lt;MyHomePage&gt; {
  GlobalKey _paintKey = new GlobalKey();
  Offset _offset;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Stack(
        fit: StackFit.expand,
        children: &lt;Widget&gt;[
          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&lt;Color&gt; colors = [
      Colors.red,
      Colors.blue,
      Colors.yellow,
      Colors.green,
      Colors.white,
    ];
    for (int i = 0; i &lt; 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) =&gt; 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) =&gt; other._offset != _offset;
}
</code></pre>
