LateInitializationError: Field '_noteData#861302000' has not been initialized - flutter

I am trying to create notebook with sqlite database in flutter 3.1.0 .
I have problem with initialing my NoteEntityData with late and initState().
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:samsung_note/Database/database.dart';
import 'package:samsung_note/Screens/edit_screen.dart';
import 'package:samsung_note/app_style.dart';
class DetailsScreen extends StatefulWidget {
final int id;
const DetailsScreen({Key? key, required this.id}) : super(key: key);
#override
State<DetailsScreen> createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State<DetailsScreen> {
late Database _database;
late NoteEntityData _noteData;
#override
void initState() {
super.initState();
_database = Database();
getSingleNote();
}
#override
void dispose() {
_database.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
final time = DateFormat.Hm().format(_noteData.createdTime);
final dateTime = DateFormat.yMMMd().format(_noteData.createdTime);
return Scaffold(
appBar: AppBar(
elevation: 1,
leading: IconButton(
onPressed: () => Get.back(),
icon: const Icon(Icons.arrow_back_ios)),
actions: [
IconButton(
onPressed: () => Get.to(() => const EditScreen()),
icon: const Icon(Icons.edit)),
const SizedBox(width: 10),
_noteData.isImportant
? const Icon(Icons.star, color: Colors.orange)
: const Icon(Icons.star_border),
const SizedBox(width: 10),
IconButton(onPressed: () {}, icon: const Icon(Icons.delete)),
]),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
_noteData.title,
style: AppStyle.titleTextStyle,
),
const SizedBox(height: 25),
Text(_noteData.description, style: AppStyle.descriptionTextStyle),
const SizedBox(height: 50),
Text(
"Created time: $time",
style: AppStyle.smallTextStyle
.copyWith(fontSize: 16, color: Colors.grey.shade500),
textAlign: TextAlign.end,
),
const SizedBox(height: 10),
Text(
"Created Datetime: $dateTime",
style: AppStyle.smallTextStyle
.copyWith(fontSize: 16, color: Colors.grey.shade500),
textAlign: TextAlign.end,
),
],
),
),
);
}
getSingleNote() async {
_noteData = await _database.getSingleNote(widget.id);
}
}
I know that we can't use async in initState() , so I create a Future method to initial my noteData . but when I run my code , compiler can't understand initialing noteData and I got this error :
======== Exception caught by widgets library =======================================================
The following LateError was thrown building DetailsScreen(dirty, state: _DetailsScreenState#e1c83):
LateInitializationError: Field '_noteData#861302000' has not been initialized.
The relevant error-causing widget was:
DetailsScreen DetailsScreen:file:///C:/Users/Hp/AndroidStudioProjects/samsung_note/lib/Screens/home_screen.dart:72:51
When the exception was thrown, this was the stack:
#0 _DetailsScreenState._noteData (package:samsung_note/Screens/details_screen.dart)
#1 _DetailsScreenState.build (package:samsung_note/Screens/details_screen.dart:36:41)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4919:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4806:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4977:11)
#5 Element.rebuild (package:flutter/src/widgets/framework.dart:4529:5)
#6 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4787:5)
#7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4968:11)
#8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
... Normal element mounting (275 frames)
===================================================================================================
here is where I got one note id in HomeScreen :
Scaffold(
backgroundColor: Colors.grey.shade200,
drawer: const Drawer(),
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.grey.shade200,
title: Text(
"All notes",
style: AppStyle.normalTextStyle.copyWith(fontWeight: FontWeight.w600),
),
actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.search)),
IconButton(
onPressed: () {}, icon: const Icon(Icons.more_vert_outlined))
],
),
body: FutureBuilder<List<NoteEntityData>>(
future: _database.getAllNotes(),
builder: (context, snapshot) {
final List<NoteEntityData>? notes = snapshot.data;
if (snapshot.connectionState != ConnectionState.done) {
return Center(
child: LoadingAnimationWidget.inkDrop(
color: Colors.deepOrange, size: 200),
);
} else if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
} else if (notes!.isNotEmpty) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: notes.length,
itemBuilder: (context, index) {
final note = notes[index];
return GestureDetector(
onTap: () => Get.to(() => DetailsScreen(id: note.id)),
child: BaseContainer(note: note));
},
));
}
and I have to mention ALL THIS CODE is for some course and it's Same as teacher Code.. That code it's work just fine but mine has this ERROR .

Try to add setState((){}) to your getSingleNote method
like this :
getSingleNote() async {
_noteData = await _database.getSingleNote(widget.id);
setState((){});
}

that because getSingleNote is an async function and when Flutter framwork call build function of your class _noteData is not initialized.
I think you can use a FutureBuilder in build function for initialize _noteData before use it

Related

After Scanning Barcode , how to pass scanned data to a new page?

the thing I will like to ask about is that I want to pass the data in the barcode to a new page after scanning. Is there anyway can I do it?
Hope anyone can solve my problem <3
Had been doing this for my intern for 4 days and I have no clue at all. Hope can solve it as fast as possible
Below is my code:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:meditation_app/widgets/category_card.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key key}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String _scanBarcode = 'Unknown';
#override
void initState() {
super.initState();
}
Future<void> scanBarcodeNormal() async {
String barcodeScanRes ;
try {
barcodeScanRes = await FlutterBarcodeScanner.scanBarcode(
'#ff6666', 'Cancel', true, ScanMode.BARCODE);
print(barcodeScanRes);
} on PlatformException {
barcodeScanRes = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_scanBarcode = barcodeScanRes; //Here is the thing I will like to pass to another page
});
}
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('EzyMerchant'),
actions: <Widget>[
IconButton(
icon: SvgPicture.asset("assets/icons/setting.svg",color: Colors.white,),
onPressed: () {
Navigator.pushNamed(context, '/setting');
},
),
],
),
body: Stack(
children: <Widget>[
SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical:20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Good Morning \nAdmin",
style: Theme.of(context)
.textTheme
.headline4
.copyWith(fontWeight: FontWeight.w900),
),
SizedBox(height: 50),
Expanded(
child: Container(
child: GridView.count(
crossAxisCount: 2,
childAspectRatio: .85,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
children: <Widget>[
Container(
child: CategoryCard(
title: "Add",
svgSrc: ("assets/icons/Hamburger.svg"),
press: () => scanBarcodeNormal(), //Here is the scan function
),
),
CategoryCard(
title: "Redeem",
svgSrc: "assets/icons/Excrecises.svg",
press: () {},
),
CategoryCard(
title: "Wallet",
svgSrc: "assets/icons/Meditation.svg",
press: () {},
),
CategoryCard(
title: "Voucher",
svgSrc: "assets/icons/yoga.svg",
press: () {},
),
],
),
),
),
],
),
),
)
],
),
);
}
}
You can use arguments property in Navigator.pushNamed like
Navigator.pushNamed(context, '/setting',arguments: _scanBarcode);

I am trying to retrieve data from my Firebase realtime database but it is getting me null?

This is my code for the main screen at which i want to retrieve the image name and the Login and signup words other than writing them with hard code from my realtime database. However here i always get the answer as null and the picture doesn't load. So what can i change in my code to get the values from my database without getting null. Moreover, my database is us central and i tried to put the url other than the instance and didn’t do any change.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
runApp(NGU_APP());
}
// ignore: camel_case_types
class NGU_APP extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomepage(),
routes: {
"login": (_) => LoginScreen(),
"signup": (_) => RegistrationScreen(),
},
);
}
}
class MyHomepage extends StatefulWidget {
const MyHomepage({key}) : super(key: key);
#override
_MyHomepageState createState() => _MyHomepageState();
}
class _MyHomepageState extends State<MyHomepage> {
DatabaseReference dbref;
String Images = "images/logo.png";
String Login = "Log In";
#override
void initState() {
super.initState();
dbref = FirebaseDatabase
.instance
.reference()
.child('ngu-su-default-rtdb');
dbref.child("Login").onValue.listen((event) {
print(event.snapshot.value.toString());
setState(() {
Login = event.snapshot.value.toString();
print(Login);
});
});
dbref.child("Imagees").onValue.listen((event) {
print(event.snapshot.value.toString());
setState(() {
Images = event.snapshot.value.toString();
print(Images);
});
});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color(0xFF6D0131),
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Hero(
tag: 'logo',
child: CircleAvatar(
radius: (100),
child: ClipRRect(
borderRadius: BorderRadius.circular(110),
child: Image.asset("$Images"),
)),
),
),
],
),
SizedBox(
height: 48.0,
),
Buttons(
colour: Colors.white,
text: Login.toString(),
page: LoginScreen()),
SizedBox(
height: 5.0,
),
Buttons(
colour: Colors.white,
text: 'Sign Up',
page: RegistrationScreen())
],
),
),
),
),
),
);
}
}
class RoundedButton extends StatelessWidget {
RoundedButton({this.title, this.colour, #required this.onPressed});
final Color colour;
final String title;
final Function onPressed;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
elevation: 5.0,
color: colour,
borderRadius: BorderRadius.circular(30.0),
child: MaterialButton(
onPressed: onPressed,
minWidth: 200.0,
height: 42.0,
child: Text(
title,
style: TextStyle(
fontSize: 20.0,
color: Color(0xFF6D0131),
),
),
),
),
);
}
}
class Buttons extends StatelessWidget {
Buttons({
#required this.colour,
#required this.text,
#required this.page,
});
final String text;
final Color colour;
final Widget page;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return page;
},
),
);
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(20.0),
),
margin: EdgeInsets.only(bottom: 10.0),
padding: EdgeInsets.only(left: 18.0),
child: Center(
child: Text(
text,
style: TextStyle(
color: Color(0xFF6D0131),
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
This is the error i get:
I/flutter ( 5514): null
======== Exception caught by image resource service ================================================
The following assertion was thrown resolving an image codec:
Unable to load asset: null
When the exception was thrown, this was the stack:
#0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:224:7)
<asynchronous suspension>
#1 AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:675:14)
<asynchronous suspension>
Image provider: AssetImage(bundle: null, name: "null")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#6f075(), name: "null", scale: 1.0)
====================================================================================================
I/chatty ( 5514): uid=10124(com.newgizauniversity.ngusu) 1.ui identical 2 lines
I/flutter ( 5514): null

flutter Problem: How to update number of items count in cart?

I implement to add to cart functionality items added into cart successfully but the number of count in the cart badge is not updated when I reload dart page than the number of count updates.can anyone help me?
I implement to add to cart functionality items added into cart successfully but the number of count in the cart badge is not updated when I reload dart page than the number of count updates.can anyone help me?
This is my Homepage.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:badges/badges.dart';
import 'package:hospital/BestDeatProducts/best_deal_product_page.dart';
import 'package:hospital/CartPage/pages/cartPage.dart';
import 'package:hospital/Drawer/dropdown_menu.dart';
import 'package:hospital/FirstSection/carousel.dart';
import 'package:hospital/Drawer/drawercontent.dart';
import 'package:hospital/FloatingActionButton/ConsultWithDoctor/consult_with_doctor.dart';
import 'package:hospital/MedicineCateory/medicine_category_page.dart';
import 'package:hospital/SecondSection/second_page.dart';
import 'package:hospital/ThirdSection/third_page.dart';
import 'package:hospital/TrendingProducts/trending_product_page.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'No Internet/connectivity_provider.dart';
import 'No Internet/no_internet.dart';
import 'package:http/http.dart' as http;
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
SharedPreferences loginData;
// late String username;
Future getUsername() async {
loginData = await SharedPreferences.getInstance();
setState(() {
// print("uname" + uname.toString());
print("dddpppuu1 : responceData_un" +
loginData.getString('responceData_un').toString());
print("dddpppuu2 : responceData_ue" +
loginData.getString('responceData_ue').toString());
print("dddpppuu3 : responceData_status" +
loginData.getString('responceData_status').toString());
String responceData_uid =
loginData.getString('responceData_uid').toString();
fetchData(responceData_uid);
});
}
var response;
var addToCartApi;
#override
void initState() {
// TODO: implement initState
//
super.initState();
Provider.of<ConnectivityProvider>(context, listen: false).startMonitering();
// for loading
getUsername();
}
fetchData(String argResponceData_uid) async {
var api = Uri.parse(
'$ecommerceBaseUrl/addToCartApi.php?a2rTokenKey=$a2rTokenKey&action=addToCartList&uid=${argResponceData_uid}');
print('cartpage' + api.toString());
response = await http.get(api);
print("Carousel" + response.body);
addToCartApi = jsonDecode(response.body);
print('addToCartApi' + addToCartApi['total'].toString());
print('totalPriceAfterOffer' + totalPriceAfterOffer.toString());
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kGreen,
title: Text(
"BK Arogyam",
style: TextStyle(fontStyle: FontStyle.italic),
),
actions: [
response != null
? Badge(
position: BadgePosition.topEnd(top: 3, end: 18),
animationDuration: Duration(milliseconds: 300),
animationType: BadgeAnimationType.slide,
badgeContent: Text(
addToCartApi['total']['num'].toString(),
style: TextStyle(color: Colors.white),
),
child: IconButton(
icon: Icon(Icons.shopping_cart),
padding: EdgeInsets.only(right: 30.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cartpage()),
);
}),
)
: IconButton(
icon: Icon(Icons.shopping_cart),
// onPressed: () => print("open cart"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cartpage()),
);
},
),
DropDownMenu(),
],
),
floatingActionButton: FloatingActionButton(
backgroundColor: kGreen,
onPressed: () => Navigator.push(context,
MaterialPageRoute(builder: (context) => ConsultWithDoctor())),
tooltip: 'Consult With Doctor',
child: Container(
child: Image(
image: AssetImage(
"assets/icons/cwd.png",
),
color: Colors.white,
width: 40,
height: 40,
),
),
),
drawer: Drawer(
child: DrawerContent(),
),
body: pageUI());
}
Widget pageUI() {
return Consumer<ConnectivityProvider>(
builder: (consumerContext, model, child) {
if (model.isOnline != null) {
return model.isOnline
? ListView(
children: [
Carousel(),
SizedBox(
height: 10.0,
),
MedicineCategoryPage(),
SizedBox(
height: 10.0,
),
SecondPage(),
SizedBox(
height: 10.0,
),
ThirdPage(),
SizedBox(
height: 10.0,
),
TrendingProductPage(),
SizedBox(
height: 16.0,
),
BestDealProductPage(),
SizedBox(
height: 10.0,
),
],
)
: NoInternet();
}
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
},
);
}
}
You can use the change notifier provide by provider package.
And watch the video on how to use, exactly for ur use case search YouTube change notifier provider by the growing developer
Hope it helps 🙂
You can use provider(provider: ^5.0.0) or Getx(get: ^4.1.4) to handle this kind of case.
There are lots of examples are available for GetX and Provider.
If you don't want to use any of them, Then store your cart/badge count to tempCartCount variable(Example: int cartCount = 0) and set it to the badge count instead of "addToCartApi['total']['num'].toString()" , Make sure to setState on update/addCart Item.
Here I provide a simple example of how to update count on appBar.
if you want to change from any other screen make cartCount to global otherwise you can set it local/private.
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
class UpdateCountExample extends StatefulWidget {
#override
_UpdateCountExampleState createState() => _UpdateCountExampleState();
}
int cartCount = 0;
class _UpdateCountExampleState extends State<UpdateCountExample> {
List<String> cartArray = [];
#override
void initState() {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
setState(() {
cartCount = 0;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
actions: [
Padding(
padding: const EdgeInsets.only(right: 18.0, top: 5.0),
child: Badge(
badgeContent: Text(cartCount.toString()),
child: Icon(Icons.add_shopping_cart),
),
)
],
),
body: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Add item in cart",
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, decoration: TextDecoration.none, color: Colors.black),
),
SizedBox(
height: 20,
),
InkWell(
onTap: () {
setState(() {
cartArray.add("value ${cartArray.length}");
cartCount = cartArray.length;
});
},
child: Container(
padding: const EdgeInsets.all(10.0),
color: Colors.amber,
child: Text(
"Add Item",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15, decoration: TextDecoration.none, color: Colors.black),
),
),
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: cartArray.length,
itemBuilder: (context, index) {
return Text(
cartArray[index],
style: TextStyle(fontSize: 20, color: Colors.black),
);
}),
)
],
),
),
);
}
}
I have used StreamBuilder to update cart items instantly.
You can use the code from this post
How to use Streambuilder in flutter

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;
},
),
),
));
}

Why isn't Navigator.pop() refreshing data?

Hi guys I'm trying to build an app with flutter, so I have two screens HomeScreen() and RoutineScreen(). The first one is a Scaffold and in the body has a child Widget (a ListView called RoutinesWidget()) with all the routines. And the second one is to create a routine. The thing is, that when I create the routine, I use a button to pop to the HomeScreen() but it doesn't refresh the ListView (I'm guessing that it's because when I use Navigator.pop() it refreshes the Scaffold but not the child Widget maybe?)
HomeScreen() code here:
import 'package:flutter/material.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Widgets/routines_widget.dart';
import 'package:workout_time/Widgets/statistics_widget.dart';
import 'package:workout_time/Screens/settings_screen.dart';
import 'package:workout_time/Screens/routine_screen.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
List<Widget> _views = [
RoutinesWidget(),
StatisticsWidget(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kThirdColor,
appBar: AppBar(
leading: Icon(Icons.adb),
title: Text("Workout Time"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () => Navigator.push(context,
MaterialPageRoute(builder: (context) => SettingsScreen()))),
],
),
body: _views[_selectedIndex],
floatingActionButton: (_selectedIndex == 1)
? null
: FloatingActionButton(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RoutineScreen(null)));
setState(() {});
},
child: Icon(
Icons.add,
color: kSecondColor,
size: 30.0,
),
elevation: 15.0,
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
bottomItems(Icon(Icons.fitness_center_rounded), "Routines"),
bottomItems(Icon(Icons.leaderboard_rounded), "Statistics"),
],
currentIndex: _selectedIndex,
onTap: (int index) => setState(() => _selectedIndex = index),
),
);
}
}
BottomNavigationBarItem bottomItems(Icon icon, String label) {
return BottomNavigationBarItem(
icon: icon,
label: label,
);
}
RoutinesWidget() code here:
import 'package:flutter/material.dart';
import 'package:workout_time/Services/db_crud_service.dart';
import 'package:workout_time/Screens/routine_screen.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Models/routine_model.dart';
class RoutinesWidget extends StatefulWidget {
#override
_RoutinesWidgetState createState() => _RoutinesWidgetState();
}
class _RoutinesWidgetState extends State<RoutinesWidget> {
DBCRUDService helper;
#override
void initState() {
super.initState();
helper = DBCRUDService();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: helper.getRoutines(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Routine routine = Routine.fromMap(snapshot.data[index]);
return Card(
margin: EdgeInsets.all(1.0),
child: ListTile(
leading: CircleAvatar(
child: Text(
routine.name[0],
style: TextStyle(
color: kThirdOppositeColor,
fontWeight: FontWeight.bold),
),
backgroundColor: kAccentColor,
),
title: Text(routine.name),
subtitle: Text(routine.exercises.join(",")),
trailing: IconButton(
icon: Icon(Icons.delete_rounded),
color: Colors.redAccent,
onPressed: () {
setState(() {
helper.deleteRoutine(routine.id);
});
},
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RoutineScreen(routine))),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
color: kSecondColor,
);
},
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}
RoutineScreen() code here:
import 'package:flutter/material.dart';
import 'package:workout_time/Models/routine_model.dart';
import 'package:workout_time/Widgets/type_card_widget.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Services/db_crud_service.dart';
class RoutineScreen extends StatefulWidget {
final Routine _routine;
RoutineScreen(this._routine);
#override
_RoutineScreenState createState() => _RoutineScreenState();
}
class _RoutineScreenState extends State<RoutineScreen> {
DBCRUDService helper;
final _nameController = TextEditingController();
final _descriptionController = TextEditingController();
bool _type = true;
int _cycles = 1;
int _restBetweenExercises = 15;
int _restBetweenCycles = 60;
#override
void initState() {
super.initState();
helper = DBCRUDService();
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context),
),
title: widget._routine != null
? Text(widget._routine.name)
: Text("Create your routine"),
actions: [
IconButton(
icon: Icon(Icons.done_rounded),
onPressed: createRoutine,
)
],
bottom: TabBar(
tabs: [
Tab(
text: "Configuration",
),
Tab(
text: "Exercises",
),
],
),
),
body: TabBarView(children: [
//_routine == null ? ConfigurationNewRoutine() : Text("WIDGET N° 1"),
ListView(
children: [
Container(
padding: EdgeInsets.all(15.0),
child: Row(
children: [
Text(
"Name:",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 40.0,
),
Expanded(
child: TextField(
textAlign: TextAlign.center,
controller: _nameController,
),
),
],
),
),
SizedBox(
height: 20.0,
),
Card(
margin: EdgeInsets.all(15.0),
color: kSecondColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Container(
padding: EdgeInsets.all(15.0),
child: Column(
children: [
Text(
"Type",
style: TextStyle(fontSize: 25.0),
),
Row(
children: [
Expanded(
child: TypeCard(
Icons.double_arrow_rounded,
_type == true ? kFirstColor : kThirdColor,
() => setState(() => _type = true),
"Straight set",
),
),
Expanded(
child: TypeCard(
Icons.replay_rounded,
_type == false ? kFirstColor : kThirdColor,
() => setState(() => _type = false),
"Cycle",
),
),
],
),
],
),
),
),
SizedBox(
height: 20.0,
),
Container(
padding: EdgeInsets.all(15.0),
child: Row(
children: [
Text(
"N° cycles:",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 40.0,
),
Expanded(
child: Text("Hello"),
),
],
),
),
SizedBox(
height: 20.0,
),
],
),
Text("WIDGET N° 2"),
]),
),
);
}
void createRoutine() {
List<String> _exercises = ["1", "2"];
List<String> _types = ["t", "r"];
List<String> _quantities = ["30", "20"];
Routine routine = Routine({
'name': _nameController.text,
'description': "_description",
'type': _type.toString(),
'cycles': 1,
'numberExercises': 2,
'restBetweenExercises': 15,
'restBetweenCycles': 60,
'exercises': _exercises,
'types': _types,
'quantities': _quantities,
});
setState(() {
helper.createRoutine(routine);
Navigator.pop(context);
});
}
}
Any idea what can I do to make it work? Thank you
Make it simple
use Navigator.pop() twice
so that the current class and old class in also removed
from the stack
and then use Navigator.push()
When you push a new Route, the old one still stays in the stack. The new route just overlaps the old one and forms like a layer above the old one. Then when you pop the new route, it will just remove the layer(new route) and the old route will be displayed as it was before.
Now you must be aware the Navigator.push() is an asynchronous method and returns a Future. How it works is basically when you perform a Navigator.push(), it will push the new route and will wait for it to be popped out. Then when the new route is popped, it returns a value to the old one and that when the future callback will be executed.
Hence the solution you are looking for is add a future callback like this after your Navigator.push() :
Navigator.push(context,
MaterialPageRoute(builder: (context) => SettingsScreen())
).then((value){setState(() {});}); /// A callback which is executed after the new route will be popped. In that callback, you simply call a setState and refresh the page.