Flutter setState正在还原

时间:2019-02-14 15:59:32

标签: dart flutter setstate

当我setState并将图像添加到_images数组时,它似乎已经添加了,但是随后迅速还原:

enter image description here

此表格粗略地遵循Brian Egan's redux architecture example

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

class Note {
  final String comments;
  final List<String> images;

  Note({
    this.comments,
    this.images,
  });
}

class AddNote extends StatefulWidget {
  final Note note;
  final bool isEditing;

  AddNote({
    this.note,
    this.isEditing,
  });

  @override
  _AddNoteState createState() => _AddNoteState();
}

class _AddNoteState extends State<AddNote> {
  static final _scaffoldKey = GlobalKey<ScaffoldState>();
  static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  List<String> _images;
  String _comments;

  Note get _note => widget.note;
  bool get _isEditing => widget.isEditing;

  @override
  Widget build(BuildContext context) {
    _images = _note.images;
    _comments = _note.comments;

    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: Text(
          _isEditing ? "Edit Note" : "Create Note",
        ),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              _photoPickerField(),
              _notesField(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _photoPickerField() {
    return GestureDetector(
      onTap: _selectPicture,
      child: Row(
        children: <Widget>[
          Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey, width: 1,),
              borderRadius: BorderRadius.all(const Radius.circular(10)),
            ),
            child: SizedBox(child: Icon(Icons.camera_alt), width: 110, height: 110,)
          ),
        ] + _imagesRowItems(),
      ),
    );
  }

  List<Widget> _imagesRowItems() {
    return _images.map((image) {
      return SizedBox(
        height: 110,
        width: 110,
        child: Image.file(File(image), height: 110, width: 110, fit: BoxFit.cover),
      );
    }).toList();
  }

  Future _selectPicture() async {
    return ImagePicker.pickImage(source: ImageSource.gallery)
      .then((file) {
        setState(() {
          _images.add(file.path);
        });
    });
  }

  Widget _notesField() {
    return TextFormField(
      maxLines: 2,
      keyboardType: TextInputType.multiline,
      initialValue: _comments,
      onSaved: (String value) => _comments = value,
    );
  }
}

请注意,comments字段保持其状态没有问题。如何以保持其新状态的方式添加到图像数组?

1 个答案:

答案 0 :(得分:4)

您的问题是,您正在Widget状态的build()方法内设置变量,但是每次您调用setState()时都会调用build方法,因为变量已更改,因此它将重置图片和评论。

要解决此问题,您应该使用initState()方法初始化变量,如下所示:

class _AddNoteState extends State<AddNote> {
  ...
  @override
  void initState() {
    super.initState();
    _images = _note.images;
    _comments = _note.comments;
  }
}

并从build()方法中将其删除。