You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter添加BottomNavigator后ReminderPage控件失效及背景异常求助

Flutter按钮无法点击+背景异常问题排查

我是Flutter新手,开发应用时遇到如下问题:原本ReminderPage上的“Add Reminder”按钮可正常跳转至AddReminder页面,在MainPage中添加BottomNavigator后,从HomePage进入ReminderPage时,该按钮与主题切换图标均无法点击,且背景突然变为蓝色。以下是相关代码及效果截图,恳请帮忙排查问题。

ReminderPage代码

import 'package:date_picker_timeline/date_picker_timeline.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:medreminder/Reminder/services/notification_services.dart';
import 'package:medreminder/Reminder/services/theme_services.dart';
import 'package:intl/intl.dart';
import 'package:medreminder/Reminder/ui/theme.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';
import 'package:medreminder/Reminder/ui/widgets/button.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';

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

  @override
  State<ReminderHomePage> createState() => _ReminderHomePageState();
}

class _ReminderHomePageState extends State<ReminderHomePage> {
  DateTime _selectedDate = DateTime.now();
  var notifyHelper;
  @override
  void initState() {
    super.initState();
    notifyHelper=NotifyHelper();
    notifyHelper.initializeNotification();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: _appBar(),
      backgroundColor: context.theme.backgroundColor,
      body: Column(
        children: [
          _addTaskBar(),
          _addDateBar(),
        ],
        ),
    );
  }
  _addDateBar(){
    return Container(
            margin: const EdgeInsets.only(top: 20, left: 20),
            child: DatePicker(
              DateTime.now(),
              height: 100,
              width: 80,
              initialSelectedDate: DateTime.now(),
              selectionColor: Color(0xFFAAB6FB),
              selectedTextColor: Colors.white,
              dateTextStyle: GoogleFonts.lato(
                textStyle: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.w600,
                    color:Colors.grey
                ),
              ),
              dayTextStyle: GoogleFonts.lato(
                textStyle: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                    color:Colors.grey
                ),
              ),
              monthTextStyle: GoogleFonts.lato(
                textStyle: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    color:Colors.grey
                ),
              ),
              onDateChange: (date){
                    _selectedDate=date;
              },
            ),
          );
  }
  _addTaskBar(){
    return Container(
            margin: const EdgeInsets.only(left: 20, right: 20, top: 5),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Container(
                  margin: const EdgeInsets.symmetric(horizontal: 20),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(DateFormat.yMMMMd().format(DateTime.now()),
                      style: subHeadingStyle,
                      ),
                      Text("Today", 
                      style: headingStyle,
                      )
                    ],
                  ),
                ),
                MyButton(label: "Add Reminder", onTap: ()=>Get.to(AddReminderPage()))
              ],
            ),
          );
  }

  _appBar(){
    return AppBar(
      elevation: 0,
      backgroundColor: context.theme.backgroundColor,
      leading: GestureDetector(
        onTap: (){
            ThemeService().switchTheme();
            notifyHelper.displayNotification(
              title:"Theme Changed!",
              body: Get.isDarkMode?"Activated Light Theme!":"Activated Dark Theme!"
            );

            notifyHelper.scheduledNotification();
        },
        child: Icon(Get.isDarkMode ?Icons.wb_sunny_outlined:Icons.nightlight_round,
        size: 20,
          color:Get.isDarkMode ? Colors.white:Colors.black
        ),
      ),
      actions: [
        CircleAvatar(
          backgroundImage: AssetImage(
            "images/profile.png"
          ),
        ),
        SizedBox(width: 20,),
      ],
    );
  }
}

BottomNavigator代码

import 'package:flutter/material.dart';
import 'package:medreminder/Reminder/ui/home_reminder.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';
import 'package:medreminder/home_page.dart';
import 'package:medreminder/profile_page.dart';
import 'package:medreminder/settings_page.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:medreminder/Reminder/ui/theme.dart';

void main() => runApp(MaterialApp(home: MainPage()));

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

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  List <Widget> pages = [
    HomePage(),
    SettingPage(),
    ProfilePage()
  ];
  int currentIndex = 0;
  void onTap(int index){
    setState(() {
      currentIndex = index;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      
      body: Container(
        width: MediaQuery.of(context).size.width,
        child: pages[currentIndex]
      ),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.shifting,
        onTap: onTap,
        currentIndex: currentIndex,
        selectedItemColor: bluishClr,
        unselectedItemColor: Colors.black,
        showUnselectedLabels: false,
        showSelectedLabels: false,
        items: [
          BottomNavigationBarItem(label: "Home", icon: Icon(Icons.home)),
          BottomNavigationBarItem(label: "Settings", icon: Icon(Icons.settings)),
          BottomNavigationBarItem(label: "Profile", icon: Icon(Icons.account_circle)),
          
        ],
      ),
    );
  }
}

HomePage代码

import 'package:flutter/material.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_navigation/get_navigation.dart';
import 'Reminder/ui/home_reminder.dart';
import 'Reminder/ui/widgets/button.dart';

void main() {
  runApp(const HomePage());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Medicine Reminder App'),
        ),
        body: Column(children: [
          Stack(
            children: [
              Image.asset(
                'images/MenuImg.jpg',
                width: 600,
                height: 200,
                fit: BoxFit.cover,
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TextButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.black)),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const ReminderHomePage()),
                );
                },
                child: Text("Button1"),
              ),
              TextButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.black)),
                onPressed: () {},
                child: Text("Button2"),
              ),
              TextButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.black)),
                onPressed: () {},
                child: Text("Button3"),
              ),
            ],
          )
        ]),
      ),
    );
  }
}

效果截图

  • 仅运行ReminderPage时应用正常:正常状态截图
  • 添加BottomNavigator后的异常状态:异常状态截图

问题分析与解决方案

核心问题

  1. 嵌套App上下文冲突:HomePage本身是GetMaterialApp,又被嵌套在MainPage的MaterialApp里,导致路由、主题的上下文混乱——ReminderPage用Get.to()跳转时找不到正确的GetX上下文,按钮点击事件失效;同时context.theme.backgroundColor获取的是外层MaterialApp的默认主题,出现背景变蓝的问题。
  2. 路由方式不统一:HomePage用Navigator.push,ReminderPage用Get.to(),两种路由体系混用加剧了上下文冲突。

修复步骤

1. 统一根App为GetMaterialApp

修改MainPage的main方法,把MaterialApp换成GetMaterialApp,确保整个应用只有一个根App:

void main() => runApp(GetMaterialApp(home: MainPage()));
2. 移除HomePage中的嵌套GetMaterialApp

HomePage不需要作为独立App,改成普通StatelessWidget:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Medicine Reminder App'),
      ),
      body: Column(children: [
        Stack(
          children: [
            Image.asset(
              'images/MenuImg.jpg',
              width: 600,
              height: 200,
              fit: BoxFit.cover,
            ),
          ],
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            TextButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.black)),
              onPressed: () {
                // 统一用GetX路由跳转
                Get.to(const ReminderHomePage());
              },
              child: const Text("Button1", style: TextStyle(color: Colors.white)),
            ),
            TextButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.black)),
              onPressed: () {},
              child: const Text("Button2", style: TextStyle(color: Colors.white)),
            ),
            TextButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.black)),
              onPressed: () {},
              child: const Text("Button3", style: TextStyle(color: Colors.white)),
            ),
          ],
        )
      ]),
    );
  }
}
3. 确保路由跳转全用GetX方法

ReminderPage里的Get.to()保持不变,HomePage的跳转也改成Get.to(),彻底统一路由体系。

这样修改后,App的上下文层级清晰,路由和主题都由GetX统一管理,按钮点击和背景颜色的问题就能解决。

内容的提问来源于stack exchange,提问作者NyK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:01:14