这是我的小部件树。当我在MemberSection
课程中按RaisedButton
时,我想更改AdminSection
课程中的文本小部件。 MemberSection
和AdminSection
都在HomePage
级。
下面是飞镖文件:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: HomePage(),
),
);
}
class HomePage extends StatelessWidget {
final int count = 0;
@override
Widget build(BuildContext context) {
return new Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[MemberSection(count), AdminSection(count)],
),
);
}
}
class MemberSection extends StatefulWidget {
MemberSection(this.count);
final int count;
@override
_MemberSectionState createState() => new _MemberSectionState();
}
class _MemberSectionState extends State<MemberSection> {
@override
Widget build(BuildContext context) {
return new Text('${widget.count} member(s)');//I need to change this widget
}
}
class AdminSection extends StatefulWidget {
AdminSection(this.count);
final int count;
@override
_AdminSectionState createState() => new _AdminSectionState();
}
class _AdminSectionState extends State<AdminSection> {
void incrementer() {
setState(() {
//widget.count++; //cannt do
});
}
void decrementer() {
setState(() {
//widget.count--; //cannt do
});
}
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
Text('${widget.count} admin(s)'),//Also, I need to change this widget
ButtonBar(
children: <Widget>[
RaisedButton(
child: Text('add a member'),
onPressed: incrementer,
),
RaisedButton(
child: Text('delete a member'),
onPressed: decrementer,
),
],
),
],
);
}
}
注意:此示例用于演示我的问题。
我知道我可以在incrementer
类中实现decrementer
和HomePage
并将该函数传递给小部件但是根据这种情况无法完成,因为一个RaisedButton
小部件位于小部件树的另一侧。
更新
链接的重复问题与我的问题不同,因为我没有在MemberSection
内AdminSection
实例化
答案 0 :(得分:1)
是的,这是可能的。
最简单的方法是使用InheritedWidget
您可能记得方法of(context)
,例如:
MediaQuery.of(context).size
Navigator.of(context).pop()
Theme.of(context).canvasColor
这些是继承的小部件。您在应用中的任何位置使用of()
,您可以访问您的主题,因为它们是继承的。使用of
方法,您可以在实现窗口小部件树后更改窗口小部件树的状态。
因此,您的示例代码应如下所示:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyApp(),
),
);
}
//this is a newly added stateful widget to use inherited widget
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
void incrementer() {
setState(() {
count++;
});
}
void decrementer() {
setState(() {
count--;
});
}
@override
Widget build(BuildContext context) {
return CounterState(
count: count,
incrementer: incrementer,
decrementer: decrementer,
child: HomePage(),
);
}
}
//this is the inherited widget
class CounterState extends InheritedWidget {
CounterState({Key key, this.count, this.incrementer, this.decrementer, Widget child})
: super(key: key, child: child);
final int count;
final Function incrementer;
final Function decrementer;
@override
bool updateShouldNotify(CounterState oldWidget) {
return count != oldWidget.count;
}
static of(BuildContext context) {
return context.inheritFromWidgetOfExactType(CounterState);
}
}
//make below classes stateless(not must but useless)
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
MemberSection(),
AdminSection()
],
),
);
}
}
class MemberSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterState = CounterState.of(context);
return new Text('${counterState.count} member(s)');
}
}
class AdminSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterState = CounterState.of(context);
return new Column(
children: <Widget>[
Text('${counterState.count} admin(s)'),
ButtonBar(
children: <Widget>[
RaisedButton(child: Text('add a member'), onPressed: counterState.incrementer,),
RaisedButton(child: Text('delete a member'), onPressed: counterState.decrementer,),
],
),
],
);
}
}
可以找到一个很棒的教程here。