Flutter listview不使用setState更新

Flutter listview不使用setState更新,flutter,listview,setstate,Flutter,Listview,Setstate,我有一张卡片,上面有一个TexField和一个选择图像的按钮。 选择图像后,必须将图标替换为图像,并且在选择对话框中必须显示“删除”项。 它在第一张固定的卡上工作得很好,但在Listview中动态插入的卡上,它不工作,因为它不使用setState更新。 如何更新listView import 'package:flutter/material.dart'; import 'dart:io'; import 'package:image_picker/image_picker.dart'; imp

我有一张卡片,上面有一个TexField和一个选择图像的按钮。 选择图像后,必须将图标替换为图像,并且在选择对话框中必须显示“删除”项。 它在第一张固定的卡上工作得很好,但在Listview中动态插入的卡上,它不工作,因为它不使用setState更新。 如何更新listView

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropper/image_cropper.dart';

void main() => runApp(MaterialApp(
      home: NewPollPage(),
    ));

class NewPollPage extends StatefulWidget {
  @override
  _NewPollPageState createState() => _NewPollPageState();
}

class _NewPollPageState extends State<NewPollPage> {
  Map photoMap = {};
  var cards = <Card>[];
  var newAlt = <TextEditingController>[];
  var alternativaController = TextEditingController();
  var alternativa1Controller = TextEditingController();

  String indice = UniqueKey().toString();
  File cropped;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: Text('Cards'),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Card(
              elevation: 0,
              color: Color(0xFAFAFA),
              child: Row(
                children: [
                  !photoMap.containsKey('foto_n1')
                      ? IconButton(
                          padding: EdgeInsets.only(bottom: 18.0),
                          icon: Icon(Icons.camera_alt),
                          color: Colors.black,
                          onPressed: () {
                            setState(() {
                              selectImage(context, 'n1', false);
                            });
                          },
                        )
                      : GestureDetector(
                          child: Container(
                            padding: EdgeInsets.only(bottom: 20.0),
                            width: 50,
                            height: 46,
                            child: Image.file(photoMap['foto_n1']),
                          ),
                          onTap: () {
                            setState(() {
                              selectImage(context, 'n1', true);
                            });
                          },
                        ),
                  Expanded(
                    child: TextField(
                      controller: alternativa1Controller,
                      maxLength: 60,
                      decoration: InputDecoration(
                        hintText: 'Digite a alternativa',
                        contentPadding: EdgeInsets.only(left: 12, top: 22),
                        fillColor: Color(0xFFE3E4E8),
                        filled: true,
                        border: OutlineInputBorder(
                          borderSide: BorderSide.none,
                          borderRadius: BorderRadius.circular(25.0),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            ListView.builder(
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              itemCount: cards.length,
              itemBuilder: (context, index) {
                indice = UniqueKey().toString();
                return cards[index];
              },
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        backgroundColor: Colors.black,
        onPressed: () {
          setState(() => cards.add(createCard(indice)));
        },
      ),
    );
  }

  Card createCard(indice) {
    var alternativaController = TextEditingController();
    newAlt.add(alternativaController);
    return Card(
      elevation: 0,
      color: Color(0xFAFAFA),
      child: Row(
        children: [
          !photoMap.containsKey('foto_$indice')
              ? IconButton(
                  padding: EdgeInsets.only(bottom: 18.0),
                  icon: Icon(Icons.camera_alt),
                  color: Colors.black,
                  onPressed: () {
                    setState(() {
                      selectImage(context, '$indice', false);
                    });
                  },
                )
              : GestureDetector(
                  child: Container(
                    padding: EdgeInsets.only(bottom: 20.0),
                    width: 50,
                    height: 46,
                    child: Image.file(photoMap['foto_$indice']),
                  ),
                  onTap: () {
                    setState(() {
                      selectImage(context, '$indice', true);
                    });
                  },
                ),
          Expanded(
            child: TextField(
              maxLength: 60,
              decoration: InputDecoration(
                hintText: 'Digite a alternativa',
                contentPadding: EdgeInsets.only(left: 12, top: 22),
                fillColor: Color(0xFFE3E4E8),
                filled: true,
                border: OutlineInputBorder(
                  borderSide: BorderSide.none,
                  borderRadius: BorderRadius.circular(25.0),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  selectImage(parentContext, indice, visivel) {
    return showDialog(
        context: context,
        builder: (context) {
          return SimpleDialog(
            title: Text('Selecione:'),
            children: [
              if (photoMap.containsKey('foto_$indice'))
                Image.file(photoMap['foto_$indice']),
              SimpleDialogOption(
                  child: Row(
                    children: [
                      Icon(Icons.camera_alt),
                      Text('  Tirar foto com a câmera'),
                    ],
                  ),
                  onPressed: () => getImage(ImageSource.camera, indice)),
              SimpleDialogOption(
                  child: Row(
                    children: [
                      Icon(Icons.photo_library),
                      Text('  Foto da galeria'),
                    ],
                  ),
                  onPressed: () => getImage(ImageSource.gallery, indice)),
              Visibility(
                visible: visivel,
                child: SimpleDialogOption(
                    child: Row(
                      children: [
                        Icon(Icons.delete),
                        Text('  Apagar'),
                      ],
                    ),
                    onPressed: () => null //apagarFoto(mapa),
                    ),
              ),
              SimpleDialogOption(
                child: Row(
                  children: [
                    Icon(Icons.cancel),
                    Text('  Cancelar'),
                  ],
                ),
                onPressed: () => Navigator.pop(context),
              )
            ],
          );
        });
  }

  Future getImage(ImageSource source, indice) async {
    Navigator.pop(context);
    PickedFile imagePicker = await ImagePicker().getImage(source: source);
    if (imagePicker != null) {
      cropped = await ImageCropper.cropImage(
        sourcePath: imagePicker.path,
        aspectRatio: CropAspectRatio(ratioX: 4, ratioY: 3),
        compressQuality: 70,
        maxWidth: 700,
        maxHeight: 700,
        compressFormat: ImageCompressFormat.jpg,
        androidUiSettings: AndroidUiSettings(
          toolbarColor: Colors.black,
          toolbarTitle: "Foto",
          statusBarColor: Colors.black,
          backgroundColor: Colors.black,
          toolbarWidgetColor: Colors.white,
          dimmedLayerColor: Colors.black,
        ),
      );
      if (cropped != null) {
        setState(() {
          photoMap['foto_$indice'] = cropped;
        });
      }
    }
  }
}

导入“包装:颤振/材料.省道”;
导入“dart:io”;
导入“包:image_picker/image_picker.dart”;
导入“package:image_cropper/image_cropper.dart”;
void main()=>runApp(MaterialApp(
主页:NewPollPage(),
));
类NewPollPage扩展StatefulWidget{
@凌驾
_NewPollPageState createState();
}
类_NewPollPageState扩展状态{
Map photoMap={};
var卡=[];
var newAlt=[];
var alternativaController=TextEditingController();
var alternativa1Controller=TextEditingController();
字符串标识=UniqueKey().toString();
文件裁剪;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
背景颜色:Colors.black,
标题:文本(“卡片”),
标题:对,
),
正文:SingleChildScrollView(
子:列(
儿童:[
卡片(
海拔:0,
颜色:颜色(0xFAFAFA),
孩子:排(
儿童:[
!photoMap.containsKey('foto_n1'))
?图标按钮(
填充:仅限边缘设置(底部:18.0),
图标:图标(Icons.camera\u alt),
颜色:颜色,黑色,
已按下:(){
设置状态(){
选择图像(上下文“n1”,false);
});
},
)
:手势检测器(
子:容器(
填充:仅限边缘设置(底部:20.0),
宽度:50,
身高:46,
子:Image.file(photoMap['foto_n1']),
),
onTap:(){
设置状态(){
选择图像(上下文“n1”,true);
});
},
),
扩大(
孩子:TextField(
控制器:Alternativa1控制器,
最大长度:60,
装饰:输入装饰(
hintText:“Digite a alternativa”,
contentPadding:仅限边集(左:12,顶:22),
填充颜色:颜色(0xFFE3E4E8),
是的,
边框:大纲输入边框(
borderSide:borderSide.none,
边界半径:边界半径。圆形(25.0),
),
),
),
),
],
),
),
ListView.builder(
收缩膜:对,
物理学:NeverscrollableScroll物理学(),
itemCount:cards.length,
itemBuilder:(上下文,索引){
indice=UniqueKey().toString();
返回卡[索引];
},
)
],
),
),
浮动操作按钮:浮动操作按钮(
子:图标(Icons.add),
背景颜色:Colors.black,
已按下:(){
设置状态(()=>cards.add(createCard(indice));
},
),
);
}
卡片创建卡片(标识){
var alternativaController=TextEditingController();
newAlt.add(可选控件);
回程卡(
海拔:0,
颜色:颜色(0xFAFAFA),
孩子:排(
儿童:[
!photoMap.containsKey('foto_u$indice')
?图标按钮(
填充:仅限边缘设置(底部:18.0),
图标:图标(Icons.camera\u alt),
颜色:颜色,黑色,
已按下:(){
设置状态(){
选择图像(上下文,$indice',false);
});
},
)
:手势检测器(
子:容器(
填充:仅限边缘设置(底部:20.0),
宽度:50,
身高:46,
子:Image.file(photoMap['foto_u$indice']),
),
onTap:(){
设置状态(){
选择图像(上下文,$indice',true);
});
},
),
扩大(
孩子:TextField(
最大长度:60,
装饰:输入装饰(
hintText:“Digite a alternativa”,
contentPadding:仅限边集(左:12,顶:22),
填充颜色:颜色(0xFFE3E4E8),
是的,
边框:大纲输入边框(
borderSide:borderSide.none,
边界半径:边界半径。圆形(25.0),
),
),
),
),
],
),
);
}
选择图像(父上下文、标识、访问级别){
返回显示对话框(
上下文:上下文,
生成器:(上下文){
返回SimpleDialog(
标题:文本('Selecione:'),
儿童:[
if(影像地图容器('foto_u$indice'))
Image.file(photoMap['foto_u$indice']),
简单幻觉(
孩子:排(
儿童:[
图标(Icons.camera)_
ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: cards.length,
          itemBuilder: (context, index) {
            indice = UniqueKey().toString();
            return cards[index];
          },
        )
ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: photoMap.length,
          itemBuilder: (context, index) {
            return _cardWidget(index);
          },
        )
Card _cardWidget(int index) {
return Card(
  elevation: 0,
  color: Color(0xFAFAFA),
  child: Row(
    children: [
      photoMap['foto_$index'] == ''
          ? IconButton(
              padding: EdgeInsets.only(bottom: 18.0),
              icon: Icon(Icons.camera_alt),
              color: Colors.black,
              onPressed: () {
                setState(() {
                  selectImage(context, '$index', false);
                });
              },
            )
          : GestureDetector(
              child: Container(
                padding: EdgeInsets.only(bottom: 20.0),
                width: 50,
                height: 46,
                child: Image.file(photoMap['foto_$index']),
              ),
              onTap: () {
                setState(() {
                  selectImage(context, '$index', true);
                });
              },
            ),
      Expanded(
        child: TextField(
          maxLength: 60,
          decoration: InputDecoration(
            hintText: 'Digite a alternativa',
            contentPadding: EdgeInsets.only(left: 12, top: 22),
            fillColor: Color(0xFFE3E4E8),
            filled: true,
            border: OutlineInputBorder(
              borderSide: BorderSide.none,
              borderRadius: BorderRadius.circular(25.0),
            ),
          ),
        ),
      ),
    ],
  ),
);
   }
floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    backgroundColor: Colors.black,
    onPressed: () {
      setState(() => photoMap["foto_${photoMap.length}"] = '');
    },
  ),
  if (photoMap['foto_$indice'] != '')Image.file(photoMap['foto_$indice']),