I am trying to user Streambuilder to display gridview, but it return this error, I am calling the method classList() to container in scaffold body
database = FirebaseDatabase.instance
I want to show classData, show 0,1,2..etc I want to show ('className','classSection' in one button per child) in gridview as RaisedButtons
I get this error when the code below is executed
I/flutter ( 5433): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5433): The following NoSuchMethodError was thrown building HomePage(dirty, state: _HomePage#055be):
I/flutter ( 5433): The method 'split' was called on null.
I/flutter ( 5433): Receiver: null
I/flutter ( 5433): Tried calling: split("/")
I/flutter ( 5433):
I/flutter ( 5433): When the exception was thrown, this was the stack:
I/flutter ( 5433): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
I/flutter ( 5433): #1 DatabaseReference.child (file:///G:/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_database-2.0.3/lib/src/database_reference.dart:24:58)
I/flutter ( 5433): #2 _HomePage.classList (package:barcode_scan_example/home_page.dart:169:44)
I/flutter ( 5433): #3 _HomePage.build (package:barcode_scan_example/home_page.dart:265:30)
I/flutter ( 5433): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
I/flutter ( 5433): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3736:15)
I/flutter ( 5433): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3716:5)
I/flutter ( 5433): #8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3864:11)
I/flutter ( 5433): #9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
I/flutter ( 5433): #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
I/flutter ( 5433): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
I/flutter ( 5433): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
I/flutter ( 5433): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #14 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2273:33)
I/flutter ( 5433): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:700:20)
I/flutter ( 5433): #16 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:268:5)
I/flutter ( 5433): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:988:15)
I/flutter ( 5433): #18 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:928:9)
I/flutter ( 5433): #19 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:840:5)
I/flutter ( 5433): #23 _invoke (dart:ui/hooks.dart:209:10)
I/flutter ( 5433): #24 _drawFrame (dart:ui/hooks.dart:168:3)
I/flutter ( 5433): (elided 3 frames from package dart:async)
classList() {
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: null,
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
the entire dart file
import 'package:flutter/material.dart';
import 'auth.dart';
import 'auth_provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'make_class.dart';
import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:firebase_database/firebase_database.dart';
import 'qr_screen.dart';
class HomePage extends StatefulWidget {
#override
_HomePage createState() => _HomePage();
}
enum ScaffoldType { student, lecturer }
ScaffoldType _scaffoldType = ScaffoldType.lecturer;
class _HomePage extends State<HomePage> {
final FirebaseDatabase database = FirebaseDatabase.instance;
String barcode = "";
String userUid;
var userClass;
Future<void> _signOut(BuildContext context) async {
try {
final BaseAuth auth = AuthProvider.of(context).auth;
await auth.signOut();
} catch (e) {
print(e);
}
}
#override
void initState() {
super.initState();
userUi();
setState(() async* {
FirebaseDatabase database;
database = FirebaseDatabase.instance;
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
});
}
Future reUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
var userUid = user.uid;
var userWho = await database
.reference()
.child('user')
.child(userUid)
.once()
.then((DataSnapshot snapshot) {
Map<dynamic, dynamic> data = snapshot.value;
var isL = data.values.toList();
print(isL[1]);
print(data.values);
if (isL[1].toString().toLowerCase() == "true") {
_scaffoldType = ScaffoldType.lecturer;
print('lecturer');
} else if (isL[1].toString().toLowerCase() == "false") {
_scaffoldType = ScaffoldType.student;
print("student");
}
});
// print(userWho);
}
userUi() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
return user.uid;
}
classList(userUid) {
print(userUid);
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: (){},
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
#override
Widget build(BuildContext context) {
// var userUid = userUi();
reUser();
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: Container(child: classList(userUi()),),
);
}
List<Widget> buttonBelow() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MakeClass()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("Add Class")
];
} else {
return <Widget>[
Opacity(
opacity: 0,
child: FlatButton(
onPressed: () {},
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(180)),
),
),
Opacity(opacity: 0, child: Text("Add Class"))
];
}
}
List<Widget> buttonBelow2() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.blur_on,
semanticLabel: "QRCode",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => QrScreen()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("QRCode")
];
}
}
Future scan() async {
try {
String barcode = await BarcodeScanner.scan();
setState(() => this.barcode = barcode);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this.barcode = 'The user did not grant the camera permission!';
});
} else {
setState(() => this.barcode = 'Unknown error: $e');
}
} on FormatException {
setState(() => this.barcode =
'null (User returned using the "back"-button before scanning anything. Result)');
} catch (e) {
setState(() => this.barcode = 'Unknown error: $e');
}
}
}
Main problem is when we pass blank or null string in ".child()" method of firebase, it will give us split("/") error because internally it will try to split from string and get try to get data
from it.
Now the problem in your code is you are calling "classList(userUid)" in the widget override method before the data come from firebase userid with use of StreamBuilder() but the userUid is blank and as i said above,
firebase will give us split("/") error if we pass blank or null in that ".child()" method.
So the conclusion is we have to wait for firebase userid until we get it from async result because to get firebase userid which is async task and we have to wait for that until result come with using await keyword.
So Here is the answer, how to do that:
You have to replace your body portion in widget with the use of future<> such as below:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: new FutureBuilder<FirebaseUser>(
future: FirebaseAuth.instance.currentUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return new Container(child: classList(snapshot.data.uid));
}
else {
return new Text('Loading...');
}
},
),
);
}
Also the best practice is that you have to get firebase userid only in "initState()" method which will call only once during lifecycle. so declare "FirebaseUser user" globally in your class and then call your "userUi()"
in only "initState()" method.
The method 'split' was called on null.
This type of exceptions occurs whenever you are referencing a path that doesn't exist. So make sure the path of your firebase database is correct.
Related
This is the variable initialisation
var displayResult = '';
Here is the on press code
Padding(
padding: EdgeInsets.all(5.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
color: Theme
.of(context)
.primaryColor,
textColor: Theme
.of(context)
.primaryColorLight,
child: Text("calculate"),
onPressed: () {
setState(() {
this.displayResult = _calculateTotalReturn();
});
},
)),
This the function Im trying to call
String _calculateTotalReturn() {
setState(() {
double principle = double.parse(principleController.text);
double roi = double.parse(roiController.text);
double term = double.parse(termController.text);
double tap = principle + (principle * roi * term) / 100;
String result = "After $term years, your investment will worth $tap $_currentItemSelected";
return result;
});
}
This is the error I'm getting
Performing hot reload...
Syncing files to device iPhone XR...
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building SIForm(dirty, dependencies:
flutter: [_LocalizationsScope-[GlobalKey#4c1f9], _InheritedTheme], state: _SIFormState#b2966):
flutter: 'package:flutter/src/widgets/text.dart': Failed assertion: line 237 pos 15: 'data != null': is not
flutter: true.
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #2 new Text (package:flutter/src/widgets/text.dart:237:15)
flutter: #3 _SIFormState.build (package:simple_cal/main.dart:153:24)
flutter: #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
flutter: #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3736:15)
flutter: #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
flutter: #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2273:33)
flutter: #8 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:700:20)
flutter: #9 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:268:5)
flutter: #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:988:15)
flutter: #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:928:9)
flutter: #12 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:749:7)
flutter: #14 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
flutter: #15 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
flutter: #16 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
flutter: (elided 3 frames from class _AssertionError and package dart:async)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
Reloaded 1 of 432 libraries in 641ms.
This is the complete main.dart file
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
Widget MyApp() {
return MaterialApp(
title: 'Simple Intrest app',
home: SIForm (),
theme: ThemeData(
primaryColor: Colors.deepPurple,
accentColor: Colors.deepPurpleAccent
),
);
}
class SIForm extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _SIFormState ();
}
}
class _SIFormState extends State<SIForm> {
var _currencies = ["INR", "USD", "CAD"];
var _currentItemSelected = "INR";
var displayResult = '';
TextEditingController principleController = TextEditingController();
TextEditingController roiController = TextEditingController();
TextEditingController termController = TextEditingController();
#override
Widget build(BuildContext context) {
TextStyle textStyle = Theme
.of(context)
.textTheme
.title;
return Scaffold(
appBar: AppBar(
title: Text("Simple Interest Calc"),
),
body: Container(padding: EdgeInsets.only(top: 50.0),
child: ListView(
children: <Widget>[
Padding(
padding: EdgeInsets.all(5.0),
child: TextField(
keyboardType: TextInputType.number,
controller: principleController,
decoration: InputDecoration(
labelText: 'principle',
hintText: '0.00',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
)
),
)),
Padding(
padding: EdgeInsets.all(5.0),
child: TextField(
controller: roiController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Rate of Interest',
hintText: '0.00',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
)
),
)),
Padding(
padding: EdgeInsets.all(5.0),
child: Row(
children: <Widget>[
Expanded(child: TextField(
controller: termController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Terms',
hintText: '%',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
)
),
)),
Container(width: 10.0),
Expanded(
child: DropdownButton<String>(
items: _currencies.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
value: _currentItemSelected,
onChanged: (val) {
_ondropDownChange(val);
},),
),
],
)),
Padding(
padding: EdgeInsets.all(5.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
color: Theme
.of(context)
.primaryColor,
textColor: Theme
.of(context)
.primaryColorLight,
child: Text("calculate"),
onPressed: () {
setState(() {
this.displayResult = _calculateTotalReturn();
});
},
)),
Container(width: 5.0),
Expanded(
child: RaisedButton(
color: Theme
.of(context)
.accentColor,
textColor: Theme
.of(context)
.primaryColorLight,
child: Text("Reset"),
onPressed: () {
setState(() {
// _reset();
});
}
)),
],
)),
Padding(
padding: EdgeInsets.all(5.0),
child: Text(this.displayResult),
)
],
),
),
);
}
void _ondropDownChange(String value) {
setState(() {
this._currentItemSelected = value;
});
}
String _calculateTotalReturn() {
setState(() {
double principle = double.parse(principleController.text);
double roi = double.parse(roiController.text);
double term = double.parse(termController.text);
double tap = principle + (principle * roi * term) / 100;
String result = "After $term years, your investment will worth $tap $_currentItemSelected";
return result;
});
}
void _reset() {
setState(() {
this.principleController.text = " ";
this.roiController.text = " ";
this.termController.text = " ";
this.displayResult = " ";
});
}
}
You should get rid of the setState in _calculateTotalReturn. The return result; there is returning from the inline function that you give to setState and _calculateTotalReturn actually returns null.
I tried something like this:
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(widget.title),
),
child: Center(
child: Container(
child: CupertinoButton.filled(
child: const Text('Push screen'),
onPressed: () {
CupertinoNavigationBar navBar = CupertinoNavigationBar(
leading: Row(children: <Widget>[
const CupertinoNavigationBarBackButton(),
CupertinoButton(
child: const Text('Button 2'),
padding: EdgeInsets.zero,
onPressed: () {},
),
]),
);
Navigator.push(context, CupertinoPageRoute<CupertinoPageScaffold>(
builder: (_) => CupertinoPageScaffold(
navigationBar: navBar,
child: Center(child: const Text('Content')),
)
));
},
),
),
),
);
}
And when tapping the button, it fails with
I/flutter (30855): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (30855): The following NoSuchMethodError was thrown building CupertinoNavigationBarBackButton(dirty):
I/flutter (30855): The getter 'canPop' was called on null.
I/flutter (30855): Receiver: null
I/flutter (30855): Tried calling: canPop
The reason is that this code in CupertinoNavigationBarBackButton returns null
final ModalRoute<dynamic> currentRoute = ModalRoute.of(context);
I wonder why that's the case? Is it because when I push the button, context still hasn't gotten the route yet?
What's the correct way to manually add a back button?
Thanks in advance.
Here is a very simple snippet of code. I hope it helps you:
class DemoView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
leading: GestureDetector(
onTap: () {
debugPrint('Back button tapped');
},
child: Row(
children: <Widget>[
Icon(CupertinoIcons.left_chevron),
Text(
'Back',
style: TextStyle(
color: CupertinoColors.activeBlue,
),
),
],
),
),
middle: Text('Demo'),
trailing: GestureDetector(
onTap: () {
debugPrint('add icon tapped');
},
child: Icon(
CupertinoIcons.add,
color: CupertinoColors.black,
),
),
),
child: Center(
child: Text(
'Content',
style: TextStyle(fontSize: 36.0),
),
),
);
}
}
Which is the correct way to add manually back button?
I use code like this:
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(widget.title),
leading: CupertinoNavigationBarBackButton(
onPressed: () => Navigator.of(context).pop(),
),
child: _myAppBody() // return widget
),
);
}
First of all, I'm a beginner at Flutter. I'm sending form data to login API and waiting for Success: OK message and UserID from API.
After getting UserID and Succes: OK response from API I'm sending the user to the dashboard with userID Here is my full code ;
class LoginScreen1 extends StatefulWidget {
#override
_LoginScreen1State createState() => _LoginScreen1State();
}
class _LoginScreen1State extends State<LoginScreen1> {
StreamSubscription streamSubscription;
String formMail, formSifre;
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
final formKey = GlobalKey<FormState>();
Login login;
Future<Login> _gonderiGetir(String formMail, String formSifre) async {
var url = 'MYURL';
var apiKey = "MYKEY";
var authPassword = this.formSifre;
var authMail = this.formMail;
debugPrint(this.formSifre);
var response = await http
.get('$url?Key=12345&mail=${this.formMail}&password=${this.formSifre}');
debugPrint("Sonuç Bekleniyor.");
if (response.statusCode == 200) {
_gelenDegeriBekle();
return Login.fromJsonMap(json.decode(response.body));
} else {
throw Exception("Baglanamadık ${response.statusCode}");
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
/*_gonderiGetir(formSifre, formMail).then((gelenDeger) {
login = gelenDeger;
debugPrint(login.UserID);
});*/
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Color(0xFFF7F8FA),
child: ListView(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: 250.0,
width: double.infinity,
),
Container(
height: 300.0,
width: double.infinity,
color: Color(0xFFFED428),
),
Positioned(
top: 225.0,
left: 15.0,
right: 15.0,
child: Material(
elevation: 3.0,
borderRadius: BorderRadius.circular(7.0),
child: Container(
height: 280.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
color: Color(0xF6F6F6)),
),
)),
Positioned(
top: 75.0,
left: (MediaQuery.of(context).size.width / 2 - 50.0),
child: CircleAvatar(
radius: 50.0,
backgroundImage: NetworkImage(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHVRLWSF79r7ABstLzXZi_pTcNkAMqx8EtWfIRZiA8mmqcl-Fsqw"),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(40, 235, 40, 15),
child: Form(
key: formKey,
autovalidate: true,
child: Column(
children: <Widget>[
TextFormField(
decoration: const InputDecoration(
labelStyle: TextStyle(color: Color(0xFFBBBFCB)),
icon: Icon(
Icons.person,
color: Color(0xFFBBBFCB),
),
labelText: 'Email *',
),
validator: (String girilenVeri) {
if (!girilenVeri.contains("#")) {
return "Geçerli bir mail adresi giriniz.";
} else
return null;
},
controller: _usernameController,
onSaved: (deger) => formMail = deger,
),
SizedBox(
height: 10.0,
),
TextFormField(
obscureText: true,
decoration: const InputDecoration(
labelStyle: TextStyle(color: Color(0xFFBBBFCB)),
icon: Icon(
Icons.lock,
color: Color(0xFFBBBFCB),
),
labelText: 'Şifre *',
),
validator: (String girilenVeri) {
if (girilenVeri.length < 6) {
return "Şifre 6 karakterden kısa olamaz.";
} else
return null;
},
controller: _passwordController,
onSaved: (deger) => formSifre = deger,
),
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(40, 420, 40, 15),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
width: double.infinity,
height: 50,
child: RaisedButton(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Color(0xFFFED428),
onPressed: () {
if (formKey.currentState.validate()) {
formKey.currentState.save();
_gonderiGetir(formMail, formSifre);
debugPrint("OnPress Geldi");
}
},
child: Text(
"GİRİŞ",
style: TextStyle(fontSize: 20),
),
),
),
FlatButton(
onPressed: () {},
child: Text(
"Şifremi Unuttum",
style: TextStyle(
fontSize: 10, color: Color(0xFFBBBFCB)),
),
)
],
),
),
),
],
)
],
),
),
);
;
}
void _loginControl() {
if (formKey.currentState.validate()) {
formKey.currentState.save();
//formMail = _usernameController.text;
//formSifre= _passwordController.text;
debugPrint("$formSifre ve $formMail");
}
}
void _gelenDegeriBekle() {
_gonderiGetir(formSifre, formMail).then((gelenDeger) {
login = gelenDeger;
if (login.Status != null) {
debugPrint(login.UserID);
debugPrint(login.Status);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => MyHomePage(),
),
);
}
});
}
}
But i'm getting this loop error:
flutter: asdasd
flutter: 387ddd00-f5ed-4c9c-87cf-45835bf77a53
flutter: OK
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method 'ancestorStateOfType' was called on null.
Receiver: null
Tried calling: ancestorStateOfType(Instance of 'TypeMatcher<NavigatorState>')
#0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
#1 Navigator.of (package:flutter/src/widgets/navigator.dart:1376:19)
#2 Navigator.pushReplacement (package:flutter/src/widgets/navigator.dart:1055:22)
#3 _LoginScreen1State._gelenDegeriBekle.<anonymous closure> (package:flutter_apppp/login.dart:247:19)
#4 _rootRunUnary (dart:async/zone.dart:1132:38)
#5 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#6 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
#7 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
#8 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
#9 Future._complete (dart:async/future_impl.dart:473:7)
#10 _SyncCompleter.complete (dart:<…>
I keep getting this error message.
It looks like you have a loop that continuously runs in your widget. You're calling _gonderiGetir from _gelenDegeriBekle and also calling _gelenDegeriBekle from _gonderiGetir. So it's going to keep doing this forever, even after your widget has been removed (which is why context is null).
If you need to do something continuously, I'd recommend instead using a periodic timer to call it, and making sure that the timer is stopped when your widget is disposed!
I am trying to parse JSON and convert it into list view.
I am getting the response body and it is been converted to list also but its sending null to the future builder, I am getting this error:
/flutter ( 9715): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9715): The following assertion was thrown building FutureBuilder<List<Event>>(dirty, state:
I/flutter ( 9715): _FutureBuilderState<List<Event>>#6efa6):
I/flutter ( 9715): A build function returned null.
I/flutter ( 9715): The offending widget is: FutureBuilder<List<Event>>
I/flutter ( 9715): Build functions must never return null. To return an empty space that causes the building widget to
I/flutter ( 9715): fill available room, return "new Container()". To return an empty space that takes as little room as
I/flutter ( 9715): possible, return "new Container(width: 0.0, height: 0.0)".
I/flutter ( 9715):
I/flutter ( 9715): When the exception was thrown, this was the stack:
The code is:
import 'package:flutter/material.dart';
import 'package:event/models/readEvent.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:event/models/global.dart';
import 'dart:async';
import 'dart:convert';
import 'package:isolate/isolate_runner.dart';
Map<String, dynamic> body = {
"query": {"key": "XOXOXO", "value": "YOY", "specific": ""}
};
Future<List<Event>> fetchPosts(http.Client client) async {
http.post(URL_READEVENT, body: json.encode(body)).then((response) {
print(response.body);
final parsed = json.decode(response.body);
print(response.body);
print(parsed['rs']);
List<Event> event= (parsed["rs"] as List).map<Event>((json) =>
new Event.fromJson(json)).toList();
print(event[0].name);
return event;
});
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _count = 0;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(
'Events',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.white,
),
body: Container(
child: Center(
child: Column(children: <Widget>[
Row(children: <Widget>[
Container(
padding: EdgeInsets.only(right: 20.0, left: 30.0, top: 16.0),
child: Image.asset('lib/images/dscnew.png',
width: 120.0, height: 120.0, fit: BoxFit.cover),
),
Column(children: <Widget>[
Text(
"Developer Student Clubs",
style: TextStyle(fontWeight: FontWeight.w700),
),
Text(
"VIT Vellore",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.grey, fontWeight:FontWeight.w500),
)
]),
]),
new FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
print(snapshot.hasData);
if (snapshot.data!=null) {
print(snapshot.data);
return ListViewPosts(events: snapshot.data);
} else {
return new CircularProgressIndicator();
}
}
}
),
);
}
class ListViewPosts extends StatelessWidget {
final List<Event> events;
ListViewPosts({Key key, this.events}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 600,
width: 600,
child: Expanded(child:ListView.builder(
itemCount: events.length,
padding: const EdgeInsets.all(15.0),
itemBuilder: (context, position) {
return Column(
children: <Widget>[
Divider(height: 5.0),
ListTile(
title: Text(
'${events[0].name}',
style: TextStyle(
fontSize: 22.0,
color: Colors.deepOrangeAccent,
),
),
subtitle: Text(
'${events[0].status}',
style: new TextStyle(
fontSize: 18.0,
fontStyle: FontStyle.italic,
),
),
leading: Column(
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.blueAccent,
radius: 35.0,
child: Text(
'User ${events[0].clubName}',
style: TextStyle(
fontSize: 22.0,
color: Colors.white,
),
),
)
],
),
onTap: () => _onTapItem(context, events[position]),
),
],
);
}),
)
);
}
void _onTapItem(BuildContext context, Event post) {
// Scaffold
// .of(context)
// .showSnackBar(new SnackBar(content: new Text(post.id.toString() + ' - ' + post.title)));
}
}
The problem is that when your FutureBuilder returns with no data (when the FutureBuilder is first loaded) you do not return a widget.
Try changing your FutureBuilder like so:
FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CircularProgressIndicator();
},
)
#Jordan Davies answer is definitely correct but i want to add something for iOS. If you check this in both Android and iOS then you should code like following:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; // This is for IOS widgets
class API extends StatefulWidget {
#override
_APIState createState() => _APIState();
}
class _APIState extends State<API> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("POST JSON"),
),
body: Theme.of(context).platform == TargetPlatform.android
? loadAndroidLayout()
: loadIOSLayout(),
);
}
}
Widget loadIOSLayout(){
return FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CupertinoActivityIndicator(); //IOS loading Widget
}
}
Widget loadAndroidLayout(){
return FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CircularProgressIndicator(); //Android loading Widget
}),
}
FutureBuilder has initialData: []
return FutureBuilder(
future: fetchPosts(new http.Client()),
initialData: [],
builder: (context, AsyncSnapshot<List<dynamic>> snapshot){
return ListViewPosts(events: snapshot.data);
});
I am trying to use the Share package provided by the Flutter team. I tried implementing the package and when that didn't work I tried straight up copying and pasting their code, but got an error just the same. Unfortunately the error is not very helpful and the description of the error says "we need to explain this better". Any ideas?
Here's the package I'm using
My Code:
FlatButton(
child: Text(
'Share',
style: TextStyle(
color: Color.fromRGBO(245, 93, 62, 1.0)),
),
color: Colors.grey[100],
onPressed: () {
final RenderBox box = context.findRenderObject();
Share.share('Hello this is a test',
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
},
),
The Error:
flutter: The following assertion was thrown while handling a gesture:
flutter: type 'RenderSliverList' is not a subtype of type 'RenderBox'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 _EverythingState._buildEventCards.<anonymous closure> (package:loopt_in/widgets/everything.dart:175:43)
flutter: #1 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:507:14)
flutter: #2 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:562:30)
flutter: #3 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
flutter: #4 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
flutter: #5 TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:204:7)
flutter: #6 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
flutter: #7 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:184:20)
flutter: #8 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:158:22)
flutter: #9 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:138:7)
flutter: #10 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:101:7)
flutter: #11 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:85:7)
flutter: #12 _invoke1 (dart:ui/hooks.dart:165:13)
flutter: #13 _dispatchPointerDataPacket (dart:ui/hooks.dart:119:5)
flutter: Handler: onTap
flutter: Recognizer:
flutter: TapGestureRecognizer#ecc56(debugOwner: GestureDetector, state: ready, won arena, finalPosition:
flutter: Offset(196.0, 747.5), sent tap down)
Update
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:share/share.dart';
class Everything extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _EverythingState();
}
}
class _EverythingState extends State<Everything> {
Widget _buildEventCards(BuildContext context, DocumentSnapshot document) {
var width = MediaQuery.of(context).size.width;
return Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 14.0),
child: Card(
elevation: 0.0,
child: Column(
children: <Widget>[
Image.asset(
document['image'],
fit: BoxFit.cover,
),
Container(
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0),
child: Column(
children: <Widget>[
SizedBox(
height: 15.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Icon(document['icon']),
],
),
],
),
SizedBox(
height: 10.0,
),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.start,
children: <Widget>[
Chip(
backgroundColor: Colors.grey[100],
label: Text(
document['date'],
),
),
SizedBox(
width: 10.0,
),
Chip(
backgroundColor: Colors.grey[100],
label: Text(document['source']),
),
SizedBox(
width: 10.0,
),
Chip(
backgroundColor: Colors.grey[100],
label: Text(
document['location'],
),
),
],
),
SizedBox(
height: 15.0,
),
Container(
width: width,
child: Text(
document['title'],
style: TextStyle(fontSize: 24.0),
),
),
SizedBox(
height: 20.0,
),
Text(document['desc']),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
FlatButton(
child: Text(
'More',
style: TextStyle(
color: Color.fromRGBO(118, 190, 208, 1.0)),
),
color: Colors.grey[100],
onPressed: () {
print('webview clicked');
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => WebviewScaffold(
url: document['url'],
appBar: AppBar(
title: Text(document['source']),
backgroundColor: Color.fromRGBO(
135,
142,
136,
1.0,
),
),
),
),
);
},
),
SizedBox(
width: 15.0,
),
FlatButton(
child: Text(
'Share',
style: TextStyle(
color: Color.fromRGBO(245, 93, 62, 1.0)),
),
color: Colors.grey[100],
onPressed: () {
final RenderBox box = context.findRenderObject();
Share.share('Hello this is a test',
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
},
),
],
),
],
),
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance.collection('stories').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_buildEventCards(context, snapshot.data.documents[index]),
);
});
}
// #override
// void initState() {
// // TODO: implement initState
// super.initState();
// FirebaseAdMob.instance.initialize(appId: FirebaseAdMob.testAppId);
// var bannerAd = _buildBanner()..load();
// }
}
New Error Traceback
[VERBOSE-2:shell.cc(184)] Dart Error: Unhandled exception:
MissingPluginException(No implementation found for method share on channel plugins.flutter.io/share)
#0 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:291:7)
<asynchronous suspension>
#1 Share.share (package:share/share.dart:44:20)
#2 ShareButton.build.<anonymous closure> (package:loopt_in/widgets/everything.dart:220:17)
#3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:507:14)
#4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:562:30)
#5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
#6 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
The issue in this line
RenderBox box = context.findRenderObject();
the right side return RenderSliverList and you assigning it to RenderBox that why there is a mismatch type.
What excactly you are trying to share? so I can help with that
Edit:
You need to extract share button into its own widget. Try the following complete code. It works.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:share/share.dart';
class Everything extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _EverythingState();
}
}
class _EverythingState extends State<Everything> {
Widget _buildEventCards(BuildContext context, DocumentSnapshot document) {
var width = MediaQuery.of(context).size.width;
return Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 14.0),
child: Card(
elevation: 0.0,
child: Column(
children: <Widget>[
Image.asset(
document['image'],
fit: BoxFit.cover,
),
Container(
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0),
child: Column(
children: <Widget>[
SizedBox(
height: 15.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Icon(document['icon']),
],
),
],
),
SizedBox(
height: 10.0,
),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.start,
children: <Widget>[
Chip(
backgroundColor: Colors.grey[100],
label: Text(
document['date'],
),
),
SizedBox(
width: 10.0,
),
Chip(
backgroundColor: Colors.grey[100],
label: Text(document['source']),
),
SizedBox(
width: 10.0,
),
Chip(
backgroundColor: Colors.grey[100],
label: Text(
document['location'],
),
),
],
),
SizedBox(
height: 15.0,
),
Container(
width: width,
child: Text(
document['title'],
style: TextStyle(fontSize: 24.0),
),
),
SizedBox(
height: 20.0,
),
Text(document['desc']),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
FlatButton(
child: Text(
'More',
style: TextStyle(
color: Color.fromRGBO(118, 190, 208, 1.0)),
),
color: Colors.grey[100],
onPressed: () {
print('webview clicked');
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => WebviewScaffold(
url: document['url'],
appBar: AppBar(
title: Text(document['source']),
backgroundColor: Color.fromRGBO(
135,
142,
136,
1.0,
),
),
),
),
);
},
),
SizedBox(
width: 15.0,
),
new MyButton(),
],
),
],
),
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance.collection('stories').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_buildEventCards(context, snapshot.data.documents[index]),
);
});
}
// #override
// void initState() {
// // TODO: implement initState
// super.initState();
// FirebaseAdMob.instance.initialize(appId: FirebaseAdMob.testAppId);
// var bannerAd = _buildBanner()..load();
// }
}
class MyButton extends StatelessWidget {
const MyButton({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return FlatButton(
child: Text(
'Share',
style: TextStyle(
color: Color.fromRGBO(245, 93, 62, 1.0)),
),
color: Colors.grey[100],
onPressed: () {
final RenderBox box = context.findRenderObject();
Share.share('Hello this is a test',
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
},
);
}
}
In case anyone is still having issues on this. Here is a code that works for me.
shareData(BuildContext context){
Share.share('Some text here',
subject: 'Update the coordinate!',
sharePositionOrigin: Rect.fromLTWH(left, top, width, height)
);
}