我正在学习颤动,并且已经开发了我的第一个待办事项应用程序。我遇到的问题是该应用程序在设备和仿真器上的调试模式下运行良好,但是当我运行flutter run build命令并安装发行版APK时,在其中输入Todo项的文本框不起作用,而是出现了一个灰色框。 我将附加一些图像进行说明。我是新手,所以很可能错过了一些东西。我只是想将我的应用作为发行版APK进行测试,以查看它是否流畅。
感谢您的帮助!
这是vscode在我的摩托罗拉手机中安装的调试apk
这是该对话框在发行版apk上的样子
我已经上传了项目供您查看,但这是表单代码和列表
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"]);
}
}
完整的项目网址: https://drive.google.com/drive/folders/1tNue3EfdwV_7M7zHt_A7A4RsNIdppHqj?usp=sharing
答案 0 :(得分:2)
我认为问题是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),
),
),
],
);
}
}