dart 底部导航栏在Flutter应用程序的所有页面中不持久

dxpyg8gm  于 2023-11-14  发布在  Flutter
关注(0)|答案(1)|浏览(111)

我有一个自定义的底部导航栏,在我的Flutter应用程序中工作得很好。
然而,在日历屏幕上我有一个按钮,导航到“添加预约”屏幕。我不是使用底部导航栏导航到这个屏幕,而只是一个按钮。
当我进入“添加约会”屏幕时,底部导航栏消失,当我返回日历屏幕时,底部导航栏仍然缺失。
如何在所有屏幕上保持此状态?
下面是我的底部导航条形码:

class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
  CustomAppBar({Key? key})
      : preferredSize = const Size.fromHeight(kToolbarHeight),
        super(key: key);

  @override
  final Size preferredSize; // default is 56.0

  @override
  _CustomAppBarState createState() => _CustomAppBarState();
}

class _CustomAppBarState extends State<CustomAppBar> {
  final auth = FirebaseAuth.instance; // Need this to logout

  Future<void> signOut() async {
    await auth.signOut();
  }

  @override
  Widget build(BuildContext context) {
    return AppBar(
      //automaticallyImplyLeading: false, // removes the back button in appbar
      title: const Text("Deal Diligence"),
      actions: [
        IconButton(
          onPressed: () {
            signOut();
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => LoginScreen()));
          },
          icon: const Icon(Icons.logout),
        )
      ],
    );
  }
}

字符串
下面是我实现底部导航栏的代码:

class MainScreenState extends State<MainScreen> {
  final auth = FirebaseAuth.instance;
  int _pageIndex = 0;

  final List<Widget> appScreens = [
    const CompanyDashboardScreen(),
    const TransactionDetailScreen(),
    const AppointmentCalendarScreen(),
    const UserProfileScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //appBar: CustomAppBar(),
      body: Container(
        child: appScreens.elementAt(_pageIndex),
      ),
      bottomNavigationBar: BottomNav(
        // Navigation Bar widget
        selectedPage: _pageIndex,
        onDestinationSelected: (index) {
          setState(() {
            _pageIndex = index;
          });
        },
      ),
    );
  }

  // Added this for BottomNavigationBar sync
  void setIndex(int index) {
    if (mounted) setState(() => this._pageIndex = index);
  }
}


谢谢你能给我的任何帮助给予。

更新:

我将代码修改为类似于第一个答案,但我仍然得到与原始帖子相同的行为。下面是新代码:

class MainScreenState extends State<MainScreen> {
  final auth = FirebaseAuth.instance;
  int _pageIndex = 0;

  final List<Widget> appScreens = [
    const CompanyDashboardScreen(),
    const TransactionDetailScreen(),
    const AppointmentCalendarScreen(),
    const UserProfileScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: appScreens[_pageIndex],
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.blueAccent,
        selectedIconTheme: const IconThemeData(color: Colors.white),
        selectedItemColor: Colors.white,
        unselectedItemColor: Colors.black45,
        type: BottomNavigationBarType.fixed,
        currentIndex: _pageIndex,
        onTap: (value) {
          setState(() {
            _pageIndex = value;
          });
        },
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
          BottomNavigationBarItem(
              icon: Icon(Icons.add_business_outlined), label: "Trxn"),
          BottomNavigationBarItem(
              icon: Icon(Icons.calendar_today), label: "Calendar"),
          BottomNavigationBarItem(icon: Icon(Icons.people), label: "Profile"),
        ],
      ),
    );
  }

更新#2:

下面是我单击按钮并转到“添加事件”页面的代码:

return Scaffold(
      appBar: CustomAppBar(),
      backgroundColor: Colors.white,
      resizeToAvoidBottomInset: false,
      body: Column(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          StreamBuilder<QuerySnapshot>(
            stream: _db
                .collection('users')
                .doc(ref.read(globalsNotifierProvider).currentUserId)
                .collection('events')
                .where('eventDate', isGreaterThanOrEqualTo: kFirstDay)
                .where('eventDate', isLessThanOrEqualTo: kLastDay)
                .snapshots(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              // Handle any errors
              if (snapshot.hasError) {
                return Center(
                  child: Text('Error fetching data: ${snapshot.error}'),
                );
              }

              // Handle loading data
              debugPrint('Data: ${snapshot.data}');
              if (snapshot.connectionState == ConnectionState.waiting) {
                return const Center(child: CircularProgressIndicator());
              } else {
                if (snapshot.hasData && snapshot.data!.docs.isNotEmpty) {
                  List<Events> eventsList = [];
                  for (var snapshotEvent in snapshot.data!.docs) {
                    Events event =
                        Events.fromJson(snapshotEvent.id, snapshotEvent.data());
                    eventsList.add(event);
                  }
                  return _buildTableCalendar(eventsList);
                } else {
                  return _buildTableCalendar();
                }
              }
            },
          ),
          const SizedBox(height: 8.0),
          //_buildButtons(),
          ElevatedButton(
            onPressed: () async {
              setState(() {
                showSpinner = true;
              });
              try {
                ref.read(globalsNotifierProvider.notifier).updatenewEvent(true);

                Navigator.of(context).pushReplacement(
                    MaterialPageRoute(builder: (context) => AddEventScreen()));

                setState(() {
                  showSpinner = false;
                });
              } catch (e) {
                // todo: add better error handling
                print(e);
              }
            },
            child: const Text('Add Event'),
          ),
          const SizedBox(height: 8.0),
          Expanded(child: _buildEventList()),
        ],
      ),
    );


下面是下一页的代码,“添加事件”:

return Scaffold(
      appBar: CustomAppBar(),
      backgroundColor: Colors.white,
      body: SafeArea(
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Column(
              children: <Widget>[
                const Text(
                  'Event Editor',
                  style: TextStyle(
                    fontSize: 30,
                    fontWeight: FontWeight.w800,
                  ),
                ),
                const SizedBox(
                  height: 30.0,
                ),
                TextField(
                  controller: eventNameController,
                  autofocus: true,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    ref
                        .read(eventsNotifierProvider.notifier)
                        .updateEventname(value);
                  },
                  decoration: const InputDecoration(
                      hintText: 'Event Name', labelText: 'Event Name'),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: eventDurationController,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    ref
                        .read(eventsNotifierProvider.notifier)
                        .updateEventDuration(value);
                  },
                  decoration: const InputDecoration(
                      hintText: 'Duration', labelText: 'Duration'),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: eventDateController,
                  keyboardType: TextInputType.datetime,
                  textAlign: TextAlign.center,
                  onTap: () async {
                    DateTime? _datePicked = await showDatePicker(
                        context: context,
                        initialDate: _selectedDate!,
                        firstDate: DateTime(2023),
                        lastDate: DateTime(2026));
                    if (_date != null && _date != _datePicked) {
                      setState(() {
                        eventDateController.text =
                            DateFormat("MM/dd/yyyy").format(_datePicked!);
                        ref
                            .read(eventsNotifierProvider.notifier)
                            .updateEventDate(_datePicked);
                        _selectedDate = _datePicked;
                        //DateFormat("MM/dd/yyyy").format(_date));
                      });
                    }
                  },
                  onChanged: (value) {
                    ref
                        .read(eventsNotifierProvider.notifier)
                        .updateEventDate(_date);
                  },
                  decoration: const InputDecoration(
                    hintText: 'Date',
                    labelText: 'Date',
                  ),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: eventStartTimeController,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onTap: () async {
                    final TimeOfDay? _timePicked = await showTimePicker(
                      context: context,
                      initialTime: TimeOfDay.now(),
                    );
                    if (_timePicked != null) {
                      _dt = DateTime(
                        _selectedDate.year,
                        _selectedDate.month,
                        _selectedDate.day,
                        _timePicked.hour,
                        _timePicked.minute,
                      );
                      setState(() {
                        eventStartTimeController.text =
                            DateFormat('h:mm a').format(_dt);
                        ref
                            .read(eventsNotifierProvider.notifier)
                            .updateeventStartTime(_dt);
                      });
                    }
                  },
                  onChanged: (value) {
                    ref
                        .read(eventsNotifierProvider.notifier)
                        .updateeventStartTime(_dt);
                  },
                  decoration: const InputDecoration(
                    hintText: 'Start Time',
                    labelText: 'Start Time',
                  ),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: eventDescriptionController,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    // ref
                    //     .read(eventsNotifierProvider.notifier)
                    //     .updateEventDescription(value);
                  },
                  decoration: const InputDecoration(
                      hintText: 'Description', labelText: 'Description'),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                RoundedButton(
                  title: 'Save Event',
                  colour: Colors.blueAccent,
                  onPressed: () async {
                    setState(() {
                      showSpinner = true;
                    });
                    try {
                      ref
                          .read(globalsNotifierProvider.notifier)
                          .updatenewEvent(true);
                      if (currentEventId != null && currentEventId != '') {
                        ref.read(eventsNotifierProvider.notifier).saveEvent(
                            ref.read(eventsNotifierProvider), currentEventId);
                      } else {
                        ref
                            .read(eventsNotifierProvider.notifier)
                            .updateEventDescription(
                                eventDescriptionController.text);

                        ref.read(eventsNotifierProvider.notifier).saveEvent(
                            ref.read(eventsNotifierProvider),
                            eventDescriptionController
                                .text); // Create new event
                      }
                      Navigator.of(context).pushReplacement(MaterialPageRoute(
                          builder: (context) =>
                              const AppointmentCalendarScreen()));

                      setState(() {
                        showSpinner = false;
                      });
                    } catch (e) {
                      // todo: add better error handling
                      print(e);
                    }
                  },
                ),
                const SizedBox(
                  height: 8.0,
                ),
                (widget != null)
                    ? RoundedButton(
                        title: 'Delete',
                        colour: Colors.red,
                        onPressed: () async {
                          setState(() {
                            showSpinner = true;
                          });
                          try {
                            ref
                                .read(eventsNotifierProvider.notifier)
                                .deleteEvent(currentEventId);
                            Navigator.of(context).pushReplacement(
                                MaterialPageRoute(
                                    builder: (context) =>
                                        AppointmentCalendarScreen()));

                            setState(() {
                              showSpinner = false;
                            });
                          } catch (e) {
                            // todo: add better error handling
                            print(e);
                          }
                        },
                      )
                    : Container()
              ],
            ),
          ),
        ),
      ),
    );


我希望这对你有帮助谢谢

ohfgkhjo

ohfgkhjo1#

在底部导航栏中,所有页面都是主容器的子容器。如果您停留在父容器上,则可以从任何子容器访问底部导航。我正在与您分享一个示例

class BottomNavigationExample extends StatefulWidget {
  const BottomNavigationExample({Key? key}) : super(key: key);

  @override
  _BottomNavigationExampleState createState() =>
      _BottomNavigationExampleState();
}

class _BottomNavigationExampleState extends State {
  int _selectedTab = 0;

  List _pages = [
    HomePage(),
    AboutPage(),
    ProductPage(),
    ContactPage(),
    SettingsPage(),
  ];

  _changeTab(int index) {
    setState(() {
      _selectedTab = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: _pages[_selectedTab],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedTab,
        onTap: (index) => _changeTab(index),
        selectedItemColor: Colors.red,
        unselectedItemColor: Colors.grey,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "About"),
          BottomNavigationBarItem(
              icon: Icon(Icons.grid_3x3_outlined), label: "Product"),
          BottomNavigationBarItem(
              icon: Icon(Icons.contact_mail), label: "Contact"),
          BottomNavigationBarItem(
              icon: Icon(Icons.settings), label: "Settings"),
        ],
      ),
    );
  }
}

字符串
不要使用“导航器”来导航底部导航页面。底部导航是通过视图更改进行导航,如示例
在导航到其他屏幕时不要使用推送替换。推送替换将当前屏幕替换为目标屏幕,并且您无法返回到父屏幕。只能使用如下示例中的推送

Navigator.of(context).push(
                    MaterialPageRoute(builder: (context) => AddEventScreen()));

相关问题