setState 並沒有真正設置狀態 [flutter]


所以我有這段代碼應該繪製到畫布上。

import 'dart:ui';

導入“包:顫振/material.dart”;

無效的主要(){
  runApp(const MyApp());
}

MyApp 類擴展 StatelessWidget {
  const MyApp({Key?key}) : super(key: key);

  @覆蓋
  小部件構建(BuildContext 上下文){
    返回常量 MaterialApp(
      debugShowCheckedModeBanner:假,
      家:家(),
    );
  }
}

// 偏移量
List 偏移量 = [];

類 Home 擴展 StatefulWidget {
  常量首頁({
    鑰匙?鑰匙,
  }) : 超級(鍵:鍵);

  @覆蓋
  State createState() => _HomeState();
}

類 _HomeState 擴展 State {
  // 偏移量
  List 偏移量 = [];

  @覆蓋
  小部件構建(BuildContext 上下文){
    返回腳手架(
      應用欄:應用欄(
        標題:常量文本('繪圖'),
      ),
      正文:手勢檢測器(
        onPanDown:(詳細信息){
          設置狀態((){
            offsets.add(details.localPosition);
          });
        },
        onPanUpdate:(詳細信息){
          設置狀態((){
            offsets.add(details.localPosition);
          });
        },
        onPanEnd:(詳情){
          設置狀態((){
            偏移量.add(null);
          });
        },
        孩子:容器(
          寬度:雙無限,
          高度:MediaQuery.of(context).size.height,
          顏色:顏色.灰色,
          孩子:自定義油漆(
            前景畫家:畫家(偏移:偏移),
          ),
        ),
      ),
    );
  }
}

類 Painter 擴展 CustomPainter {
  畫家({需要this.offsets});

  List 偏移量;

  @覆蓋
  無效油漆(帆布畫布,尺寸大小){
    油漆油漆=油漆()
      ..strokeWidth = 2
      ..style = 繪畫風格.stroke;

    // 對於每個偏移量和下一個偏移量
    for (int i = 0; i < offsets.length - 1; i++) {
      // 如果兩者都不為空
      if (offsets[i] != null && offsets[i + 1] != null) {
        canvas.drawLine(offsets[i]!, offsets[i + 1]!, paint);
      } else if (offsets[i] != null && offsets[i + 1] == null) {
        canvas.drawPoints(PointMode.points, [offsets[i]!], paint);
      }
    }
    print('調用油漆');
  }

  @覆蓋
  bool shouldRepaint(協變 CustomPainter oldDelegate){
    返回假;
  }
}

它的工作原理是它檢測容器上的手勢,當容器上有滑動時,它記錄它的偏移量並將它們添加到偏移量數組中。稍後,該數組被傳遞給自定義繪製器,我們在其中遍歷所有偏移量並渲染線條。因此,當我將偏移量添加到數組時,我使用 setState 以便添加新的偏移量,再次渲染屏幕,將新的偏移量傳遞給自定義畫家並渲染這些線條。但是當我滑動時它不起作用,但是當我進行熱重載時會出現線條。為什麼是這樣?為什麼我需要手動熱重載才能看到這些行?任何幫助將不勝感激。

編輯:似乎正在正確添加偏移量,並且 setState 也工作正常,但不知何故沒有調用自定義畫家。

NVM,從 shouldRepaint 方法返回 true 解決了這個問題。

@override
bool shouldRepaint(協變 CustomPainter oldDelegate){
  返回真;
}