我在Firestore中有onDestroy()
个文档,其中有task
字段,在Flutter UI中有todo
。
请建议如何使TextField
与textfield
字段同步,即
todo
中的文本都会随着用户的键入而改变,并使用刚刚输入的值更新textfield
字段。todo
字段都会被更新(手动在Firestore控制台中或由其他用户使用),并使用最新值更新todo
。谢谢!
答案 0 :(得分:2)
首先,向TextEditingController
提供一个TextField
(有关完整示例,请查看this)。
对于问题的第一部分,您需要向listener
提供一个TextEditingController
。 listener
应该触发如下功能:
Future<void> _updateTaskValue(String text) {
Firestore().runTransaction((Transaction transaction) {
Firestore.instance.document([PATH OF YOUR DOCUMENT]).updateData({"todo": text});
});
}
假设text
是控制器的text
值。请注意,runTransaction
用于避免数据并发。
对于问题的第二部分,您将不得不听文档。为此,请在initState
中声明StreamSubscription
:
subscription = Firestore.instance.document("").snapshots().listen(
(DocumentSnapshot snapshot) => this._onDatabaseUpdate(snapshot));
每次内容更新时(无论当前用户是更新TextField
,还是其他用户还是通过后台手动更新,此订阅都将触发功能。
下面调用的函数仅用新内容更新控制器的text
属性:
void _onDatabaseUpdate(DocumentSnapshot snapshot) {
setState(() {
_controller.text = snapshot.data["todo"];
});
}
有关完整示例,请参见this gist。
答案 1 :(得分:0)
这是代码:
import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO Screen',
theme: ThemeData(
primarySwatch: Colors.orange,
),
home: TODOScreen(),
);
}
}
class TODOScreen extends StatefulWidget {
@override
_TODOScreenState createState() => _TODOScreenState();
}
class _TODOScreenState extends State<TODOScreen> {
final _ref = FirebaseDatabase.instance.reference().child('todo_id').child('value');
TextEditingController _todoController = new TextEditingController();
StreamSubscription _subscription;
@override
void initState() {
super.initState();
_subscription = _ref.onValue.listen((data) {
String value = data.snapshot.value as String ?? "";
updateOnChanged(value);
});
}
saveOnChanged(String value) async {
await _ref.set(value);
}
updateOnChanged(String value) async {
setState(() {
_todoController.value = _todoController.value.copyWith(
text: value,
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO Screen'),
),
body: Center(
child: Container(
padding: EdgeInsets.all(10.0),
child: TextField(
decoration: InputDecoration(labelText: "TODO"),
maxLines: 5,
onChanged: saveOnChanged,
controller: _todoController,
),
),
),
);
}
@override
void dispose() {
_todoController.dispose();
if (_subscription != null) _subscription.cancel();
super.dispose();
}
}
希望它会帮助您!