我有一个自定义的底部导航栏,在我的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()
],
),
),
),
),
);
型
我希望这对你有帮助谢谢
1条答案
按热度按时间ohfgkhjo1#
在底部导航栏中,所有页面都是主容器的子容器。如果您停留在父容器上,则可以从任何子容器访问底部导航。我正在与您分享一个示例
字符串
不要使用“导航器”来导航底部导航页面。底部导航是通过视图更改进行导航,如示例
在导航到其他屏幕时不要使用推送替换。推送替换将当前屏幕替换为目标屏幕,并且您无法返回到父屏幕。只能使用如下示例中的推送
型