从侧抽屉颤动改变脚手架主体

问题描述 投票:0回答:2

我正在尝试从 Flutter 的侧抽屉更改 Scaffold 主体的内容。我正在使用不同的文件来存储侧面导航栏和新的正文内容。

我创建了一个带有类 NavigationController 的单独文件,其中包含一个静态变量,用于让小部件显示在脚手架的主体中。

我使用不同的文件来更好地组织。

提前致谢,非常感谢任何建议。

当我使用打印功能进行测试时,变量正在更新。

如果我按下页面上执行设置状态的按钮,我还可以在单击侧面导航栏中的按钮后更改屏幕内容。

所以看起来我在按下侧面导航栏中的按钮时执行的设置状态并没有刷新主页。

主要应用程序:

import 'package:flutter/material.dart';
import 'package:playground/sidenav.dart';
import 'package:playground/pagecontroller.dart';

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const SideNav(),
      appBar: AppBar(),
      body: NavigationController.currentPage,
    );
  }
}

导航控制器:

import 'package:flutter/material.dart';

class NavigationController {
  static Widget currentPage = const Text("Hello World");
}

侧抽屉小部件:

import 'package:flutter/material.dart';
import 'package:playground/pagecontroller.dart';
import 'package:playground/newbody.dart';

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

  @override
  State<SideNav> createState() => _SideNavState();
}

class _SideNavState extends State<SideNav> {
  @override
  Widget build(BuildContext context) {
    return Drawer(
        child: ListView(children: <Widget>[
      ListTile(
          title: const Text('Page 1'),
          onTap: () {
            setState(() {
              NavigationController.currentPage = const NewBody();
              Navigator.pop(context);
            });
          })
    ]));
  }
}
flutter navigation-drawer
2个回答
0
投票

希望你一切都好。

setState is refreshing `SideNav` and not the main widget.

你必须使用更好的解决方案,尝试阅读有关状态管理和提供者的内容。

推荐使用Flutter提供者Flutter cubit 您可以通过创建一个带有侦听器的主页来实现这一点 -> 观察来自提供者的任何更改并使用新的小部件重新加载小部件。


0
投票

这是一个示例代码片段,它替换抽屉项目单击上的主体:

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

  @override
  State<MainDrawerScreen> createState() => _MainDrawerScreenState();
}

class _MainDrawerScreenState extends State<MainDrawerScreen> {
  Widget currentPage = const Page0();

  void _onDrawerItemClick({required int clickedIndex}) {
    setState(() {
      switch (clickedIndex) {
        case 0:
          currentPage = const Page0();
          break;
        case 1:
          currentPage = const Page1();
          break;
        default:
          currentPage = const Page0();
          break;
      }
    });
  }

  //This screen acts as a container of different pages and it also provides
  //the common appBar. So children pages should not contain an appBar
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: currentPage(),  
      ),
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text("Common title: Can be changed based on current page"),
      ),
      drawer: MainDrawer(onDrawerItemClick: _onDrawerItemClick),
    );
  }
}

MainDrawer
小部件应如下所示:

class MainDrawer extends StatelessWidget {
  const MainDrawer({super.key, required this.onDrawerItemClick});

  final void Function({required int clickedIndex}) onDrawerItemClick;

  @override
  Widget build(BuildContext context) {
    return Drawer(
      // Add a ListView to the drawer. This ensures the user can scroll
      // through the options in the drawer if there isn't enough vertical
      // space to fit everything.
      child: ListView(
        // Important: Remove any padding from the ListView.
        padding: EdgeInsets.zero,
        children: [
          DrawerHeader(
            decoration: BoxDecoration(
              color: Theme.of(context).colorScheme.inversePrimary,
            ),
            child: Text("Put your design here"),
          ),
          ListTile(
            title: const Text('Page 0'),
            onTap: () {
              onDrawerItemClick(clickedIndex: 0);
              Navigator.pop(context);
            },
          ),
          ListTile(
            title: const Text('Page 1'),
            onTap: () {
              onDrawerItemClick(clickedIndex: 1);
              Navigator.pop(context);
            },
          ),
        ],
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.