简体   繁体   English

如何从父小部件调用子小部件 function

[英]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.

相关问题 如何从子小部件调用父小部件中的 function | Flutter - How to Call a function in parent widget from child widget | Flutter 如何从 Flutter 中的子小部件调用父小部件 function - How to call parent widget function from child widget in Flutter 如何从父小部件调用子小部件的 setState? - How can I call setState of a child widget from a parent widget? Flutter - 如何从子小部件调用父小部件函数,同时还使用变量保持状态? - Flutter - How do I call a Parent widget function from child widget while also maintaining the state with a variable? 如何从父小部件在子有状态小部件内运行函数? - How to run a function inside a child stateful widget from parent widget? 每次重建子小部件时调用父小部件的 function - call a function of a parent widget each time when a child widget is rebuilt Flutter:当小部件没有父/子关系时,如何从小部件 B 调用小部件 A 中的 function? - Flutter: How do I call a function in widget A from widget B when the widgets do not have a parent/child relationship? Flutter - 如何从父级调用子级小部件的方法 - Flutter - how to call child widget's method from parent 如何从父级调用另一个小部件的子方法 - How to call child method from parent for another widget Flutter:如何从子小部件更新子(和父)小部件的 state(父小部件得到更新,子小部件没有) - Flutter: How to update state of child (and parent) widget from child widget (parent widget gets update, child does not)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM