Flutter Web Unexpected Null Value - flutter

enter image description here I get Unexpected Null value error when switching from Home page to Vehicle Add page. I couldn't understand what caused this.
I tried to run it in debug mode, but it was very confusing in debug mode, I couldn't understand it.
home.dart page
import 'package:Car_Price_App/Pages/category_add.dart';
import 'package:Car_Price_App/Pages/vehicle_add.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../services/auth_service.dart';
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser;
final email = user?.email;
return Scaffold(
appBar: AppBar(
title: Center(child: Text("Sıfır Araçlar ${email?.toUpperCase()}")),
leading: const Icon(Icons.car_rental),
actions: [
IconButton(onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=> CategoryAdd(gelenEmail: email.toString(),)));
print("giden $email");
}, icon: const Icon(Icons.category)),
IconButton(onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=> VehicleAdd()));
}, icon: const Icon(Icons.add)),
IconButton(onPressed: () {}, icon: const Icon(Icons.update)),
IconButton(onPressed: () {}, icon: const Icon(Icons.delete)),
],
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Giriş Yapıldı $email"),
const SizedBox(height: 10,),
ElevatedButton(onPressed: (){
AuthService().signOut();
}, child: const Text("Çıkış Yap",),),
],
),
),
);
}
}
vehicle_add.dart page
import 'dart:io';
import 'dart:math';
import 'dart:core';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:currency_text_input_formatter/currency_text_input_formatter.dart';
import 'package:file_picker/file_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../models/trade_mark_model.dart';
import '../models/type_of_vehicle_model.dart';
import '../models/vehicle_body_type_model.dart';
import '../models/vehicle_model.dart';
import '../models/vehicle_year_model.dart';
class VehicleAdd extends StatefulWidget {
const VehicleAdd({Key? key}) : super(key: key);
#override
State<VehicleAdd> createState() => _VehicleAddState();
}
class _VehicleAddState extends State<VehicleAdd> {
GlobalKey? aracEkleKey = GlobalKey<FormState>();
var db = FirebaseFirestore.instance;
TextEditingController vehicleProperties = TextEditingController();
TextEditingController vehiclePrice = TextEditingController();
String? vasitaTipi = "";
String? kasaTipi = "";
String? marka = "";
String? model = "";
String? yil = "";
PlatformFile? pickedFile;
UploadTask? uploadTask;
Future selectFile() async {
final result = await FilePicker.platform.pickFiles();
if (result == null) return;
setState(() {
pickedFile = result.files.first;
});
}
Future uploadFile() async {
final path = 'aracResimleri/${pickedFile?.name}';
final file = File(pickedFile!.path!);
final ref = FirebaseStorage.instance.ref().child(path);
setState(() {
uploadTask = ref.putFile(file);
});
final snapshot = await uploadTask?.whenComplete(() {});
final urlDownload = await snapshot?.ref.getDownloadURL();
print('Download Link : $urlDownload');
setState(() {
uploadTask = null;
});
}
Stream<List<TypeOfVehicleModel>> readVehicleType() => db.collection("Vasıtalar").snapshots().map((snapshot) => snapshot.docs.map((doc) => TypeOfVehicleModel.fromJson(doc.data())).toList());
Stream<List<VehicleBodyTypeModel>> readBodyType() => db.collection("KasaTipleri").snapshots().map((snapshot) => snapshot.docs.map((doc) => VehicleBodyTypeModel.fromJson(doc.data())).toList());
Stream<List<TradeMarkModel>> readTradeMark() => db.collection("Markalar").snapshots().map((snapshot) => snapshot.docs.map((doc) => TradeMarkModel.fromJson(doc.data())).toList());
Stream<List<VehicleModel>> readVehicleModel() => db.collection("Modeller").snapshots().map((snapshot) => snapshot.docs.map((doc) => VehicleModel.fromJson(doc.data())).toList());
Stream<List<VehicleYearModel>> readVehicleYear() => db.collection("Yıllar").snapshots().map((snapshot) => snapshot.docs.map((doc) => VehicleYearModel.fromJson(doc.data())).toList());
late int _key;
_collapse() {
int? newKey;
do {
_key = Random().nextInt(10000);
} while (newKey == _key);
}
#override
void initState() {
super.initState();
_collapse();
}
#override
Widget build(BuildContext context) {
var screenInfo = MediaQuery.of(context);
final double screenWidth = screenInfo.size.width;
final double screenHeight = screenInfo.size.height;
return Scaffold(
appBar: AppBar(
title: const Text("Araç Ekle"),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
child: Center(
child: Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
key: aracEkleKey,
child: SizedBox(
width: screenWidth / 2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FutureBuilder<List<TypeOfVehicleModel>>(
future: readVehicleType().first,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text("Something went wrong");
} else if (snapshot.hasData) {
final typeOfVehicle = snapshot.data!;
return ExpansionTile(
key: Key(_key.toString()),
initiallyExpanded: false,
leading: const Icon(Icons.merge_type),
title: const Text("Vasıta Seçiniz"),
children: typeOfVehicle.map(buildTov).toList(),
);
} else {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
},
), // Vasıta Tipi
Text("$vasitaTipi"),
Text("$kasaTipi"),
Text("$marka"),
Text("$model"),
Text("$yil"),
FutureBuilder<List<VehicleBodyTypeModel>>(
future: readBodyType().first,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text("Something went wrong");
} else if (snapshot.hasData) {
final bodyType = snapshot.data!;
return ExpansionTile(
key: Key(_key.toString()),
initiallyExpanded: false,
leading: const Icon(Icons.type_specimen),
title: const Text("Kasa Tipi Seçiniz"),
children: bodyType.map(buildBodyType).toList(),
);
} else {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
},
), // Kasatipi
FutureBuilder<List<TradeMarkModel>>(
future: readTradeMark().first,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text("Something went wrong");
} else if (snapshot.hasData) {
final tradeMarka = snapshot.data!;
return ExpansionTile(
key: Key(_key.toString()),
initiallyExpanded: false,
leading: const Icon(Icons.branding_watermark),
title: const Text("Marka Seçiniz"),
children: tradeMarka.map(buildTradeMark).toList(),
);
} else {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
},
), //Markalar
FutureBuilder<List<VehicleModel>>(
future: readVehicleModel().first,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text("Something went wrong");
} else if (snapshot.hasData) {
final model = snapshot.data!;
return ExpansionTile(
key: Key(_key.toString()),
initiallyExpanded: false,
leading: const Icon(Icons.time_to_leave),
title: const Text("Model Seçiniz"),
children: model.map(buildModel).toList(),
);
} else {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
},
), //Modeller
FutureBuilder<List<VehicleYearModel>>(
future: readVehicleYear().first,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text("Something went wrong");
} else if (snapshot.hasData) {
final year = snapshot.data!;
return ExpansionTile(
key: Key(_key.toString()),
initiallyExpanded: false,
leading: const Icon(Icons.calendar_month),
title: const Text(
"Yıl Seçiniz",
),
children: year.map(buildYear).toList(),
);
} else {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
},
), //Yıllar
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: vehicleProperties,
decoration: const InputDecoration(
labelText: "Araç Özellikleri Giriniz",
suffixText: "Araç Özellikleri Giriniz",
border: OutlineInputBorder(),
),
minLines: 1,
maxLines: screenHeight.toInt(),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
// for below version 2 use this
FilteringTextInputFormatter.allow(RegExp(
r'\d',
)),
FilteringTextInputFormatter.digitsOnly,
CurrencyTextInputFormatter(
symbol: '₺',
name: "TL",
)
],
controller: vehiclePrice,
decoration: const InputDecoration(
labelText: "Araç Fiyat Giriniz",
suffixText: "Araç Fiyat Giriniz",
border: OutlineInputBorder(),
),
minLines: 1,
maxLines: screenHeight.toInt(),
),
),
Expanded(
child: Image.file(
File(pickedFile!.path!),
width: double.infinity,
fit: BoxFit.cover,
),
),
ElevatedButton.icon(
icon: const Icon(Icons.image),
onPressed: () {
selectFile();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Araç Resmi Seç"),
content: Text(pickedFile!.name),
actions: [
TextButton(
onPressed: () async {
uploadFile();
},
child: const Center(
child: Text(
"Galeri'den Seç",
style: TextStyle(color: Colors.black, fontSize: 20),
))),
],
);
});
},
label: const Text("Araç Resimi Ekle"),
),
const SizedBox(
height: 30,
),
StreamBuilder<TaskSnapshot>(
stream: uploadTask!.snapshotEvents,
builder: (context, snapshot) {
if (snapshot.hasData) {
final data = snapshot.data!;
double progress = data.bytesTransferred / data.totalBytes;
return SizedBox(
height: 50,
child: Stack(
fit: StackFit.expand,
children: [
LinearProgressIndicator(
value: progress,
color: Colors.green,
backgroundColor: Colors.grey,
),
Center(
child: Text(
'${(100 * progress).roundToDouble()} %',
style: const TextStyle(color: Colors.white),
),
)
],
),
);
} else {
return const SizedBox(
height: 50,
);
}
},
)
],
),
),
),
),
),
),
// Fab Buton visible olacak doldurulması geren herşey dolduğunda gözükecek
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
// bool kontrolSonucu = aracEkleKey.currentState!.validate();
},
),
);
}
Widget buildTov(TypeOfVehicleModel typeOfVehicleModel) => ListTile(
onTap: () {
setState(() {
_collapse();
vasitaTipi = typeOfVehicleModel.typeOfVehicle;
});
if (kDebugMode) {
print("$vasitaTipi");
}
},
leading: const Icon(
Icons.stars_outlined,
size: 10,
),
title: Text(typeOfVehicleModel.typeOfVehicle.toString()),
); //Araç vasıta tipi
Widget buildBodyType(VehicleBodyTypeModel vehicleBodyTypeModel) => ListTile(
onTap: () {
setState(() {
_collapse();
kasaTipi = vehicleBodyTypeModel.vehicleBodyType;
});
if (kDebugMode) {
print(vehicleBodyTypeModel.vehicleBodyType);
}
},
leading: const Icon(
Icons.stars_outlined,
size: 10,
),
title: Text(vehicleBodyTypeModel.vehicleBodyType.toString()),
); // Araç kasa tipi
Widget buildTradeMark(TradeMarkModel tradeMarkModel) => ListTile(
onTap: () {
setState(() {
_collapse();
marka = tradeMarkModel.tradeMarkName;
});
if (kDebugMode) {
print(tradeMarkModel.tradeMarkName);
}
},
leading: const Icon(
Icons.stars_outlined,
size: 10,
),
title: Text(tradeMarkModel.tradeMarkName.toString()),
); // Araç MArka
Widget buildModel(VehicleModel vehicleModel) => ListTile(
onTap: () {
setState(() {
_collapse();
model = vehicleModel.modelName;
});
if (kDebugMode) {
print(vehicleModel.modelName);
}
},
leading: const Icon(
Icons.stars_outlined,
size: 10,
),
title: Text(vehicleModel.modelName.toString()),
); // Araç Modeli
Widget buildYear(VehicleYearModel vehicleYearModel) => ListTile(
onTap: () {
setState(() {
_collapse();
yil = vehicleYearModel.year;
});
if (kDebugMode) {
print(vehicleYearModel.year);
}
},
leading: const Icon(
Icons.stars_outlined,
size: 10,
),
title: Text(vehicleYearModel.year.toString()),
); // Araç Yılı
Widget buildProgress() => StreamBuilder<TaskSnapshot>(
stream: uploadTask?.snapshotEvents,
builder: (context, snapshot) {
if (snapshot.hasData) {
final data = snapshot.data!;
double progress = data.bytesTransferred / data.totalBytes;
return SizedBox(
height: 50,
child: Stack(
fit: StackFit.expand,
children: [
LinearProgressIndicator(
value: progress,
color: Colors.green,
backgroundColor: Colors.grey,
),
Center(
child: Text(
'${(100 * progress).roundToDouble()} %',
style: const TextStyle(color: Colors.white),
),
)
],
),
);
} else {
return const SizedBox(
height: 50,
);
}
},
);
}
I don't know which variable is causing the problem. I'm inexperienced in flutter.

The error message says on which line the error is. See
That means it's on line 297. If I'm not mistaken that is the line:
child: Image.file(File(pickedFile!.path!),
So pickedFile is null

Related

I was trying to show user a feedback message to in password reset by Email, But it's not working

I'm creating a reset password page for my flutter app and I'm using showDialog for giving the feedback to the user to, but while running the code the message does not appear in screen, kindly check the code and tell me is there any mistate which I have made.
If anyone know the solution please help, I was trying to solve it but I can't find any solution.
The code is below:
class ForgotPasswordMailScreen extends StatefulWidget {
const ForgotPasswordMailScreen({Key? key}) : super(key: key);
#override
State<ForgotPasswordMailScreen> createState() =>
_ForgotPasswordMailScreenState();
}
final TextEditingController _email = TextEditingController();
class _ForgotPasswordMailScreenState extends State<ForgotPasswordMailScreen> {
final formKey = GlobalKey<FormState>();
bool loading = false;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios_new,
color: Colors.blue,
),
),
),
body: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(kDefaultSize),
child: Column(
children: [
const SizedBox(height: kDefaultSize * 4),
const FormHeaderWidget(
image: kForgotPasswordImage,
title: kForgotPassword,
subTitle: kForgotEmailTitle,
crossAxisAlignment: CrossAxisAlignment.center,
heightBetween: 10.0,
textAlign: TextAlign.center,
),
const SizedBox(height: kFormHeight),
Form(
key: formKey,
child: Column(
children: [
TextFormField(
controller: _email,
validator: (value) {
if (value!.isEmpty ||
!RegExp(r'^[\w-\.]+#([\w-]+\.)+[a-z]{2,5}$')
.hasMatch(value)) {
return 'Enter a valid email address.';
} else {
return null;
}
},
decoration: const InputDecoration(
label: Text(kEmail),
hintText: kEmail,
prefixIcon: Icon(Icons.mail_outline_rounded),
),
),
const SizedBox(height: 20.0),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
resetPassword();
formKey.currentState?.reset();
// _email.clear();
}
},
child: const Text(kNext),
),
),
],
),
),
],
),
),
),
),
);
}
// showLoadingScreen() {}
showMessage() {
showDialog(
context: context,
builder: (context) {
return const AlertDialog(
content: Text('Password reset link sent! Check your email.'),
);
});
}
showErrorMessage(String eMsg) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(eMsg),
);
});
}
resetPassword() async {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(),
),
);
try {
await FirebaseAuth.instance
.sendPasswordResetEmail(email: _email.text.trim())
.then((value) {
Navigator.pop(context);
});
showMessage();
} on FirebaseAuthException catch (e) {
String error = e.message.toString();
showErrorMessage(error);
Navigator.pop(context);
}
}
}

Flutter text message is not being displayed on the foreground but is visible on cloud firestore

I have been working on the chat functionality of an app. However, I have found that the message is been saved on the backend but does not display on the screen. Any help will be beneficial. I would like to know where I went wrong and see if the chat functionality can function properly. I would like for the sender of the text message to see the message and have the ability to communicate with the receiver of the message seemlessly. Below is the code snippet:
class MessageCenter extends StatefulWidget {
final String garageUid;
final String garageName;
const MessageCenter(
{super.key, required this.garageUid, required this.garageName});
#override
State<MessageCenter> createState() =>
_MessageCenterState(garageName, garageUid);
}
class _MessageCenterState extends State<MessageCenter> {
CollectionReference chats = FirebaseFirestore.instance.collection('chats');
final String garageUid;
final String garageName;
final currentUserId = FirebaseAuth.instance.currentUser!.uid;
var chatDocId;
final _textController = TextEditingController();
_MessageCenterState(this.garageUid, this.garageName);
#override
void initState() {
chats
.where('users', isEqualTo: {garageUid: null, currentUserId: null})
.limit(1)
.get()
.then(
(QuerySnapshot querySnapshot) {
if (querySnapshot.docs.isNotEmpty) {
chatDocId = querySnapshot.docs.single.id;
} else {
chats.add({
'users': {currentUserId: null, garageUid: null}
}).then((value) => {chatDocId = value});
}
},
)
.catchError((error) {});
super.initState();
}
void sendMessage(String msg) {
if (msg == '') return;
chats.doc(chatDocId).collection('messages').add({
'createdOn': FieldValue.serverTimestamp(),
'uid': currentUserId,
'msg': msg
}).then((value) {
_textController.text = '';
});
}
bool isSender(String user) {
return user == currentUserId;
}
Alignment getAlignment(user) {
if (user == currentUserId) {
return Alignment.topRight;
}
return Alignment.topLeft;
}
#override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('chats')
.doc(chatDocId)
.collection('messages')
.orderBy('createdOn', descending: true)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong'),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
var data;
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
previousPageTitle: "back",
middle: Text(garageUid),
trailing: CupertinoButton(
child: const Icon(CupertinoIcons.phone),
onPressed: () {},
),
),
child: SafeArea(
child: Column(
children: [
Expanded(
child: ListView(
reverse: true,
children:
snapshot.data!.docs.map((DocumentSnapshot document) {
data = document.data()!;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: ChatBubble(
clipper: ChatBubbleClipper6(
nipSize: 0,
radius: 0,
type: isSender(data['uid'].toString())
? BubbleType.sendBubble
: BubbleType.receiverBubble,
),
alignment: getAlignment(data['uid'].toString()),
margin: const EdgeInsets.only(top: 20),
backGroundColor: isSender(data['uid'].toString())
? const Color(0xFF08C187)
: const Color(0xffE7E7ED),
child: Container(
constraints: BoxConstraints(
maxWidth:
MediaQuery.of(context).size.width * 0.7,
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
data['msg'],
style: TextStyle(
color:
isSender(data['uid'].toString())
? Colors.white
: Colors.black),
maxLines: 100,
overflow: TextOverflow.ellipsis,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
data['createdOn'] == null
? DateTime.now().toString()
: data['createdOn']
.toDate()
.toString(),
style: TextStyle(
fontSize: 10,
color:
isSender(data['uid'].toString())
? Colors.white
: Colors.black),
),
],
),
],
),
),
),
);
}).toList(),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: CupertinoTextField(
controller: _textController,
)),
CupertinoButton(
child: const Icon(Icons.send_sharp),
onPressed: () => sendMessage(_textController.text))
],
),
],
),
),
);
}
return Container();
},
);
}
}

Control ESP32 via Flutter BLE

I am using this library (https://pub.dev/packages/flutter_blue/example) to control my ESP32 (Arduino). I have two buttons that work perfectly, one to turn off the led and one to turn on the led. My problem is that I want to receive data that the arduino sends (notify). I don’t know how to do it.
main.dart
// Copyright 2017, Paul DeMarco.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:minertti/widgets.dart';
void main() {
runApp(FlutterBlueApp());
}
class FlutterBlueApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.lightBlue,
home: StreamBuilder<BluetoothState>(
stream: FlutterBlue.instance.state,
initialData: BluetoothState.unknown,
builder: (c, snapshot) {
final state = snapshot.data;
if (state == BluetoothState.on) {
return FindDevicesScreen();
}
return BluetoothOffScreen(state: state);
}),
);
}
}
class BluetoothOffScreen extends StatelessWidget {
const BluetoothOffScreen({Key? key, this.state}) : super(key: key);
final BluetoothState? state;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlue,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.bluetooth_disabled,
size: 200.0,
color: Colors.white54,
),
Text(
'Bluetooth Adapter is ${state != null ? state.toString().substring(15) : 'not available'}.',
style: Theme.of(context)
.primaryTextTheme
.subtitle1
?.copyWith(color: Colors.white),
),
],
),
),
);
}
}
class FindDevicesScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Find Devices'),
),
body: RefreshIndicator(
onRefresh: () =>
FlutterBlue.instance.startScan(timeout: Duration(seconds: 4)),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
StreamBuilder<List<BluetoothDevice>>(
stream: Stream.periodic(Duration(seconds: 2))
.asyncMap((_) => FlutterBlue.instance.connectedDevices),
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data!
.map((d) => ListTile(
title: Text(d.name),
subtitle: Text(d.id.toString()),
trailing: StreamBuilder<BluetoothDeviceState>(
stream: d.state,
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
if (snapshot.data ==
BluetoothDeviceState.connected) {
return RaisedButton(
child: Text('OPEN'),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
DeviceScreen(device: d))),
);
}
return Text(snapshot.data.toString());
},
),
))
.toList(),
),
),
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data!
.map(
(r) => ScanResultTile(
result: r,
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
r.device.connect();
return DeviceScreen(device: r.device);
})),
),
)
.toList(),
),
),
],
),
),
),
floatingActionButton: StreamBuilder<bool>(
stream: FlutterBlue.instance.isScanning,
initialData: false,
builder: (c, snapshot) {
if (snapshot.data!) {
return FloatingActionButton(
child: Icon(Icons.stop),
onPressed: () => FlutterBlue.instance.stopScan(),
backgroundColor: Colors.red,
);
} else {
return FloatingActionButton(
child: Icon(Icons.search),
onPressed: () => FlutterBlue.instance
.startScan(timeout: Duration(seconds: 4)));
}
},
),
);
}
}
class DeviceScreen extends StatelessWidget {
const DeviceScreen({Key? key, required this.device}) : super(key: key);
final BluetoothDevice device;
List<Widget> _buildServiceTiles(List<BluetoothService> services) {
return services
//just show the last service
.sublist(services.length - 1)
.map(
(s) => ServiceTile(
service: s,
characteristicTiles: s.characteristics
.map(
(c) => CharacteristicTile(
characteristic: c,
//turnOff: () => c.read(),
turnOff: () => c.write(utf8.encode("0")),
turnOn: () => c.write(utf8.encode("1")),
extraButton: () => c.write(utf8.encode("2")),
onNotificationPressed: () async {
await c.setNotifyValue(!c.isNotifying);
await c.read();
},
descriptorTiles: c.descriptors
.map(
(d) => DescriptorTile(
descriptor: d,
//turnOff: () => d.read(),
//turnOn: () => d.read(),
),
)
.toList(),
),
)
.toList(),
),
)
.toList();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(device.name),
actions: <Widget>[
StreamBuilder<BluetoothDeviceState>(
stream: device.state,
initialData: BluetoothDeviceState.connecting,
builder: (c, snapshot) {
VoidCallback? onPressed;
String text;
switch (snapshot.data) {
case BluetoothDeviceState.connected:
onPressed = () => device.disconnect();
text = 'DISCONNECT';
break;
case BluetoothDeviceState.disconnected:
onPressed = () => device.connect();
text = 'CONNECT';
break;
default:
onPressed = null;
text = snapshot.data.toString().substring(21).toUpperCase();
break;
}
return FlatButton(
onPressed: onPressed,
child: Text(
text,
style: Theme.of(context)
.primaryTextTheme
.button
?.copyWith(color: Colors.white),
));
},
)
],
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
StreamBuilder<BluetoothDeviceState>(
stream: device.state,
initialData: BluetoothDeviceState.connecting,
builder: (c, snapshot) => ListTile(
leading: (snapshot.data == BluetoothDeviceState.connected)
? Icon(Icons.bluetooth_connected)
: Icon(Icons.bluetooth_disabled),
title: Text(
'Device is ${snapshot.data.toString().split('.')[1]}.'),
subtitle: Text('${device.id}'),
trailing: StreamBuilder<bool>(
stream: device.isDiscoveringServices,
initialData: false,
builder: (c, snapshot) => IndexedStack(
index: snapshot.data! ? 1 : 0,
children: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: () => device.discoverServices(),
),
IconButton(
icon: SizedBox(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.grey),
),
width: 18.0,
height: 18.0,
),
onPressed: null,
)
],
),
),
),
),
StreamBuilder<int>(
stream: device.mtu,
initialData: 0,
builder: (c, snapshot) => ListTile(
title: Text('MTU Size'),
subtitle: Text('${snapshot.data} bytes'),
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () => device.requestMtu(223),
),
),
),
StreamBuilder<List<BluetoothService>>(
stream: device.services,
initialData: [],
builder: (c, snapshot) {
return Column(
children: _buildServiceTiles(snapshot.data!),
);
},
),
],
),
),
);
}
}
device.dart
// Copyright 2017, Paul DeMarco.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
class ScanResultTile extends StatelessWidget {
const ScanResultTile({Key? key, required this.result, this.onTap})
: super(key: key);
final ScanResult result;
final VoidCallback? onTap;
Widget _buildTitle(BuildContext context) {
if (result.device.name.length > 0) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
result.device.name,
overflow: TextOverflow.ellipsis,
),
Text(
result.device.id.toString(),
style: Theme.of(context).textTheme.caption,
)
],
);
} else {
return Text(result.device.id.toString());
}
}
Widget _buildAdvRow(BuildContext context, String title, String value) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title, style: Theme.of(context).textTheme.caption),
SizedBox(
width: 12.0,
),
Expanded(
child: Text(
value,
style: Theme.of(context)
.textTheme
.caption
?.apply(color: Colors.black),
softWrap: true,
),
),
],
),
);
}
String getNiceHexArray(List<int> bytes) {
return '[${bytes.map((i) => i.toRadixString(16).padLeft(2, '0')).join(', ')}]'
.toUpperCase();
}
String getNiceManufacturerData(Map<int, List<int>> data) {
if (data.isEmpty) {
return 'N/A';
}
List<String> res = [];
data.forEach((id, bytes) {
res.add(
'${id.toRadixString(16).toUpperCase()}: ${getNiceHexArray(bytes)}');
});
return res.join(', ');
}
String getNiceServiceData(Map<String, List<int>> data) {
if (data.isEmpty) {
return 'N/A';
}
List<String> res = [];
data.forEach((id, bytes) {
res.add('${id.toUpperCase()}: ${getNiceHexArray(bytes)}');
});
return res.join(', ');
}
#override
Widget build(BuildContext context) {
return ExpansionTile(
title: _buildTitle(context),
leading: Text(result.rssi.toString()),
trailing: RaisedButton(
child: Text('CONNECT'),
color: Colors.black,
textColor: Colors.white,
onPressed: (result.advertisementData.connectable) ? onTap : null,
),
children: <Widget>[
_buildAdvRow(
context, 'Complete Local Name', result.advertisementData.localName),
_buildAdvRow(context, 'Tx Power Level',
'${result.advertisementData.txPowerLevel ?? 'N/A'}'),
_buildAdvRow(context, 'Manufacturer Data',
getNiceManufacturerData(result.advertisementData.manufacturerData)),
_buildAdvRow(
context,
'Service UUIDs',
(result.advertisementData.serviceUuids.isNotEmpty)
? result.advertisementData.serviceUuids.join(', ').toUpperCase()
: 'N/A'),
_buildAdvRow(context, 'Service Data',
getNiceServiceData(result.advertisementData.serviceData)),
],
);
}
}
class ServiceTile extends StatelessWidget {
final BluetoothService service;
final List<CharacteristicTile> characteristicTiles;
const ServiceTile(
{Key? key, required this.service, required this.characteristicTiles})
: super(key: key);
#override
Widget build(BuildContext context) {
if (characteristicTiles.length > 0) {
return ExpansionTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Service'),
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
],
),
children: characteristicTiles,
);
} else {
return ListTile(
title: Text('Service'),
subtitle:
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}'),
);
}
}
}
class CharacteristicTile extends StatelessWidget {
final BluetoothCharacteristic characteristic;
final List<DescriptorTile> descriptorTiles;
final VoidCallback? turnOff;
final VoidCallback? extraButton;
final VoidCallback? turnOn;
final VoidCallback? onNotificationPressed;
const CharacteristicTile(
{Key? key,
required this.characteristic,
required this.descriptorTiles,
this.turnOff,
this.extraButton,
this.turnOn,
this.onNotificationPressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder<List<int>>(
stream: characteristic.value,
initialData: characteristic.lastValue,
builder: (c, snapshot) {
final value = snapshot.data;
return ExpansionTile(
title: ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Characteristic'),
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
],
),
subtitle: Text(value.toString()),
contentPadding: EdgeInsets.all(0.0),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.lightbulb_outline,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: turnOff,
),
IconButton(
icon: Icon(Icons.lightbulb,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5)),
onPressed: turnOn,
),
//iconButton for add
IconButton(
icon: Icon(
Icons.add_circle,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: extraButton,
),
IconButton(
icon: Icon(
characteristic.isNotifying
? Icons.sync_disabled
: Icons.sync,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5)),
onPressed: onNotificationPressed,
)
],
),
children: descriptorTiles,
);
},
);
}
}
class DescriptorTile extends StatelessWidget {
final BluetoothDescriptor descriptor;
final VoidCallback? turnOff;
final VoidCallback? turnOn;
final VoidCallback? extraButton;
const DescriptorTile(
{Key? key,
required this.descriptor,
this.turnOff,
this.extraButton,
this.turnOn})
: super(key: key);
#override
Widget build(BuildContext context) {
return ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Descriptor'),
Text('0x${descriptor.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.bodyText1
?.copyWith(color: Theme.of(context).textTheme.caption?.color))
],
),
subtitle: StreamBuilder<List<int>>(
stream: descriptor.value,
initialData: descriptor.lastValue,
builder: (c, snapshot) => Text(snapshot.data.toString()),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.lightbulb_outline,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: turnOff,
),
IconButton(
icon: Icon(
Icons.lightbulb,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: turnOn,
),
IconButton(
icon: Icon(
Icons.add_circle,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: extraButton,
)
],
),
);
}
}
class AdapterStateTile extends StatelessWidget {
const AdapterStateTile({Key? key, required this.state}) : super(key: key);
final BluetoothState state;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.redAccent,
child: ListTile(
title: Text(
'Bluetooth adapter is ${state.toString().substring(15)}',
style: Theme.of(context).primaryTextTheme.subtitle1,
),
trailing: Icon(
Icons.error,
color: Theme.of(context).primaryTextTheme.subtitle1?.color,
),
),
);
}
}
ESP32 Code:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
float txValue = 0;
const int readPin = 32; // Use GPIO number. See ESP32 board pinouts
const int LED = 2; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.
//std::string rxValue; // Could also make this a global var to access it in loop()
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}
Serial.println();
// Do stuff based on the command received from the app
if (rxValue.find("1") != -1) {
Serial.println("Turning ON!");
digitalWrite(LED, HIGH);
}
else if (rxValue.find("0") != -1) {
Serial.println("Turning OFF!");
digitalWrite(LED, LOW);
}
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
// Create the BLE Device
BLEDevice::init("ESP32"); // Give it a name
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
if (deviceConnected) {
// Fabricate some arbitrary junk for now...
txValue = analogRead(readPin) / 3.456; // This could be an actual sensor reading!
// Let's convert the value to a char array:
char txString[8]; // make sure this is big enuffz
dtostrf(txValue, 1, 2, txString); // float_val, min_width, digits_after_decimal, char_buffer
// pCharacteristic->setValue(&txValue, 1); // To send the integer value
// pCharacteristic->setValue("Hello!"); // Sending a test message
pCharacteristic->setValue(txString);
pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txString);
Serial.println(" ***");
// You can add the rxValue checks down here instead
// if you set "rxValue" as a global var at the top!
// Note you will have to delete "std::string" declaration
// of "rxValue" in the callback function.
// if (rxValue.find("A") != -1) {
// Serial.println("Turning ON!");
// digitalWrite(LED, HIGH);
// }
// else if (rxValue.find("B") != -1) {
// Serial.println("Turning OFF!");
// digitalWrite(LED, LOW);
// }
}
delay(1000);
}
The app correctly receives the information, but in a strange code that I don't understand. How do I convert it to letters and numbers?
In device.dart you can see that there is a part that says: "subtitle: Text(value.toString())"
That is the one that sends the data, but I don't understand it.
...
builder: (c, snapshot) {
final value = snapshot.data;
return ExpansionTile(
title: ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Characteristic'),
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
],
),
subtitle: Text(value.toString()),
...
Arduino sends: 98.96 and I receive this data from value.toString(): [57, 56, 46, 57, 54]
Try using String.fromCharCodes to convert the received data ([57, 56, 46, 57, 54]) to 98.96.
Refer to this utf8 char table: https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/02572bcf-76c4-420a-90ac-65a0c8c71eae/iso-8859-5-php-orange.png
You are receiving Uint8List. Decode that data into string then parse it in double.
Try this:
String decodedData = utf8.decode(receivedData);
where receivedData -> Uint8List
Now in decodedData you will get the required string that you can parse into other data types.

display alert when data is changed using flutter?

My screen look like thisI have trying to display alert when snapshot.data value has been changed.i try the if else condition
import 'dart:async';
import 'dart:convert';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import'package:flutter_custom_clippers/flutter_custom_clippers.dart';
import 'package:tv_dashboard/pages/test.dart';
//import 'package:assets_audio_player/assets_audio_player.dart';
class DashBoard extends StatefulWidget {
#override
_DashBoardState createState() => _DashBoardState();
}
var now = new DateTime.now();
String g = ('${now.day}-${now.month}-${now.year}');
AnimationController _controller;
Animation<double> _animation;
class _DashBoardState extends State<DashBoard> with TickerProviderStateMixin {
Timer timer;
int counter = 0;
Test data = Test();
Future<List<dynamic>> fetchUsers() async {
String url = 'http://us.rdigs.com/jsonData.php';
var result = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
if (result.statusCode == 200) {
//print(result.body);
//playSound();
return json.decode(result.body);
} else {
// If the server not return a 200 OK ,
// then throw the exception.
throw Exception('Failed');
}
}
playSound() async {
AssetsAudioPlayer audioPlayer = AssetsAudioPlayer();
audioPlayer.open(Audio('assets/Ring.mp3'));
}
String name(dynamic name) {
return name['name'];
}
String leads(dynamic leads) {
return leads['leads'];
}
#override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 5), (Timer t) => addValue());
}
void addValue() {
setState(() {
//playSound();
counter++;
});
}
void alertBox() async {
await fetchUsers();
Container(
padding: EdgeInsets.only(left: 300),
child: AlertDialog(
title: Text('Alert Data'),
),
); //Use the response in the dialog
}
var totalLeads = 0;
var countLead = 0;
var allLeads;
#override
Widget build(BuildContext context) {
alertBox();
//playSound();
return Scaffold(
// backgroundColor: Color.fromRGBO(198, 159, 169, 1),
body: Column(
children: [
ClipPath(
clipper: OvalBottomBorderClipper(),
child: Container(
padding: EdgeInsets.only(top: 5),
height: 70,
color: Colors.cyan[100],
child: Center(
child: Column(
children: [
Text(
"Total Leads",
style: new TextStyle(fontSize: 28.0, fontFamily: 'Michroma'),
),
Text(
totalLeads.toString(),
style: new TextStyle(
fontSize: 25.0,
),
)
],
)),
),
),
Expanded(
child: FutureBuilder<List<dynamic>>(
future: fetchUsers(),
builder: (context, snapshot) {
if (snapshot.hasData) {
//total leads
//alertBox();
totalLeads = snapshot.data
.map<int>((m) => int.parse(m["leads"]))
.reduce((a, b) => a + b);
return GridView.builder(
itemCount: snapshot.data.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 6,
childAspectRatio:
MediaQuery.of(context).size.height / 350,
),
padding: EdgeInsets.all(8),
itemBuilder: (BuildContext context, int index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
bottomRight: Radius.circular(20)),
side: BorderSide(color: Colors.black)),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Text(
name(snapshot.data[index]),
style: new TextStyle(
fontSize: 25.0,
),
),
Container(
padding: EdgeInsets.only(top: 12),
child: Text(
leads(snapshot.data[index])
.toString(),
style: new TextStyle(
fontSize: 26.0,
color: Colors.blue),
))
],
)),
],
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return Center(child: CircularProgressIndicator());
}
}))
],
));
}
}
totalLeads is count of my all int value
sum is temp variable
my problem is when data is changed in json string then display the alert box in flutter
When data changed in string, you can show AlertDialog widget:
Future<void> showErrorDialog() async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Error'),
content: SingleChildScrollView(
child: Text(
'Error message',
),
),
actions: <Widget>[
TextButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop(),
),
],
);
},
);
}

Flutter variable keeps getting initialized after switching to the class

I am trying to apply filters in firebase and am doing so by using startswith filters in the results.I have initialized the variables which act as a filter outside of all the classes
int duration = 1440;
String destination = '';
String Company = '';
int Maxcost = 99999999999;
int MinCost = 0;
String cla = '';
String airport = '';
This means that all files will be allowed to come. But when I change the variables from another class like this.
FILTER CLASS
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => Home(email:email,destination:destination,duration:duration,Maxcost: maxCost,Mincost: minCost,airport: airport,Company: company,)));
RECIEVING CLASS(Stateful Widget)
Home({this.email,duration = 1440,destination ='',Company = '',Maxcost = 99999999,Mincost = 0,cla = '',airport = ''});
I have added "=" as there are other classes which lead to this but they don't give these values. This makes it so that when those classes don't pass these values, it becomes the default values instead of null. Now where the problem occurs
StreamBuilder(
stream: Firestore.instance.collection("Planes").where(
"cost", isLessThan: Maxcost).where(
"cost", isGreaterThan: MinCost).snapshots(),
builder: (context, snapshot) {
List<DocumentSnapshot> m = snapshot.data.documents;
List<DocumentSnapshot> l=[];
DocumentSnapshot i;
for (i in m) {
if (i[' destination'].startsWith(destination) && i['duration']<(duration) && i['airport'].startsWith(airport) && i['class'].startsWith(cla) && i['company'].startsWith(Company)) {
l.add(i);
}
}
return ListView.builder(
itemCount: l.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 1.0, horizontal: 4.0),
child: Card(
child: ListTile(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ViewPlane(plane: snapshot,
index: index,
email: email,)));
},
leading: Icon(Icons.airplanemode_active),
title: Text(l[index][' destination']),
subtitle: Text(
l[index]['airport']),
),
),
);
},
);
}
),
Before this happens(It is one of the first things done), the variable is set to the default values. How come? The variables are not initialized in the build function. Here is the entire code for the main class if needed.
MAIN CLASS
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:discount_app/AddSheets/AddPlane.dart';
import 'package:discount_app/FilterPage/PlaneFilter.dart';
import 'package:discount_app/Headings/home_screen_plane_packages.dart';
import 'package:discount_app/chat_pack/Loading.dart';
import 'package:discount_app/chat_pack/Settings.dart';
import 'package:discount_app/chat_pack/chat_home_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:discount_app/ViewSheets/ViewPlane.dart';
import 'package:discount_app/login_signup/Login.dart';
import 'package:discount_app/chat_pack/Const.dart';
import 'package:google_sign_in/google_sign_in.dart';
List<Choice> choices = const <Choice>[
const Choice(title:"Filters",icon:Icons.filter),
const Choice(title: 'Settings', icon: Icons.settings),
const Choice(title: 'Log out', icon: Icons.exit_to_app),
];
int duration = 1440;
String destination = '';
String Company = '';
int Maxcost = 99999999999;
int MinCost = 0;
String cla = '';
String airport = '';
#override
class Home extends StatefulWidget {
String email;
Home({this.email,duration = 1440,destination ='',Company = '',Maxcost = 99999999,Mincost = 0,cla = '',airport = ''});
#override
_HomeState createState() => _HomeState(email:email);
}
class _HomeState extends State<Home> {
var s;
void onItemMenuPress(Choice choice,) {
if (choice.title == 'Log out') {
handleSignOut();
}
else if (choice.title == 'Filters') {
Navigator.push(
context, MaterialPageRoute(builder: (context) => planeFilter(email:email)));
}
else {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Settings()));
}
}
final GoogleSignIn googleSignIn = GoogleSignIn();
bool isLoading = false;
Future<Null> openDialog() async {
switch (await showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
contentPadding: EdgeInsets.only(
left: 0.0, right: 0.0, top: 0.0, bottom: 0.0),
children: <Widget>[
Container(
color: themeColor,
margin: EdgeInsets.all(0.0),
padding: EdgeInsets.only(bottom: 10.0, top: 10.0),
height: 100.0,
child: Column(
children: <Widget>[
Container(
child: Icon(
Icons.exit_to_app,
size: 30.0,
color: Colors.white,
),
margin: EdgeInsets.only(bottom: 10.0),
),
Text(
'Exit app',
style: TextStyle(color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold),
),
Text(
'Are you sure to exit app?',
style: TextStyle(color: Colors.white70, fontSize: 14.0),
),
],
),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, 0);
},
child: Row(
children: <Widget>[
Container(
child: Icon(
Icons.cancel,
color: primaryColor,
),
margin: EdgeInsets.only(right: 10.0),
),
Text(
'CANCEL',
style: TextStyle(
color: primaryColor, fontWeight: FontWeight.bold),
)
],
),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, 1);
},
child: Row(
children: <Widget>[
Container(
child: Icon(
Icons.check_circle,
color: primaryColor,
),
margin: EdgeInsets.only(right: 10.0),
),
Text(
'YES',
style: TextStyle(
color: primaryColor, fontWeight: FontWeight.bold),
)
],
),
),
],
);
})) {
case 0:
break;
case 1:
exit(0);
break;
}
}
Future<Null> handleSignOut() async {
this.setState(() {
isLoading = true;
});
await FirebaseAuth.instance.signOut();
await googleSignIn.disconnect();
await googleSignIn.signOut();
this.setState(() {
isLoading = false;
});
Navigator.of(context)
.pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => LoginScreen()), (
Route<dynamic> route) => false);
}
String email;
_HomeState({this.email});
#override
Widget build(BuildContext context) {
return GestureDetector(
onPanUpdate: (details) {
if (details.delta.dx > 0) {
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => PlanePackages(email: email,)));
}
},
child: new Scaffold(
backgroundColor: Colors.pink[800],
appBar: new AppBar(
title: new Text('Home page'),
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 20.0),
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
HomeScreen(currentUserId: email,)));
},
child: Icon(Icons.chat),
)),
PopupMenuButton<Choice>(
onSelected: onItemMenuPress,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Row(
children: <Widget>[
Icon(
choice.icon,
color: primaryColor,
),
Container(
width: 10.0,
),
Text(
choice.title,
style: TextStyle(color: primaryColor),
),
],
));
}).toList();
},
),
],
),
body: WillPopScope(
child: Stack(
children: <Widget>[ StreamBuilder(
stream: Firestore.instance.collection("Planes").where(
"cost", isLessThan: Maxcost).where(
"cost", isGreaterThan: MinCost).snapshots(),
builder: (context, snapshot) {
List<DocumentSnapshot> m = snapshot.data.documents;
List<DocumentSnapshot> l=[];
DocumentSnapshot i;
for (i in m) {
if (i[' destination'].startsWith(destination) && i['duration']<(duration) && i['airport'].startsWith(airport) && i['class'].startsWith(cla) && i['company'].startsWith(Company)) {
l.add(i);
}
}
return ListView.builder(
itemCount: l.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 1.0, horizontal: 4.0),
child: Card(
child: ListTile(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ViewPlane(plane: snapshot,
index: index,
email: email,)));
},
leading: Icon(Icons.airplanemode_active),
title: Text(l[index][' destination']),
subtitle: Text(
l[index]['airport']),
),
),
);
},
);
}
),
Positioned(
child: isLoading ? const Loading() : Container(),
)
]
),
onWillPop: () async {
openDialog();
return Future.value(false);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print(cla);
Navigator.push(context, MaterialPageRoute(
builder: (context) => AddPlane(email: email,)));
},
backgroundColor: Colors.green,
child: Icon(
Icons.add,
size: 30,
),
),
),
);
}
}
Any help will be appreciated
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => Home(email:email,destationName:destination,durationValue:duration,maximumCost: maxCost,minimumCost: minCost,airportName: airport,CompanyName: company,)));
assign it this way, since they're global variables you can't assign directly in the constructor parameters
Home({this.email,durationValue = 1440,destinationName ='',companyName = '',maximumCost = 99999999,minimumCost = 0,claValue = '',airportName = ''})
{
duration=durationValue;
destination=destinationName;
Maxcost = maximumCost;
Mincost = minimmCost;
cla=claValue;
airport=airportName;
Company = companyName;
}