简体   繁体   中英

Problem with textfield in my first Flutter app build

I'm learning flutter and I've developed my first todo app. The issue I'm experiencing is that the app works well on debug mode on my device and emulator but when I run flutter run build command and install the release apk the textfield where you enter the Todo item doest work and instead I get a grey box. I'll append some images to clarify. I'm a noob so it's probable that I missed something. I just wanted to test my app as a release apk to see if it was fluent.

Thanks for your help!

this is the debug apk that vscode installs in my Motorola one

这是 vscode 在我的摩托罗拉安装的调试 apk

这就是该对话框在发布 apk 上的样子

this is how that dialog looks like on the release apk

I've uploaded the project for you to see but here is the Form code and the list

TodoItemForm.dart:

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:todo/models/TodoItemModel.dart';

class TodoItemForm extends StatefulWidget {
  TodoItemForm({
    Key key,
    @required this.context,
    this.item,
    this.onSubmit,
    this.onClose,
  }) : super(key: key) {
    if (this.item == null)
      this.item = new TodoItemModel("", false, DateTime.now(), DateTime.now());
  }

  final BuildContext context;
  TodoItemModel item;
  final ValueChanged<TodoItemModel> onSubmit;
  final VoidCallback onClose;
  @override
  _TodoItemFormState createState() => _TodoItemFormState();
}

class _TodoItemFormState extends State<TodoItemForm> {
  TextEditingController _todoItemTextController = new TextEditingController();
  @override
  void initState() {
    super.initState();
    if (widget.item != null) {
      _todoItemTextController.value = TextEditingValue(text: widget.item.text);
    } else {
      widget.item = new TodoItemModel(
          _todoItemTextController.text, false, DateTime.now(), DateTime.now());
    }
  }

  void onSubmit() {
    widget.item.text = _todoItemTextController.text;
    widget.onSubmit(widget.item);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Row(
        children: <Widget>[
          Container(
            margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
            child: Icon(
              Icons.playlist_add,
              color: Theme.of(context).primaryColor,
            ),
          ),
          Text(
            "New To Do Item",
          ),
        ],
      ),
      insetPadding: EdgeInsets.symmetric(horizontal: 2),
      content: Expanded(
        child: TextField(
          controller: _todoItemTextController,
          autofocus: true,
          decoration: InputDecoration(
            labelText: "Task to do:",
            hintText: "Buy Groseries!",
          ),
        ),
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: this.onSubmit,
          child: Text(
            "SAVE",
            style: new TextStyle(color: Theme.of(context).accentColor),
          ),
        ),
        FlatButton(
          onPressed: widget.onClose,
          child: Text(
            "CANCEL",
            style: new TextStyle(color: Theme.of(context).accentColor),
          ),
        ),
      ],
    );
  }
}

TaskList.dart:

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:todo/models/TodoItemModel.dart';
import 'package:todo/services/TodoServiceProvider.dart';
import 'package:todo/widgets/TodoItem.dart';
import 'package:todo/widgets/TodoItemForm.dart';

class TaskList extends StatefulWidget {
  TaskList({Key key}) : super(key: key);

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

class _TaskListState extends State<TaskList> {
  List<TodoItemModel> _items = [];
  final _todoItemTextController = new TextEditingController();

  @override
  void initState() {
    super.initState();
    this.refreshTodos();
  }

  void refreshTodos() {
    TodoServiceProvider.getTodoItems().then((todoList) {
      setState(() {
        _items = todoList;
      });
    });
  }

  void _handleSubmit(TodoItemModel newItem) {
    TodoServiceProvider.createTodo(newItem).then((todoItem) {
      this.refreshTodos();
      this._handleClose();
    });
  }

  void _handleEdit(TodoItemModel item) {
    TodoServiceProvider.updateTodo(item).then((todoItem) {
      this.refreshTodos();
      this._handleClose();
    });
  }

  void _handleClose() {
    Navigator.pop(context);
    _todoItemTextController.clear();
  }

  Future<bool> _handleItemCompleted(TodoItemModel model, DismissDirection dir) {
    return TodoServiceProvider.deleteTodo(model.id).then((response) {
      if (response) {
        setState(() {
          _items.remove(model);
        });
        return Future.value(true);
      }
      return Future.value(false);
    }).catchError((error) => Future.value(false));
  }

  void _showTodoItemForm({TodoItemModel item: null}) {
    final alert = TodoItemForm(
      context: context,
      item: item,
      onSubmit: item == null ? this._handleSubmit : this._handleEdit,
      onClose: this._handleClose,
    );

    showDialog(
      context: context,
      builder: (_) {
        return alert;
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Todo"),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _showTodoItemForm,
      ),
      body: Container(
        padding: EdgeInsets.all(12),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Expanded(
              child: ReorderableListView(
                onReorder: (oldIndex, newIndex) {
                  this.setState(() {
                    final aux = _items[oldIndex];
                    if (oldIndex > newIndex) {
                      _items.removeAt(oldIndex);
                      _items.insert(newIndex, aux);
                    } else {
                      _items.insert(newIndex, aux);
                      _items.removeAt(oldIndex);
                    }
                  });
                },
                children: [
                  for (final _item in _items)
                    FlatButton(
                      key: ValueKey(_item),
                      child: TodoItem(
                        model: _item,
                        onItemCompleted: this._handleItemCompleted,
                      ),
                      onPressed: () {
                        this._showTodoItemForm(item: _item);
                      },
                    ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

TodoItemModel.dart:

import 'package:todo/widgets/TodoItem.dart';

class TodoItemModel {
  int _id;
  String _text;
  bool _finished;
  DateTime _creationDate;
  DateTime _dueDate;

  TodoItemModel(this._text, this._finished, this._creationDate, this._dueDate);

  int get id => _id;
  String get text => _text;
  DateTime get creationDate => _creationDate;

  void set text(String value) {
    _text = value;
  }

  void set id(int value) => _id = value;

      
  Map<String, dynamic> toJSON() {
    var map = new Map<String, dynamic>();
    map["text"] = _text;
    map["creation_date"] = _creationDate.toIso8601String();
    if (_id != null) map["id"] = _id;

    return map;
  }

  TodoItemModel.fromJSON(Map<String, dynamic> json) {
    this._id = json["id"];
    this._text = json["text"];
    this._creationDate = DateTime.parse(json["creation_date"]);
  }
}

Full project url: https://drive.google.com/drive/folders/1tNue3EfdwV_7M7zHt_A7A4RsNIdppHqj?usp=sharing

I think the problem is the Expanded Widget in AlertDialog.

TodoItemForm.dart:

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:todo/models/TodoItemModel.dart';

class TodoItemForm extends StatefulWidget {
  TodoItemForm({
    Key key,
    @required this.context,
    this.item,
    this.onSubmit,
    this.onClose,
  }) : super(key: key) {
    if (this.item == null)
      this.item = new TodoItemModel("", false, DateTime.now(), DateTime.now());
  }

  final BuildContext context;
  TodoItemModel item;
  final ValueChanged<TodoItemModel> onSubmit;
  final VoidCallback onClose;
  @override
  _TodoItemFormState createState() => _TodoItemFormState();
}

class _TodoItemFormState extends State<TodoItemForm> {
  TextEditingController _todoItemTextController = new TextEditingController();
  @override
  void initState() {
    super.initState();
    if (widget.item != null) {
      _todoItemTextController.value = TextEditingValue(text: widget.item.text);
    } else {
      widget.item = new TodoItemModel(
          _todoItemTextController.text, false, DateTime.now(), DateTime.now());
    }
  }

  void onSubmit() {
    widget.item.text = _todoItemTextController.text;
    widget.onSubmit(widget.item);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Row(
        children: <Widget>[
          Container(
            margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
            child: Icon(
              Icons.playlist_add,
              color: Theme.of(context).primaryColor,
            ),
          ),
          Text(
            "New To Do Item",
          ),
        ],
      ),
      insetPadding: EdgeInsets.symmetric(horizontal: 2),
      content: Container( //Change this line
        child: TextField(
          controller: _todoItemTextController,
          autofocus: true,
          decoration: InputDecoration(
            labelText: "Task to do:",
            hintText: "Buy Groseries!",
          ),
        ),
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: this.onSubmit,
          child: Text(
            "SAVE",
            style: new TextStyle(color: Theme.of(context).accentColor),
          ),
        ),
        FlatButton(
          onPressed: widget.onClose,
          child: Text(
            "CANCEL",
            style: new TextStyle(color: Theme.of(context).accentColor),
          ),
        ),
      ],
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM