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

webghufk  于 2023-10-22  发布在  Flutter
关注(0)|答案(2)|浏览(119)

我有一个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
}
q0qdq0h2

q0qdq0h21#

我假设您希望导航栏调用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");
  }
}

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

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中执行所有操作

f8rj6qna

f8rj6qna2#

非常感谢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,
      ),
    ],
),

在Fav页面:

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

相关问题