我需要帮助,我尝试使用翻译包翻译颤振中的字符串列表,但它一直显示_instance of 'Future<translation>'
这是我的代码:
ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
translated((docs[index]['tweet']));
return ListTile(
title: Text(
docs[index]['name'],
style:
TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
),
subtitle: Text(
translator.translate(docs[index]['tweet']).toString()),
);
},
);
我尝试以如下方式将async
和await
与setState()
一起使用:
String output = "";
Future<void> translated(String post) async {
final Translation translation = await translator.translate(post, to: 'en');
final String out = translation.toString();
print(out);
setState(() {
output = out;
});
}
ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
translated((docs[index]['tweet']));
return ListTile(
title: Text(
docs[index]['name'],
style:
TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
),
subtitle: Text(output),
);
},
);
它确实会转换,但在显示 .这是完整的身体:
body: Container(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('favorite')
.doc(userID)
.collection('Publication')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
List<dynamic> docs = snapshot.data.docs;
return FutureBuilder<List<String>>(
future: translated(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<String> data = snapshot.data ?? [];
return ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
docs[index]['name'],
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
subtitle: Text(data[index]),
);
},
);
}
}
},
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
)),
- 列表项
当你在build method
内部调用translated
,并在translated
内调用setState
时,意味着你在build method
内部调用setState
,所以你一次又一次地重建你的小部件。将你translated
更改为:
Future<String> translated(String post) async {
final Translation translation = await translator.translate(post, to: 'en');
final String out = translation.toString();
print(out);
return out;
}
并像这样使用它:
ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
String output = await translated((docs[index]['tweet']));
return ListTile(
title: Text(
docs[index]['name'],
style:
TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
),
subtitle: Text(output),
);
},
);
我建议你放弃这种方法:
FutureBuilder<List<String>>(
future: translated(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<String> data = snapshot.data ?? [];
return ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
docs[index]['name'],
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
subtitle: Text(data[index]),
);
},
);
}
}
},
)
并将您的translated
更改为:
Future<List<String>> translated() async{
List<String> result = [];
for (var element in docs) {
String output = await translated((element['tweet']));
result.add(output);
}
return result;
}
当您在小部件的构建方法中调用函数时,只要该小部件出现在树中,就会无限调用此函数。无论操作是否异步,您都应该在 initState() 方法 - 官方 initState 文档中调用它。如果操作是异步的,则应确保在操作完成后调用使用操作数据的小组件。这可以通过多种方式进行 - 例如:创建一个变量:bool translationIsFinished = false;
,然后在翻译函数的底部调用setState(()=>translationIsFinished = true);
。在列表小部件所在的构建方法中,使用以下内容:if(translationIsFinished)...[// your widget here]
或者,您可以使用三元运算符,如下所示:translationIsFinished ? YourWidget() : Container()
在我看来,最好在显示之前翻译获取的帖子,这样您就可以这样做:
Future<List<Map<String, dynamic>>> translatePosts(List<Map<String, dynamic>> docs) async {
for (var doc in docs) {
final post = doc['tweet'];
final Translation translation = await translator.translate(post, to: 'en');
doc['tweet'] = translation.toString();
}
return docs;
}
然后,为了表明您可以使用FutureBuilder:
FutureBuilder(
future: translatePosts,
builder: (BuildContext context, AsyncSnapshot<List<Map<String, dynamic>>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: docs.length,
itemBuilder: (context, index) {
translated((snapshot[index]['tweet']));
return ListTile(
title: Text(
snapshot[index]['name'],
style:
TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
),
subtitle: Text(output),
);
},
);
}
}
)