[英]how to call child widget function from parent widget
All data is contains in Parent widget and showing in child widget所有数据都包含在父小部件中并显示在子小部件中
I want to call function in child widget when parent state change当父 state 更改时,我想在子窗口小部件中调用 function
child widget function which is stateFull widget子部件 function 是 stateFull 部件
void changeSelectedJodi(i) {
_jodiScrollController.animateTo(50.0 * i,
duration: Duration(seconds: 2), curve: Curves.fastOutSlowIn);
}
Parent widget父部件
child: JodiDataWidget(
this._jodies, <= data is here
this.selectedJodi, <= call function changeSelectedJodi in child widget when change
),
how to achieve this method如何实现这个方法
You still don't want to access your child from your parent.您仍然不想从您的父母那里访问您的孩子。 Flutter control flow goes only one way and there are good reasons for that, which your should respect. Flutter 控制流只有一种方式,这是有充分理由的,您应该尊重这一点。
The question is, then, how can my child know that my parent has changed?那么问题来了,我的孩子怎么知道我的父母变了? For this, you have to update the child from the parent (as always) then use didUdpdateWidget in the child to catch a widget change and react to it.为此,您必须(一如既往)从父级更新子级,然后在子级中使用didUdpdateWidget来捕获小部件更改并对其做出反应。
Here is a small example:这是一个小例子:
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: ParentWidget()));
}
class ParentWidget extends StatefulWidget {
@override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
/// The item of the list to display
///
/// This will be changed randomly by clicking the button
int selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Material(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Center(
child: ChildWidget(
selectedIndex: selectedIndex,
),
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: ElevatedButton(
onPressed: () => setState(() => selectedIndex = Random().nextInt(100)),
child: Center(
child: Text('Press my to move the list'),
),
),
),
],
),
);
}
}
class ChildWidget extends StatefulWidget {
/// The item of the list to display
///
/// Changed randomly by the parent
final int selectedIndex;
const ChildWidget({
Key? key,
required this.selectedIndex,
}) : super(key: key);
@override
State<ChildWidget> createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
/// The colors of the items in the list
final _itemsColors = List.generate(
100,
(index) => getRandomColor(),
);
static Color getRandomColor() =>
Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
final _controller = PageController();
void functionOfChildWidget() {
_controller.animateToPage(
widget.selectedIndex,
duration: Duration(milliseconds: 200),
curve: Curves.easeIn,
);
}
/// Here is the important part: When data is set from the parent,
/// move this widget
@override
void didUpdateWidget(covariant ChildWidget oldWidget) {
// If you want to react only to changes you could check
// oldWidget.selectedIndex != widget.selectedIndex
functionOfChildWidget();
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: 200,
child: PageView.builder(
controller: _controller,
padEnds: false,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(50),
color: _itemsColors[index],
width: 100,
);
},
itemCount: _itemsColors.length,
),
);
}
}
You can use something like this:你可以使用这样的东西:
import 'package:flutter/widgets.dart';
class ChangeCallWidget extends StatefulWidget {
final dynamic value;
final VoidCallback onChange;
final Widget child;
const ChangeCallWidget({
super.key,
required this.value,
required this.onChange,
required this.child,
});
@override
State<ChangeCallWidget> createState() => _ChangeCallWidgetState();
}
class _ChangeCallWidgetState extends State<ChangeCallWidget> {
@override
void didUpdateWidget(oldWidget) {
if (oldWidget.value != widget.value) widget.onChange();
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) => widget.child;
}
And use it like this to monitor changes of the _jodies
and trigger the onChange
if it changes:并像这样使用它来监视_jodies
的变化并在它发生变化时触发onChange
:
ChangeCallWidget(
value: _jodies,
onChange: selectedJodi,
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.