Android 何时在颤振中使用设置状态?
作为颤振的新手,在Android 何时在颤振中使用设置状态?,android,dart,flutter,Android,Dart,Flutter,作为颤振的新手,在flatter应用程序中使用setState对我来说非常混乱。在下面的代码中,布尔值搜索和varresBody在setState中使用。我的问题是为什么在setState中只搜索和resBody?为什么其他变量不可变 var resBody; bool searching = false,api_no_limit = false; String user = null; Future _getUser(String text) async{ setState(() {
flatter
应用程序中使用setState
对我来说非常混乱。在下面的代码中,布尔值搜索
和varresBody
在setState
中使用。我的问题是为什么在setState中只搜索和resBody
?为什么其他变量不可变
var resBody;
bool searching = false,api_no_limit = false;
String user = null;
Future _getUser(String text) async{
setState(() {
searching = true;
});
user = text;
_textController.clear();
String url = "https://api.github.com/users/"+text;
var res = await http
.get(Uri.encodeFull(url), headers: {"Accept":
"application/json"});
setState(() {
resBody = json.decode(res.body);
});
}
更改有状态小部件的状态时,请使用setState()
重新生成小部件及其子体。
您不需要在构造函数或小部件的initState()
中调用setState()
,因为build()
之后仍将运行
也不要在build()中的同步代码中调用setState()
。根据以下说明,您不需要从build()
中重新运行build()
:
调用setState会通知框架此对象的内部状态已发生更改,可能会影响此子树中的用户界面,从而导致框架为此状态对象安排生成
因此,如果小部件的状态发生变化,您必须调用setState
来触发视图的重建,并立即看到新状态所隐含的变化
无论如何,下面的代码片段是等效的
第一种情况(直接形成颤振创建
):
class\u MyHomePageState扩展状态{
int _计数器=0;
void _incrementCounter(){
设置状态(){
//这个对setState的调用告诉颤振框架,某些东西
//已在此状态下更改,这将导致它重新运行下面的生成方法
//以便显示能够反映更新的值。如果我们更改
//_计数器,而不调用setState(),则生成方法将不可用
//再打一次电话,似乎什么也没发生。
_计数器++;
});
}
第二种情况:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
_counter++;
setState(() {});
}
class\u MyHomePageState扩展状态{
int _计数器=0;
void _incrementCounter(){
_计数器++;
setState((){});
}
我不知道是什么原因,如果第一种情况是使用setState
的传统方式,我会说是因为代码的可读性。当您需要更改屏幕上任何小部件显示的值时。例如,在应用程序中有一个任务。完成后,哪些点应该添加到“钱包”中。但问题是我们需要刷新应用程序以查看“钱包”上的点。要解决此问题,我们使用按钮Onpressed()上的Setstate()
例如:
RaisedButton(
onpressed(){
setstate(){
points+10;
}
}
)
每次按下按钮时,它都会使用“wallet”变量返回的新值刷新小部件,而无需重新启动整个应用程序。根据:
通常,建议仅使用setState
方法
包装对状态的实际更改,而不是可能发生的任何计算
与更改关联。例如,此处为
build
函数递增,然后将更改写入
磁盘,但只有增量被包装在setState
中:
Future<void> _incrementCounter() async {
setState(() {
_counter++;
});
Directory directory = await getApplicationDocumentsDirectory();
final String dirName = directory.path;
await File('$dir/counter.txt').writeAsString('$_counter');
}
Future\u incrementCounter()异步{
设置状态(){
_计数器++;
});
目录目录=等待getApplicationDocumentsDirectory();
最终字符串dirName=directory.path;
等待文件(“$dir/counter.txt”).writeAsString(“$\u counter”);
}
每当您想要更新小部件树(通常是使用一些新数据)时,都可以调用setState
。它只能在State
类中使用。下面是简单的实现:
class\u MyPageState扩展状态{
int _计数=0;
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:升起按钮(
按下时:()=>设置状态(()=>_count++),
子项:文本('Count=$\u Count'),
),
),
);
}
}
如果您查看setState
的实现:
Future<void> _incrementCounter() async {
setState(() {
_counter++;
});
Directory directory = await getApplicationDocumentsDirectory();
final String dirName = directory.path;
await File('$dir/counter.txt').writeAsString('$_counter');
}
void设置状态(void回调fn){
断言(fn!=null);
断言(…);
最终动态结果=fn()为动态;
断言(…);
_元素。markNeedsBuild();
}
您可以看到,它所做的唯一事情是:断言一些事情来帮助您调试它的错误用法,执行回调,并标记元素以使其重新生成
因此,从技术上讲,只要调用setState
,更改setState回调内部或外部的一些变量并不重要
然而,对于可读性来说,这有很大的区别。重新构建小部件会对应用程序的性能产生影响,因此您希望尽可能少地这样做。对需要小部件在setState
回调中重新构建的变量进行所有更改,并且仅进行这些更改,可以让人们(包括您未来的自己)明白确切地说,需要重建的原因。这取决于小部件内部或外部的代码位置。从您的问题来看,这是无法推导出来的。有什么好的来源可以了解这个主题吗?,。我肯定有一些教程和YouTube视频,但我手头没有链接。我找到了一个很好的介绍。简单地说,当您更改vari的值时可以。这是最基本的。但用户变量不在setState中,但它仍在应用程序中工作。那么它在StatefulWidget中如何工作?@Goops17我很确定他的问题是“为什么我们不在setState回调中计算所有内容?”问题是,很多人都在问同样的问题,为什么第一种方法是约定。doc说“通常建议使用setState方法来包装状态的实际更改,而不是任何可能与更改相关的计算。”但是,如果我的更改是从base64字符串读取的一个大高清图像怎么办?如果图像的读取和转换在此之前完成,我在setState()
中放了什么?嗯,但是