如何使用有状态页面在 Flutter 底部导航栏页面更改时触发回调:实现两个类之间的回调

How to Trigger Callbacks on Flutter Bottom Navigation Bar Page Changes with Stateful Pages: Implementing Callbacks Between Two Classes

提问人:This is the R 提问时间:10/14/2023 最后编辑:This is the R 更新时间:10/15/2023 访问量:58

问:

我有一个带有底部导航栏的 flutter 应用程序,它将页面状态保留在导航中(我使用 go_router)。很长一段时间以来,我一直在尝试在到达该页面后立即在我最喜欢的页面上获得回调。但我不能,所以这里是我想要的大纲:

第 1 页(管理导航):

void _tabChanged() {
   ...
}
...
LazyIndexedStack(
              index: _controller.index,
              children: const [
                Home(),
                Fav(), // it should be sent the callback, linked with tabChanged()
              ],
            ),

对于该页面,您必须收到回调:

const Fav({Key? key, required this.callback}) : super(key: key);
...
widget.callback() {
... here I receive the callback from tab.dart
}
Flutter dart 回调 状态

评论


答:

0赞 PurplePolyhedron 10/14/2023 #1

我假设您希望导航栏调用 .您可以使用State<Fav>GlobleKey

import 'package:flutter/material.dart';

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    final key = GlobalKey();
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        MyWidget(key: key),
        ElevatedButton(
            onPressed: () {
              (key.currentState as _MyWidgetState).change();
            },
            child: const Text("Change"))
      ],
    );
  }
}

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int counter = 0;
  void change() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text("Counter: $counter");
  }
}

或者你可以传递一个 ,订阅它,并在导航栏中触发回调。ListenableFav

import 'package:flutter/material.dart';

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  late ChangeNotifier notifier;

  @override
  void initState() {
    super.initState();
    notifier = ChangeNotifier();
  }

  @override
  void dispose() {
    notifier.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        MyWidget(notifier: notifier),
        ElevatedButton(onPressed: notifier.notifyListeners, child: const Text("Change"))
      ],
    );
  }
}

class MyWidget extends StatefulWidget {
  final ChangeNotifier notifier;
  const MyWidget({super.key, required this.notifier});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int counter = 0;
  void change() {
    setState(() {
      counter++;
    });
  }

  @override
  void initState() {
    super.initState();
    widget.notifier.addListener(change);
  }

  @override
  void dispose() {
    widget.notifier.removeListener(change);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text("Counter: $counter");
  }
}

但是,最佳做法是将逻辑与小部件树分开,而不是在State

0赞 This is the R 10/15/2023 #2

非常感谢PurplePolyhedron,我收到了一个错误,所以这是我最后的做法:

GlobalKey<FavState> key = GlobalKey<FavState>();
void _handleTabChanged() {
  if (_tabController.index == 1) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (key.currentState != null) {
        key.currentState!.test();
      }
    });
  }
  ...
}
...
LazyIndexedStack(
  index: _controller.index,
    children: [
      const Home(),
      Fav(
        key: key,
      ),
    ],
),

在“收藏夹”页面中:

void test() {
    setState(() {
      ...
    });
  }