簡體   English   中英

Flutter:GestureDetector 中的 setState() 不起作用

[英]Flutter: setState() inside GestureDetector is not working

在我的代碼中,我將網絡圖像加載到網格中。 然后我允許用戶通過從他們自己的圖庫中選擇一個來替換網絡圖像。 請檢查以下代碼。

Widget _buildPhotoSection() {
    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: GridView.builder(
          shrinkWrap: true,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
          ),
          itemCount: 5,
          itemBuilder: (BuildContext context, int index) {
            XFile? imageFile;
            bool check = false;
            return GestureDetector(
              onTap: () async {
                final XFile? image =
                    await _picker.pickImage(source: ImageSource.gallery);

                setState(() {
                  imageFile = image;
                  check = true;
                  print("DONE");
                });
              },
              child: Stack(
                children: [
                  Card(
                    color: Colors.amber,
                    child: Container(
                      padding: EdgeInsets.all(1),
                      child: check == false
                          ? index <= imageList.length - 1
                              ? CachedNetworkImage(
                                  width: 200,
                                  height: 150,
                                  imageUrl: imageList[index].imageURL == ""
                                      ? "https://www.freeiconspng.com/uploads/no-image-icon-6.png"
                                      : imageList[index].imageURL,
                                  placeholder: (context, url) =>
                                      CircularProgressIndicator(),
                                  errorWidget: (context, url, error) =>
                                      Icon(Icons.error),
                                  fit: BoxFit.fill,
                                )
                              : CachedNetworkImage(
                                  width: 200,
                                  height: 150,
                                  imageUrl:
                                      "https://www.freeiconspng.com/uploads/no-image-icon-6.png",
                                  placeholder: (context, url) =>
                                      CircularProgressIndicator(),
                                  errorWidget: (context, url, error) =>
                                      Icon(Icons.error),
                                  fit: BoxFit.fill,
                                )
                          : Image.file(
                              File(imageFile!.path),
                              width: 200,
                              height: 150,
                            ),
                    ),
                  ),
                  Align(
                      alignment: Alignment.bottomCenter,
                      child: TextButton(
                          onPressed: () {},
                          child: Text(
                            'Change',
                          )))
                ],
              ),
            );
          }),
    );
  }

在這里我可以選擇圖像,但圖庫中的圖像永遠不會顯示。 即使setState被調用,它看起來也正在工作。

為什么會發生這種情況,我該如何解決?

你的變量XFile? imageFile; XFile? imageFile; _buildPhotoSection函數中定義 - 而不是在小部件本身中。 所以你實際上是在 setState() 調用中更新局部變量。 一旦 setState() 完成 - 它會通知 Flutter 引擎重建小部件 - 並且您的 imageFile 變量將被重新初始化 - 不保存您在上一次迭代中設置的值。

我認為你應該移動XFile? imageFile; XFile? imageFile; bool check = false; 到班級,這應該可以解決問題。

編輯:在您對多張圖片發表評論后 - 這是我的建議:

var imageFile=<int, XFile>{};

Widget _buildPhotoSection() {
    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: GridView.builder(
          shrinkWrap: true,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
          ),
          itemCount: 5,
          itemBuilder: (BuildContext context, int index) {
//             XFile? imageFile;
            //bool check = false;
            return GestureDetector(
              onTap: () async {
                final XFile? image =
                    await _picker.pickImage(source: ImageSource.gallery);

                setState(() {
                  imageFile[index] = image;
                  //check = true;
                  print("DONE");
                });
              },
              child: Stack(
                children: [
                  Card(
                    color: Colors.amber,
                    child: Container(
                      padding: EdgeInsets.all(1),
                      child: imageFile.containsKey(index) == false
                          ? index <= imageList.length - 1
                              ? CachedNetworkImage(
                                  width: 200,
                                  height: 150,
                                  imageUrl: imageList[index].imageURL == ""
                                      ? "https://www.freeiconspng.com/uploads/no-image-icon-6.png"
                                      : imageList[index].imageURL,
                                  placeholder: (context, url) =>
                                      CircularProgressIndicator(),
                                  errorWidget: (context, url, error) =>
                                      Icon(Icons.error),
                                  fit: BoxFit.fill,
                                )
                              : CachedNetworkImage(
                                  width: 200,
                                  height: 150,
                                  imageUrl:
                                      "https://www.freeiconspng.com/uploads/no-image-icon-6.png",
                                  placeholder: (context, url) =>
                                      CircularProgressIndicator(),
                                  errorWidget: (context, url, error) =>
                                      Icon(Icons.error),
                                  fit: BoxFit.fill,
                                )
                          : Image.file(
                              File(imageFile[index]!.path),
                              width: 200,
                              height: 150,
                            ),
                    ),
                  ),
                  Align(
                      alignment: Alignment.bottomCenter,
                      child: TextButton(
                          onPressed: () {},
                          child: Text(
                            'Change',
                          )))
                ],
              ),
            );
          }),
    );
  }

您會注意到我將 imageFile 轉換為地圖 - 它將保存用戶選擇的索引和 XFile。 我還刪除了檢查變量 - 我正在檢查 Map 是否包含索引鍵,並根據圖像應該呈現。

我沒有嘗試編譯這個,所以那里可能很少有錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM