All data is contains in Parent widget and showing in child widget
I want to call function in child widget when parent state change
child widget function which is stateFull widget
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
CodePudding user response:
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.
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.
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,
),
);
}
}