setState は実際には状態を設定していません [フラッター]

これで、キャンバスに描画するコードができました。

import 'dart:ui';

import 'package:flutter/material.dart';

ボイドメイン(){
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@オーバーライド
ウィジェットのビルド(BuildContext コンテキスト) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
ホーム: ホーム()、
);
}
}

// オフセット
List オフセット = [];

class Home extends StatefulWidget {
const Home({
鍵?鍵、
}) : スーパー (キー: キー);

@オーバーライド
State createState() => _HomeState();
}

class _HomeState extends State {
// オフセット
List オフセット = [];

@オーバーライド
ウィジェットのビルド(BuildContext コンテキスト) {
足場を返す(
appBar: アプリバー(
title: const Text('Drawing'),
)、
本体:GestureDetector(
onPanDown: (詳細) {
setState(() {
offsets.add(details.localPosition);
});
}、
onPanUpdate: (詳細) {
setState(() {
offsets.add(details.localPosition);
});
}、
onPanEnd: (詳細) {
setState(() {
offsets.add(null);
});
}、
子: コンテナ(
幅: double.infinity、
高さ: MediaQuery.of(context).size.height,
色: Colors.grey,
子: カスタムペイント(
foregroundPainter: Painter(オフセット: オフセット),
)、
)、
)、
);
}
}

class Painter は CustomPainter を拡張します {
Painter({this.offsets が必要});

List オフセット;

@オーバーライド
void paint(キャンバス canvas, サイズ size) {
ペイント ペイント = ペイント()
..ストローク幅 = 2
..style = PaintingStyle.stroke;

// すべてのオフセットと次のオフセット
for (int i = 0; i < offsets.length - 1; i++) {
// どちらも null でない場合
if (オフセット[i] != null && オフセット[i + 1] != null) {
canvas.drawLine(offsets[i]!, offsets[i + 1]!, paint);
} それ以外の場合 (オフセット[i] != null && オフセット[i + 1] == null) {
canvas.drawPoints(PointMode.points, [offsets[i]!], paint);
}
}
print('ペイントが呼び出されました');
}

@オーバーライド
bool shouldRepaint(covariant CustomPainter oldDelegate) {
false を返します。
}
}

これがどのように機能するかというと、コンテナーでのジェスチャーを検出し、コンテナーでスワイプが行われると、そのオフセットを記録してオフセット配列に追加します。後で、その配列はカスタム ペインターに渡され、そこですべてのオフセットを調べて線をレンダリングします。そのため、オフセットを配列に追加するときは setState を使用して、新しいオフセットが追加されるようにします。画面が再度レンダリングされ、新しいオフセットがカスタム ペインターに渡され、それらの行がレンダリングされます。しかし、スワイプすると機能しませんが、ホットリロードすると線が表示されます。どうしてこれなの?これらの行を表示するために手動でホット リロードする必要があるのはなぜですか?助けていただければ幸いです。

編集: オフセットが適切に追加され、setState も正常に機能しているようですが、カスタム ペインターが呼び出されていません。

NVM、shouldRepaint メソッドから true を返すことで問題が解決します。

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
true を返します。
}