Flutter - 从其他小部件调用 setState() [英] Flutter - calling setState() from other widget
问题描述
是否可以从其他小部件onPressed()
方法中调用特定小部件(嵌入其他小部件)的setState()
以便仅那个 小部件被重绘了吗?
Is it possible to call setState()
of particular widget (embedded in other widgets) from other widgets onPressed()
method so only that widget is redrawn?
我想单击按钮并查看MyTextWidget"的状态发生变化.布局的其余部分相同,没有任何变化,因此不应重写.
I want to click on the button and see the state of "MyTextWidget" to change. The rest of the layout is same, nothing changes there so it should not be rewritten.
这是我的代码:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Timer',
theme: new ThemeData(
primaryColor: Colors.grey.shade800,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
int _seconds = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
MyTextWidget(), //just update this widget
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.add_circle),
onPressed: _addPressed,
iconSize: 150.0,
),
IconButton(
icon: Icon(Icons.remove_circle),
onPressed: ()=> print("to be implemented"),
iconSize: 150.0,
),
],
)
],
),
);
}
void _addPressed() {
//somehow call _updateSeconds()
}
}
这是我想要更新的有状态的 MyTextWidget.
And this is statefull MyTextWidget which I want to update.
class MyTextWidget extends StatefulWidget{
@override
_MyTextWidgetState createState() => _MyTextWidgetState();
}
class _MyTextWidgetState extends State<MyTextWidget> {
int secondsToDisplay = 0;
void _updateSeconds(int newSeconds) {
setState(() {
secondsToDisplay = newSeconds;
});
}
@override
Widget build(BuildContext context) {
return Text(
secondsToDisplay.toString(),
textScaleFactor: 5.0,
);
}
}
我想要实现的目标似乎很简单,但我无法弄清楚.想象一下,如果MyTextWidget"被埋在巨大的布局树中,每次我想更新它时,我都需要重新绘制整棵树.
It seems like something quite simple what I want to achieve but I'm not able to figure it out. Imagine if "MyTextWidget" was buried in huge layout tree and every time I want to update it I would need to redraw whole tree again.
推荐答案
这是一个使用流的可能解决方案:
This is a possible solution using streams:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Timer',
theme: new ThemeData(
primaryColor: Colors.grey.shade800,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
StreamController<int> _controller = StreamController<int>();
int _seconds = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
MyTextWidget(stream: _controller.stream), //just update this widget
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.add_circle),
onPressed: _addPressed,
iconSize: 150.0,
),
IconButton(
icon: Icon(Icons.remove_circle),
onPressed: ()=> _controller.add(_seconds++),
iconSize: 150.0,
),
],
)
],
),
);
}
void _addPressed() {
//somehow call _updateSeconds()
}
}
class MyTextWidget extends StatefulWidget{
final Stream<int> stream;
MyTextWidget({this.stream});
@override
_MyTextWidgetState createState() => _MyTextWidgetState();
}
class _MyTextWidgetState extends State<MyTextWidget> {
int secondsToDisplay = 0;
void _updateSeconds(int newSeconds) {
setState(() {
secondsToDisplay = newSeconds;
});
}
@override
void initState() {
super.initState();
widget.stream.listen((seconds) {
_updateSeconds(seconds);
});
}
@override
Widget build(BuildContext context) {
return Text(
secondsToDisplay.toString(),
textScaleFactor: 5.0,
);
}
}
这篇关于Flutter - 从其他小部件调用 setState()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!