Flutter: Combine Drawer and BottomNav in PageView - flutter

I would like to have a bottomNavBar and a Drawer at the same time, which are supposed to lead to different pages. In my PageView there are a few Screens, which are, so I thought, accessible
if I call the pageController's function to change the page with the correct index.
Now the tricky part: I only use 3 out of these 6 in my
BottomNav and they work just fine. But I was thinking that
it has to be possible to access the other ones too,
if I get the correct index, i.e. I want to access the other screens/indices
with the drawer.
However, if I use the _pageController.jumpToPage(int page)
command with any index greater than 2, I get the following error:
'0 <= currentIndex && currentIndex < items.length': is not true.
Any ideas what I am missing?
Edit:
class _MainScreenState extends State<MainScreen> {
var _pageController = PageController();
int _page = 0;
List drawerItems = [
{"icon": Icons.add,"name": "Feed",},
{"icon": Icons.delete, "name": "Your Feed",},
{"icon": Icons.delete, "name": "test1",},
{"icon": Icons.delete, "name": "test2",},
{"icon": Icons.delete, "name": "test3",},
];
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => Dialogs().showExitDialog(context),
child: Scaffold(
body: _buildPageView(),
bottomNavigationBar: _buildBottomNavigation(),
drawer: _buildDrawer(),
),
);
}
PageView _buildPageView(){
return PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: onPageChanged,
children: const [
Test1Screen(),
Test2Screen(),
Test3Screen(),
Test4Screen(),
Test5Sreen(),
Test6Screen()
],
);
}
void navigationTapped(int page) {
_pageController.jumpToPage(page);
}
#override
void initState() {
super.initState();
_pageController = PageController(initialPage: 0);
}
#override
void dispose() {
super.dispose();
_pageController.dispose();
}
void onPageChanged(int page) {
print(page);
setState(() {
this._page = page;
});
}
BottomNavigationBar _buildBottomNavigation(){
return BottomNavigationBar(
backgroundColor: Theme.of(context).primaryColor,
selectedItemColor: Theme.of(context).accentColor,
unselectedItemColor: Colors.grey[500],
elevation: 20,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
FeatherIcons.home,
),
label: "Test1"
),
BottomNavigationBarItem(
icon: Icon(
FeatherIcons.compass,
),
label: "Test2"
),
BottomNavigationBarItem(
icon: Icon(
FeatherIcons.settings,
),
label: "Test3"
),
],
onTap: navigationTapped,
currentIndex: _page,
);
}
Drawer _buildDrawer(){
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
child: const Center(
child: Text("Header Area"),
),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor
),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: drawerItems.length,
itemBuilder: (BuildContext context, int index){
Map item = drawerItems[index];
return _buildDrawerListTile(item,index);
})
],
),
);
}
Widget _buildDrawerListTile(Map item, int index){
return ListTile(
leading: Icon(
item['icon'],
color: _page == index
?Theme.of(context).primaryColorLight
: Theme.of(context).primaryColorDark
),
title: Text(
item["name"],
style: TextStyle(
color: _page == index
?Theme.of(context).primaryColorLight
:Theme.of(context).primaryColorDark
)
),
onTap: (){
navigationTapped;
},
);
}
}

Related

How to add scroll into bottom navigation bar items

I have implemented an app that navigates through a few screens. I have added the bottom navigation bar and 1st tab I add a page with list view items with sqlflite data.I can't scroll list view data. other tabs I have added to show another screen.
code is below.
//this is my homepage screen
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late List<LeaveModel> _leaveList = [];
final _userService = LeaveService();
int _selectedIndex = 0;
#override
void initState() {
getAllUserDetails();
super.initState();
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
I have create botom navigation bar with 4 item.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.menu),
onPressed: () {},
),
title: const Text('Leave Tracker'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.notifications),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.add_box),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AddLeave()))
.then((data) {
if (data != null) {}
getAllUserDetails();
});
},
)
],
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.man),
label: 'All',
),
BottomNavigationBarItem(
icon: Icon(Icons.sick_rounded),
label: 'Sick',
),
BottomNavigationBarItem(
icon: Icon(Icons.holiday_village),
label: 'Casual',
),
BottomNavigationBarItem(
icon: Icon(Icons.weekend),
label: 'Other',
),
],
),
From this 4 items goto different 3 screens.1st item link to same page.(HomePage())
body: Center(
child: _selectedIndex == 0
? myListView(context)
: _selectedIndex == 1
? AllSickLeave()
: _selectedIndex == 2
? AllCasualLeave()
: ViewOtherLeave(),
),
);
}
In HomePage() i have add listview and data taking from sqlflite database.
getAllUserDetails() async {
var users = await _userService.readAllLeave();
_leaveList = <LeaveModel>[];
users.forEach((leave) {
setState(() {
var leaveModel = LeaveModel();
leaveModel.id = leave['id'];
leaveModel.leaveType = leave['leaveType'];
leaveModel.leaveStartDate = leave['leaveStartDate'];
leaveModel.leaveEndDate = leave['leaveEndDate'];
leaveModel.reason = leave['reason'];
leaveModel.leaveDays = leave['leaveDays'];
_leaveList.add(leaveModel);
});
});
}
Widget myListView(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 5.0,
),
Text(
'All Leave Details',
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
ListView.builder(
shrinkWrap: true,
itemCount: _leaveList.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(
'Leave Type : ${_leaveList[index].leaveType ?? ''}'),
subtitle: Text('Reason : ${_leaveList[index].reason}'),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.edit,
color: Colors.teal,
)),
IconButton(
onPressed: () {},
icon: Icon(
Icons.delete,
color: Colors.red,
)),
],
),
),
);
}),
],
),
),
);
}
}
You dont need to have multiple scaffold, and try this format
Widget myListView(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.only(top: 25),
itemCount: _leaveList.length + 1,
itemBuilder: (context, index) {
if (index == 0)
return Text(
'All Leave Details',
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
);
return Card(
child: ListTile(

Why FutureBuilder re-build every time?

I'm working with FutureBuilder and I initialize _future in InitState as mentioned here.
Despite this, FutureBuilder re-build itself every time I switch page with the BottomNavigationBar.
Code Sample:
class _HomeViewState extends State<HomeView> {
late final Future<List<DocumentSnapshot<Object?>>> _futureSerieA;
#override
void initState() {
super.initState();
_futureSerieA = getScheduled("Serie A");
}
#override
Widget build(BuildContext context) {
return SizedBox.expand(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0,0,0,0),
child: Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.transparent)
)
),
child: Theme(
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
child: FutureBuilder(
future: _futureSerieA,
builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if (snapshot.hasData) {
List<String> scheduled = [];
for (var DOC in snapshot.data!) {
scheduled.add(DOC.id);
}
return ...
How could I disable FutureBuilder re-build when browsing between pages of BottomNavigationBar?
BottomNavBar:
class _LoggedHandleState extends State<LoggedHandle> {
);
double height = AppBar().preferredSize.height;
int _selectedPage = 1;
final _pageOptions = [
const BetView(),
const HomeView(),
const UserView()
];
#override
Widget build(BuildContext context) {
return Scaffold(
...
),
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.white60,
backgroundColor: Colors.red,
selectedItemColor: Colors.white,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.receipt),
label: 'Schedina',
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Account',
),
]),
body: _pageOptions[_selectedPage],
);
}
}
When browsing between pages of bottom navigation bar, your state is not maintained. This behaviour causes the widget to rebuild every time.
You can use Indexed Stack https://api.flutter.dev/flutter/widgets/IndexedStack-class.html
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
onTap: (index) {
setState(() {
current_tab = index;
});
},
currentIndex: current_tab,
items: [
BottomNavigationBarItem(
...
),
BottomNavigationBarItem(
...
),
],
),
body: IndexedStack(
children: <Widget>[
PageOne(),
PageTwo(),
],
index: current_tab,
),
);
}
Although this is the best solution, it will load all your widgets once the IndexedStack is loaded.
I found a Lazy Loading Indexed Stack util to load your widgets when and only the first time they are created https://github.com/okaryo/lazy_load_indexed_stack

how to access PageViewController outside of widget

TabScreen is my main widget in my app that includes a BottomNavigationBar and a PageView to transition between pages.
PageController allows me to change views and everything is fine here, but there is one thing missing. How can I change my PageView controller outside of TabScreen? I'd like to put a button to access my main PageView controller from within my pages.
class _TabsScreenState extends State<TabsScreen> {
bool _isloading = true;
int? _selectedIndex;
List<Widget>? _pages = [
HomeScreen(),
CurrenPlanDetail(),
Container(),
ProfileScreen(),
SettingScreens(),
];
PageController? _pageController;
#override
void initState() {
_selectedIndex = 0;
_pageController = PageController(initialPage: _selectedIndex!);
}
}
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
children: _pages!,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: Visibility(
visible: !_isloading,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: kNewPurple,
//unselectedItemColor: Colors.grey,
currentIndex: _selectedIndex!,
onTap: (value) {
setState(() {
_selectedIndex = value;
_pageController!.jumpToPage(_selectedIndex!);
});
},
backgroundColor: Colors.grey[300],
items: [
BottomNavigationBarItem(
icon: Icon(
Ionicons.home_outline,
size: 15.sp,
),
label: 'Home'),
BottomNavigationBarItem(
icon: Icon(
Ionicons.reader_outline,
size: 15.sp,
),
label: 'Plan'),
BottomNavigationBarItem(
icon: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
fixedSize: Size(50, 50),
),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return FloatingButton();
});
},
child: Icon(Ionicons.add)),
label: ''),
BottomNavigationBarItem(
icon: Icon(
Ionicons.happy_outline,
size: 15.sp,
),
label: 'Profile'),
BottomNavigationBarItem(
icon: Icon(
Ionicons.settings_outline,
size: 15.sp,
),
label: 'Setting'),
],
),
),
);
}
}
for example, somewhere in my app, I'd like to put a button and pass a function like this :
_pageController!.jumpToPage(1);
Define PageController as static and
TabScreen.pageController.jumpToPage(1);

Create two custom buttons inside Bottom Navigation Bar to control four pages using page view

I want to control four pages using two arrows on the bottom navigation bar, and in the middle of these two arrow buttons I have a counter to show the ID of the page. Like the image below:
I'm using modular route to change the pages, but I don't know how can I do that using only two buttons, and don't have idea how can I put the counter in the middle of this two buttons. Any suggestion?
class _CreateAccountPageState
extends ModularState<CreateAccountPage, CreateAccountController> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: controller.pageViewController,
children: [
RouterOutlet(),
RouterOutlet(),
RouterOutlet(),
RouterOutlet()
],
),
bottomNavigationBar: AnimatedBuilder(
animation: controller.pageViewController,
builder: (context, snapshot) {
return BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
elevation: 0,
backgroundColor: Colors.white,
currentIndex: controller.pageViewController.page?.round() ?? 0,
onTap: (id) {
if (id == 0) {
Modular.to.navigate('/createaccount/pageStep1');
} else if (id == 1) {
Modular.to.navigate('/createaccount/pageStep2');
} else if (id == 2) {
Modular.to.navigate('/createaccount/pageStep3');
} else if (id == 3) {
Modular.to.navigate('/createaccount/pageStep4');
}
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Page1',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Page2',
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Page3',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Page4',
)
]
/*ElevatedButton(
onPressed: () => Modular.to.navigate("/login"),
child: Text("Voltar"))*/
);
},
));
}
Here is the output, I hope you can design the rest:
Widget
import 'package:flutter/material.dart';
class CreateAccountPage extends StatefulWidget {
CreateAccountPage({Key? key}) : super(key: key);
#override
_CreateAccountPageState createState() => _CreateAccountPageState();
}
class _CreateAccountPageState extends State<CreateAccountPage> {
PageController controller = PageController(initialPage: 0);
int currentPage = 0;
final pages = List.generate(
4,
(index) => Container(
alignment: Alignment.center,
color: index.isEven ? Colors.cyanAccent : Colors.yellowAccent,
child: Text(
"${index + 1}",
style: TextStyle(fontSize: 44),
),
),
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: controller,
children: [...pages],
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
),
bottomNavigationBar: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
setState(() {
controller.previousPage(
duration: Duration(milliseconds: 400),
curve: Curves.easeInOut);
});
},
icon: Icon(Icons.arrow_left),
),
Text(
"${currentPage + 1}/${pages.length}",
),
IconButton(
onPressed: () {
controller.nextPage(
duration: Duration(milliseconds: 400),
curve: Curves.easeInOut);
},
icon: Icon(Icons.arrow_right),
)
],
),
));
}
}
I think what you are looking for is an onboarding screen. I suggest you take a look at this library here which is created especially for onboarding named introduction_screen. you can customize the bottons and texts as shown in the examples. read documentation for more information.

Getting Error while Home widget (MyHomepage) loading

I am getting The following error while Run my app default page (Homepage) .
════════ Exception caught by widgets library ═══════════
The following ArgumentError was thrown building MyHomePage(dirty, dependencies: [MediaQuery, _EffectiveTickerMode], state: _MyHomePageState#7da5f(ticker inactive)):
Invalid argument(s)
**The Tracker showing the following reasons:**
The relevant error-causing widget was:
MyHomePage file:///F:/Orangebd/app/GoogleDriveClone-Flutter/lib/Screen/Home.dart:37:15
When the exception was thrown, this was the stack:
#0 _StringBase.+ (dart:core-patch/string_patch.dart:272:57)
#1 _MyHomePageState.build (package:googledriveclone_flutter/Screen/Home.dart:133:45)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4716:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4599:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4772:11)
...
══════════════════════════════════════════
During that error, the screen appears something like that
Here is my Home page code
import 'package:fab_circular_menu/fab_circular_menu.dart';
//import 'package:file_picker/file_picker.dart';
import 'package:floating_action_bubble/floating_action_bubble.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:googledriveclone_flutter/Screen/Files.dart';
import 'package:googledriveclone_flutter/Screen/HomeScreen.dart';
import 'package:googledriveclone_flutter/Screen/LoginPage.dart';
import 'package:googledriveclone_flutter/Screen/Profile.dart';
import 'package:googledriveclone_flutter/Widget/constants.dart';
import 'package:prompt_dialog/prompt_dialog.dart';
import 'package:sk_alert_dialog/sk_alert_dialog.dart';
import 'package:storage_capacity/storage_capacity.dart';
import 'IssudFile.dart';
void main() {
runApp(HomePage());
}
class HomePage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
try {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Digilocker',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Digilocker'),
);
}
catch(e){
print('Loading expception of page'+e.toString());
}
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
Widget _widgetBody = HomeScreen();
int _currrentIndex = 0;
Animation<double> _animation;
AnimationController _animationController;
TextEditingController _foldername = TextEditingController();
String _fileName;
var scaffoldKey = GlobalKey<ScaffoldState>();
bool isFolder;
double _diskSpace = 0;
var _freespace ;
var _freespacemb;
var _occupiedSpace ;
var _totalSpace;
#override
void initState() {
// TODO: implement initState
// _controller.addListener(() => _extension = _controller.text);
_getStorgeInfo();
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
);
final curvedAnimation = CurvedAnimation(curve: Curves.easeInOut, parent: _animationController);
_animation = Tween<double>(begin: 0, end: 1).animate(curvedAnimation);
// initDiskSpace();
super.initState();
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
void _onItemTapped(int index) async{
setState(() {
if(index == 0){
_currrentIndex = index;
_widgetBody = HomeScreen();
}
else if(index == 1){
_currrentIndex = index;
_widgetBody = MyIssuedDocScreen();
}
else if(index == 2){
_currrentIndex = index;
_widgetBody = Center(child: Text('Shared documents'),);
}
else if(index == 3){
_currrentIndex = index;
_widgetBody = MyDriveScreen();
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
endDrawerEnableOpenDragGesture: false, // This way it will not open
// endDrawer: Drawer(),
drawer: new Drawer(
elevation: 10,
child: new ListView(
padding: EdgeInsets.all(0),
children: <Widget>[
DrawerHeader(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/digi_locker.png', width: MediaQuery.of(context).size.width*0.30,),
SizedBox(height: 10,),
Text('Available space: '+_freespace+'\t (MB)'),
]
),
decoration: BoxDecoration(
color: kPrimaryLightColor,
),
),
ListTile(
leading: Icon(Icons.person),
title: Text('My profile'),
onTap: () {
// Get.back();
Get.to(profilePage());
},
),
Divider(),
ListTile(
leading: Icon(Icons.create_new_folder),
title: Text('Create folder'),
onTap: () {
// Get.back();
_showMyDialog();
},
),
ListTile(
leading: Icon(Icons.cloud_upload_rounded),
title: Text('File upload'),
onTap: () {
// Get.back();
},
),
ListTile(
leading: Icon(Icons.six_ft_apart_outlined),
title: Text('Issued documents'),
onTap: () {
// Get.back();
},
),
Divider(),
ListTile(
leading: Icon(Icons.translate_rounded),
title: Text('Change lagnuage'),
onTap: () {
// Get.back();
//Get.offAll(LoginPage());
//Do some stuff here
//Closing programmatically - very less practical use
scaffoldKey.currentState.openEndDrawer();
},
),
ListTile(
leading: Icon(Icons.logout),
title: Text('Logout'),
onTap: () {
// Get.back();
Get.offAll(LoginPage());
//Do some stuff here
//Closing programmatically - very less practical use
scaffoldKey.currentState.openEndDrawer();
},
)
],
),
),
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
brightness: Theme.of(context).brightness,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children:
[
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(35)),
color: Colors.grey.shade50,
),
child: TextFormField(
decoration: InputDecoration(
hintText: "Search in locker",
border: InputBorder.none,
icon: Container(
margin: EdgeInsets.only(left: 10),
child: Icon(Icons.search, color: kPrimaryColor,)
),
),
),
),
),
]
),
iconTheme: IconThemeData(color: kPrimaryColor),
actions: <Widget>[
IconButton(
onPressed: (){
print("Sync started");
showSnackMessage(context,"Sync Started please wait...", scaffoldKey,'');
},
icon: Icon(
Icons.sync,
color:kPrimaryColor,
),
),
IconButton(
icon: Container(
height: 50,
width: 50,
margin: EdgeInsets.all(5),
child: CircleAvatar(
radius: 14.0,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 14.0,
backgroundColor: Colors.grey[200],
backgroundImage: NetworkImage("https://qph.fs.quoracdn.net/main-qimg-11ef692748351829b4629683eff21100.webp"),
),
),
),
onPressed: () {
// do something
},
)
],
),
body: SafeArea(
child: Container(
padding: EdgeInsets.all(15.0),
child: _widgetBody
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
//Init Floating Action Bubble
floatingActionButton: FloatingActionBubble(
// Menu items
items: <Bubble>[
// Floating action menu item
Bubble(
title:"Upload",
iconColor :kPrimaryColor,
bubbleColor : Colors.white.withOpacity(0.9),
titleStyle:TextStyle(fontSize: 16 , color: kPrimaryColor),
icon:Icons.cloud_upload,
onPress: () {
// OpenFilePicker();
_animationController.reverse();
_openFileType(context);
},
),
// Floating action menu item
Bubble(
title:"Folder",
icon:Icons.create_new_folder,
iconColor :kPrimaryColor,
bubbleColor : Colors.white.withOpacity(0.9),
titleStyle:TextStyle(fontSize: 16 , color: kPrimaryColor),
onPress: () {
_animationController.reverse();
print('creating folder');
_showMyDialog();
},
),
//Floating action menu item
],
// animation controller
animation: _animation,
// On pressed change animation state
onPress: _animationController.isCompleted
? _animationController.reverse
: _animationController.forward,
// Floating Action button Icon color
iconColor: kPrimaryColor,
// Flaoting Action button Icon
icon: AnimatedIcons.menu_close,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currrentIndex,
type: BottomNavigationBarType.fixed,
showSelectedLabels: true,
showUnselectedLabels: true,
selectedItemColor: kPrimaryColor,
onTap: _onItemTapped,
items: [
BottomNavigationBarItem(
icon: _currrentIndex==0?Icon(Icons.home,size: 25,):Icon(Icons.home_outlined,size: 25),
title: Text("Home")
),
BottomNavigationBarItem(
icon: _currrentIndex==1?Icon(Icons.file_download_done,size: 25,):Icon(Icons.file_download_done_outlined,size: 25),
title: Text("Issued")
),
BottomNavigationBarItem(
icon: _currrentIndex==2?Icon(Icons.supervised_user_circle,size: 25,):Icon(Icons.supervised_user_circle,size: 25),
title: Text("Shared")
),
BottomNavigationBarItem(
icon: _currrentIndex==3?Icon(Icons.folder,size: 25,):Icon(Icons.folder_open,size: 25),
title: Text("My locker")
),
],
), );
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colors.white,
elevation: 13,
title: Text('Create folder'),
content: TextField(
onChanged: (value) { },
controller: _foldername,
decoration: InputDecoration(hintText: "your folder/directory name",
suffixIcon: IconButton(
onPressed: () => _foldername.clear(),
icon: Icon(Icons.clear),
),
),
),
actions: <Widget>[
TextButton(
child: Text('Cancel', style: TextStyle(color: Colors.red),),
onPressed: () {
//Navigator.pop(_);
Navigator.of(context).pop();
// _animationController.reverse();
},
),
TextButton(
child: Text('Create', style: TextStyle(color: kPrimaryColor),),
onPressed: () {
createFolder(context, scaffoldKey, _foldername.text.toString()) ;
Get.back();
//Navigator.of(context).pop();
// _animationController.reverse();
},
),
],
);
},
);
}
void _openFileType(BuildContext context) {
SKAlertDialog.show(
context: context,
type: SKAlertType.radiobutton,
radioButtonAry: {'Certificate': 1, 'Signature': 2, 'NID': 3, 'Passport': 4, 'Driving licence': 5},
title: 'Choose File category',
onCancelBtnTap: (value) {
print('Cancel Button Tapped');
Navigator.of(context).pop(false);
},
onRadioButtonSelection: (value) {
print('onRadioButtonSelection $value');
},
);
}
/* Future<void> initDiskSpace() async {
double diskSpace = 0;
diskSpace = await DiskSpace.getFreeDiskSpace;
if (!mounted) return;
setState(() {
_diskSpace = diskSpace;
});
}
*/
Future<void> _getStorgeInfo() async{
_freespace = await StorageCapacity.getFreeSpace;
//_freespacemb = await StorageCapacity.toMegaBytes(double.parse(_freespace.toString()));
_occupiedSpace = await StorageCapacity.getOccupiedSpace;
_totalSpace = await StorageCapacity.getTotalSpace;
}
}
NOTE: if I Hot Reload this page, it's working okay again
Please help.
the problem is, you are getting your data in the initState method, but your widget's build is being completed before initializing the data to _freespace, and that's why the error is appearing.
as a solution, I suggest removing _getStorgeInfo() call from initState, and implementing the following structure:
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
endDrawerEnableOpenDragGesture: false, // This way it will not open
// endDrawer: Drawer(),
drawer: new Drawer(
...
),
appBar: AppBar(
...
),
body: SafeArea(
child: Container(
padding: EdgeInsets.all(15.0),
child: FutureBuilder(
future: _getStorgeInfo(),
builder: (context, snapshot) {
if(snapshot.connectionState!=ConnectionState.Done) return CircularProgressIndicator();
return _widgetBody;
},
),
),
));
}