Calling multiple functions in FutureBuilder causes an error - android

I am retrieving data from Firestore in the form of two functions (_onpressed() and _drname()) and called both of them in FutureBuilder.
Function 1 is
Future _onPressed() async {
if (widget.brew.id == currentid.userid()) {
return await db
.collection('Messages')
.doc(widget.brew.id)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('${documentSnapshot.data()['Message']}');
String msg = json.encode(documentSnapshot.data()['Message']);
return msg;
} else {
print('Document does not exist on the database');
}
// var a= documentSnapshot.data()['Message'];
});
} else {
return 'No Prescription from doctor yet';
}}
Function 2 is
Future _drname() async {
if (widget.brew.id == currentid.userid()) {
return await db
.collection('Drname')
.doc(widget.brew.id)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('${documentSnapshot.data()['name']}');
String msg = json.encode(documentSnapshot.data()['name']);
return msg;
} else {
print('Document does not exist on the database');
}
// var a= documentSnapshot.data()['Message'];
});
} else {
return 'No';
}}
Calling these functions in FutureBuilder like this
Widget _messagePannel() {
return FutureBuilder(
future: Future.wait([_onPressed(),_drname()]),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
return Scaffold(
appBar: AppBar(
actions: [
Padding(
padding: const EdgeInsets.only(right: 17.0),
child: TextButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Call()),
);
},
icon: Icon(
Icons.video_call,
color: Colors.white,
size: 30.0,
),
label: Text(''),
),
)
],
title: Text(
'Prescrption',
style: TextStyle(fontFamily: 'RussoOne', fontSize: 22.0),
),
backgroundColor: Colors.green[900],
elevation: 0.0,
centerTitle: true,
),
body: Container(
decoration: image,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
color: Colors.black,
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(0.0, 4.0, 4.0, 4.0),
child: Wrap(
children: [
Center(
child: Text(
'${snapshot.data[0]} ',
textAlign: TextAlign.left,
style: TextStyle(
fontFamily: 'RussoOne',
color: Colors.white,
letterSpacing: 0.8,
fontSize: 18.0,
backgroundColor: Colors.black),
),
),
Center(
child: Text(
'${snapshot.data[1]} ',
textAlign: TextAlign.left,
style: TextStyle(
fontFamily: 'RussoOne',
color: Colors.white,
letterSpacing: 0.8,
fontSize: 18.0,
backgroundColor: Colors.black),
),
),
],
),
)),
),
),
),
],
),
),
),
);
});}
Getting This error from the Debug Console
The following NoSuchMethodError was thrown building FutureBuilder<List>(dirty, state: _FutureBuilderState<List>#44f46):
The method '[]' was called on null.
Receiver: null
Tried calling:

When using snapshot, the initial value for the data property is null (since Future has no result until you receive the response), so using it straight away as you do it in the code (e.g. snapshot.data[1]) should be avoided.
To cope with that, first of all you should check if the data is not null. For that, snapshot has a dedicated method snapshot.hasData, for instance:
return FutureBuilder(
future: Future.wait([_onPressed(),_drname()]),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator(); // E.g. Show loader if there is no data yet
}
return Scaffold(...); // Return the widget you have now
},
);

Related

_Cast Error : Null check operator used on a null value [duplicate]

This question already has answers here:
Null check operator used on a null value
(12 answers)
Closed last year.
I am new to programming and don't know how to solve this issue.
I am using the java version of 8 and using Android Studio to make apps with Flutter.
I have been making a to-do list app, and a cast error happens when
I make a new list
I update a list
I delete a list
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter ToDo List',
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: "NanumSquare",
primaryColor: Color(0xFF424874), //primary color
),
home: HomeScreen()
);
}
}
this is the main.dart
the error appears on the Home Screen.
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late Future<List<Note>> _noteList;
final DateFormat _dateFormatter = DateFormat("MMM dd, yyyy");
DatabaseHelper _databaseHelper = DatabaseHelper.instance;
void initState() {
super.initState();
_updateNoteList();
}
_updateNoteList() {
_noteList = DatabaseHelper.instance.getNoteList();
}
Widget _buildNote(Note note) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 25),
child: Column(
children: [
Container(
margin: EdgeInsets.all(5),
color: Color(0xFFDCD6F7),
child: ListTile(
title: Text(
note.title!,
style: TextStyle(
fontSize: 20,
color: Color(0xFF424874),
decoration: note.status == 0
? TextDecoration.none
: TextDecoration.lineThrough),
),
subtitle: Text(
"${_dateFormatter.format(note.date!)}-${note.priority}",
style: TextStyle(
fontSize: 15,
color: Color(0xFF424874),
decoration: note.status == 0
? TextDecoration.none
: TextDecoration.lineThrough),
),
trailing: Checkbox(
onChanged: (value) {
note.status = value! ? 1 : 0;
DatabaseHelper.instance.updateNote(note);
_updateNoteList();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => HomeScreen())
);
},
activeColor: Color(0xFFA6B1E1),
value: note.status == 1 ? true : false,
),
onTap: () => Navigator.push(
context,
CupertinoPageRoute(
builder: (_) => AddNoteScreen(
updateNoteList: _updateNoteList(),
note: note
)
),
),
),
),
Divider(
height: 5,
color: Color(0xFFA6B1E1),
thickness: 2,
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF4EEFF),
floatingActionButton: FloatingActionButton(
backgroundColor: Color(0xFF424874),
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (_) => AddNoteScreen(
updateNoteList: _updateNoteList(),
),
));
},
child: Icon(Icons.add),
),
body: FutureBuilder(
future: _noteList,
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
final int completedNoteCount = snapshot.data!.where((Note note) => note.status == 1).toList().length;
return ListView.builder(
padding: EdgeInsets.symmetric(vertical: 80),
itemCount: int.parse(snapshot.data!.length.toString()) + 1,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Padding(
padding:
EdgeInsets.symmetric(horizontal: 40, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"My Notes",
style: TextStyle(
color: Color(0xFF424874),
fontSize: 40,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"$completedNoteCount of ${snapshot.data.length}",
style: TextStyle(
color: Color(0xFFA6B1E1),
fontSize: 20,
fontWeight: FontWeight.w600),
),
],
),
);
}
return _buildNote(snapshot.data![index-1]);
});
}));
}
}
The error message is as below.
======== Exception caught by gesture ===============================================================
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value
When the exception was thrown, this was the stack:
#0 _AddNoteScreenState._delete (package:crud_sqlite_app/screens/add_note_screen.dart:80:26)
#1 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
#2 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#3 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:607:11)
#4 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#e7613
debugOwner: GestureDetector
state: ready
won arena
finalPosition: Offset(150.8, 655.2)
finalLocalPosition: Offset(110.8, 46.2)
button: 1
sent tap down
====================================================================================================
and this is the add_note_screen.dart
class AddNoteScreen extends StatefulWidget {
final Note? note;
final Function? updateNoteList;
AddNoteScreen({this.note, this.updateNoteList});
#override
_AddNoteScreenState createState() => _AddNoteScreenState();
}
class _AddNoteScreenState extends State<AddNoteScreen> {
final _formKey = GlobalKey<FormState>();
String _title = "";
String _priority = "Low";
String btnText = "Add Note";
String titleText = "Add Note";
DateTime _date = DateTime.now();
TextEditingController _dateController = TextEditingController();
final DateFormat _dateFormatter = DateFormat("MMM dd, yyyy");
final List<String> _priorities = ["Low", "Medium", "High"];
#override
void initState(){
super.initState();
if(widget.note != null) {
_title = widget.note!.title!;
_date = widget.note!.date!;
_priority = widget.note!.priority!;
setState(() {
btnText = "Update Note";
titleText = "Update Note";
});
}
else {
setState(() {
btnText = "Add Note";
titleText = "Add Note";
});
}
_dateController.text = _dateFormatter.format(_date);
}
#override
void dispose() {
_dateController.dispose();
super.dispose();
}
_handleDatePicker() async {
final DateTime? date = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime(2000),
lastDate: DateTime(2100));
if (date != null && date != _date) {
setState(() {
_date = date;
});
_dateController.text = _dateFormatter.format(date);
}
}
_delete() {
DatabaseHelper.instance.deleteNote(widget.note!.id!);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_)=> HomeScreen()
)
);
widget.updateNoteList!();
}
_submit() {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print("$_title, $_date, $_priority");
Note note = Note(
title: _title,
date: _date,
priority: _priority
);
if (widget.note == null){
note.status = 0;
DatabaseHelper.instance.insertNote(note);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=> HomeScreen())
);
}
else{
note.id = widget.note!.id;
note.status = widget.note!.status;
DatabaseHelper.instance.updateNote(note);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=> HomeScreen())
);
}
widget.updateNoteList!();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF4EEFF),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 80),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: () => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => HomeScreen(),
)
),
child: Icon(
Icons.arrow_back,
size: 30,
color: Color(0xFFA6B1E1),
),
),
SizedBox(
height: 20.0,
),
Text(
titleText,
style: TextStyle(
color: Color(0xFF424874),
fontSize: 40,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: TextFormField(
style: TextStyle(fontSize: 18),
decoration: InputDecoration(
labelText: "Title",
labelStyle: TextStyle(fontSize: 18),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
validator: (input) => input!.trim().isEmpty
? "Please enter a note title"
: null,
onSaved: (input) => _title = input!,
initialValue: _title,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: TextFormField(
readOnly: true, //hide keyboard
controller: _dateController,
style: TextStyle(fontSize: 18),
onTap: _handleDatePicker,
decoration: InputDecoration(
labelText: "Date",
labelStyle: TextStyle(fontSize: 18),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: DropdownButtonFormField(
isDense: true,
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22,
iconEnabledColor: Color(0xFF424874),
items: _priorities.map((String priority) {
return DropdownMenuItem(
value: priority,
child: Text(
priority,
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
));
}).toList(),
style: TextStyle(fontSize: 18),
decoration: InputDecoration(
labelText: "Priority",
labelStyle: TextStyle(fontSize: 18),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
)
),
// validator: (input) => _priority == null ? "Please",
onChanged: (value) {
setState(() {
_priority = value.toString();
});
},
value: _priority,
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 20),
height: 60.0,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30)),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor)
),
child: Text(
btnText,
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: _submit,
),
),
widget.note != null ? Container(
margin: EdgeInsets.symmetric(vertical: 20),
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF424874),
borderRadius: BorderRadius.circular(30)
),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor)
),
child: Text("Delete Note",
style: TextStyle(
color: Colors.white,
fontSize: 20
),
),
onPressed: _delete,
),
): SizedBox.shrink()
],
),
)
],
),
),
),
),
);
}
}
I am sorry the code is too long.
If you can help me, I will really appreciate it.
Thank you!
This error occurs when you use a bang operator (!) on a nullable instance which wasn't initialized. This operator should only be used when you are sure that the variable cannot be null, I don't recommend using it. Check out this answer

Show value from BLE device to Heart Widget in flutter App

I want to show my readings that are coming from Esp32 to my Heart Widget that is displayed on HomeScreen.
I used the example code of flutter_blue package to check whether readings are coming to the app, but I am having difficulty understanding the code as I am new to Flutter.
My Bluetooth Connection Screen looks like this, which shows the list of nearby BLE devices
When I press Connect Button it goes to this screen showing the services, descriptors, and MTU size.
As clearly seen in the picture that the last service is getting values from ESP32, I want to show the values under Characteristic to show in Heart Rate Widget, where 96 is written. But I can't understand how I should display the value of the characteristic on this screen and not on the above screen.
These are the values that I am getting on the console as well, which are correct. I just want that when I press the connect button of ESP32, it should connect instantly and instead of going to 2nd screen it should go to the home screen and show values inside the heart rate widget
My code for Bluetooth Scanning Devices Screen is:
// 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:math';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'BluetoothConnectBand.dart';
import 'widgets.dart';
class FlutterBlueApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
//backgroundColor:Colors.lightBlue ,
body: 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,
appBar:AppBar(
backgroundColor: Colors.lightBlue,
elevation: 0,
leading:IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return BluetoothConnectBand();
},
),
);
},
),
),
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
.subhead
?.copyWith(color: Colors.white),
),
],
),
),
);
}
}
class FindDevicesScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xffE5E0A1),
elevation: 0,
centerTitle: true,
title: Text(
"Connect Band",
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
fontFamily: 'Montserrat',
fontWeight: FontWeight.normal,
),
),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return BluetoothConnectBand();
},
),
);
},
),
),
body: RefreshIndicator(
onRefresh: () =>
FlutterBlue.instance.startScan(timeout: Duration(seconds: 4)),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: size.height * 0.4,
width: size.width,
color: const Color(0xffE5E0A1),
child: Image.asset(
'assets/images/bluetooth.png',
)),
Container(
width: size.width,
padding: EdgeInsets.symmetric(vertical: 20),
child: Text(
"Scanning Available Devices...",
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Montserrat',
),
textAlign: TextAlign.center,
),
),
//Expanded(child:_buildListViewOfDevices()),
],
),
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,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.w600,
fontFamily: 'Montserrat',
),
),
subtitle: Text(d.id.toString(),
style: TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: 'Montserrat',
),
),
trailing: StreamBuilder<BluetoothDeviceState>(
stream: d.state,
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
if (snapshot.data ==
BluetoothDeviceState.connected) {
return FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28.0),
),
child: Text('Connected'),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
DeviceScreen(device: d))),
);
}
return Text(snapshot.data.toString(),
style: TextStyle(
color: Colors.green,
),);
},
),
))
.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)),
backgroundColor: const Color(0xffE5E0A1),);
}
},
),
);
}
}
class DeviceScreen extends StatelessWidget {
const DeviceScreen({Key key, this.device}) : super(key: key);
final BluetoothDevice device;
List<int> _getRandomBytes() {
final math = Random();
return [
math.nextInt(255),
math.nextInt(255),
math.nextInt(255),
math.nextInt(255)
];
}
List<Widget> _buildServiceTiles(List<BluetoothService> services) {
return services
.map(
(s) => ServiceTile(
service: s,
characteristicTiles: s.characteristics
.map(
(c) => CharacteristicTile(
characteristic: c,
onReadPressed: () => c.read(),
onWritePressed: () async {
await c.write(_getRandomBytes(), withoutResponse: true);
await c.read();
},
onNotificationPressed: () async {
await c.setNotifyValue(!c.isNotifying);
await c.read();
},
descriptorTiles: c.descriptors
.map(
(d) => DescriptorTile(
descriptor: d,
onReadPressed: () => d.read(),
onWritePressed: () => d.write(_getRandomBytes()),
),
)
.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),
);
},
),
],
),
),
);
}
}
Code for Widgets is the same as written in the code example, I have only changed main file for my UI.
Code for Heart Rate Widget:
Center(
child: Container(
height: size.height * 0.190,
width: size.width * 0.80,
padding: EdgeInsets.all(11.0),
child: Card(
color: const Color(0xffe8e5af),
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 25),
alignment: Alignment.centerLeft,
child: const SpinKitPumpingHeart(
color: Colors.white,
)
//Image.asset(
// 'assets/images/heart_button.png',
// ),
),
Container(
padding: EdgeInsets.symmetric(vertical: 20),
alignment: Alignment.center,
width: size.width * 0.80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'96',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 19,
color: const Color(0xffffffff),
fontWeight: FontWeight.w500,
height: 1.4736842105263157,
),
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent: false),
textAlign: TextAlign.left,
),
SizedBox(
height: 5,
),
Text(
'Heart Rate',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 19,
color: Colors.white.withOpacity(0.7),
fontWeight: FontWeight.w500,
height: 1.2777777777777777,
),
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent: false),
textAlign: TextAlign.left,
),
],
),
)
],
),
),
),
)
One way to solve it is to use a Provider.
With one class
import 'package:flutter_blue/flutter_blue.dart';
class BlueDevice extends ChangeNotifier {
/// Internal, private state of the Device.
BluetoothDevice _device;
BluetoothService _service;
/// Device metrics
int heartRate;
...
/// Adds device to model. This is the only way to modify the device from outside.
void add(BluetoothDevice d) async {
_device = d;
await _device.connect();
_device.discoverServices();
_device.services.listen((lista) {
for (int iService = 0; iService < lista.length; iService++) {
if (lista[iService].uuid.toString().startsWith("YOUR UUID")) {
_service = lista[iService];
}
}
});
// This line tells [Model] that it should rebuild the widgets that
// depend on it.
notifyListeners();
}
void read() async {
List<List> values = [];
if (_service != null) {
for (BluetoothCharacteristic c in _service.characteristics) {
values.add(await c.read());
}
}
heartRate = values[0][0];
notifyListeners();
}
}
need to create the provider
class FlutterBlueApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
// In this app, BlueDevice is implemented as a ChangeNotifier,
// which calls for the use of ChangeNotifierProvider.
create: (context) => BlueDevice(),
child: Scaffold(...
and you may use it with a consumer
Consumer<BlueDevice>(
builder: (context, blue, child) => Text(blue.heartRate.toString(),
//'96', THIS WAS THE VALUE
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 19,
color: const Color(0xffffffff),
fontWeight: FontWeight.w500,
height: 1.4736842105263157,
),

Flutter - put variable value outside a function

i'm trying to show the data i retrieve on a function outside of it (to show in a listview of products) but i cant do it because i cant access the variable.
First I open a dialog where i put the order number, when i click a button on this dialog it runs the following code:
(this function is inside a onPressed).
Future loadProdutos() async{
ProdutosList produtosList =
ProdutosList.fromJson(response.data);
print(produtosList.produtos[1].qtd);
print(produtosList.produtos.length);
}
setState(() {
loadProdutos();
Navigator.pop(context, true);
});
So the data its stored on produtoslist, but when I try to use the produtosList length on the listview (for example) like the example below it cant access the data.
Here
child: ListView.builder(
itemCount: produtosList.produtos.length, <<< //Undefined name 'produtosList'.
Try correcting the name to one that is defined, or defining the name.dart(undefined_identifi
How can I make produtosList accessable from the whole file?
Or to create it outside of the function and use it inside (when i try i cant access the variable inside of the function, maybe because its async).
Heres the full code
class OS extends StatefulWidget {
#override
_OSState createState() => _OSState();
}
class _OSState extends State<OS> {
static _read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'operador';
final value = prefs.getString(key);
print('saved tester $value');
String operadorLogado = value;
return operadorLogado;
}
#override
final _numeroOsController = TextEditingController();
void initState() {
super.initState();
_read();
var produtosList1 = <ProdutoOs>[];
//WidgetsBinding.instance.addPostFrameCallback((_) => _read());
// final prefs = await SharedPreferences.getInstance();
// final key = 'usuario';
// final value = prefs.getString(key);
// print('saved $value');
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OS Nº xxx"),
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 20.0),
child: GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
scrollable: true,
title: Text('BUSCAR OS'),
content: Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
child: TextFormField(
controller: _numeroOsController,
decoration: InputDecoration(
icon: Icon(Icons.search),
),
),
),
),
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.blue,
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32.0),
),
),
child: Text("IR"),
onPressed: () async {
Response response;
Dio dio = new Dio();
String url =
'http://192.168.15.2:8090/api/getOs';
response = await dio.post(url, data: {
"numeroos": _numeroOsController.text
});
print(response.statusCode);
jsonDecode(response);
Future loadProdutos() async {
ProdutosList produtosList =
ProdutosList.fromJson(response.data);
print(produtosList.produtos[1].qtd);
print(produtosList.produtos.length);
}
setState(() {
loadProdutos();
Navigator.pop(context, true);
});
},
)
]);
});
},
child: Icon(
Icons.search,
size: 26.0,
),
)),
],
),
body: Column(
children: [
Container(
color: Colors.blue,
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
children: [
Expanded(
flex: 8,
child: Text(
"CLIENTE:",
style: TextStyle(color: Colors.white),
),
),
Expanded(
flex: 8,
child: Text(
"STATUS:",
style: TextStyle(color: Colors.white),
),
),
],
),
),
),
Container(
color: Colors.blue,
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 8.0, 0, 8.0),
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Text("CÓDIGO",
style: TextStyle(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis),
),
Expanded(
flex: 1,
child: Text(
"QTD",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
flex: 3,
child: Text(
"FUNCIONÁRIO",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
flex: 4,
child: Text(
"DESCRIÇÃO",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
],
),
),
),
Divider(
height: 5.0,
),
Expanded(
child: ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 4.0, 0.0, 4.0),
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Text(
"12345",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
flex: 1,
child: Text(
"12",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
flex: 3,
child: Text("example",
style: TextStyle(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis
),
),
Expanded(
flex: 4,
child: Text(
"DESCRIÇÃO DA PEÇA XXXXXX11111111 XXXXXXX",
style: TextStyle(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis),
),
],
),
);
}),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
scrollable: true,
title: Text('ADICIONAR PEÇA'),
content: Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
icon: Icon(Icons.search),
),
),
],
),
),
),
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.blue,
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32.0),
),
),
child: Text("IR"),
onPressed: () {
// your code
}),
],
);
});
},
child: Icon(Icons.add)),
);
}
}
Declare a local variable in class.
For example:
class PhotosScreen {
final photos = <Photo>[];
Future<void> reloadPhotos() async {
photos.clear();
photos.addAll(await api.getPhotos());
setState(() {});
}
}
In your case (you placed a variable to method, not to class):
var produtosList1 = <ProdutoOs>[];
#override
final _numeroOsController = TextEditingController();
void initState() {
super.initState();
}

Automatically refresh or call future function

I have a future builder which fetches an API
Everything works fine but I have an option to delete an item from the list.
When I delete an item the list should get refreshed or the future function must be called.
My code
class ViewPlans extends StatefulWidget {
static const id = 'ViewPlans';
#override
_ViewPlansState createState() => _ViewPlansState();
}
class _ViewPlansState extends State<ViewPlans> {
PlannerService _plannerService = new PlannerService();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(gradStartColor), Color(gradEndColor)])),
child: FutureBuilder(
future: _plannerService.getPlans(),
builder: (context, snapshot) {
var plans = snapshot.data;
if (plans == 'empty' || plans == null) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
));
}
return RefreshIndicator(
onRefresh: _plannerService.getPlans,
child: ListView.separated(
physics: BouncingScrollPhysics(),
itemCount: plans.content.length,
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 30),
separatorBuilder: (context, index) => null,
itemBuilder: (context, index) {
return Container(
height: 100,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Material(
elevation: 2,
shadowColor: Colors.white,
color: Colors.white,
borderRadius: BorderRadius.circular(10),
child: Center(
child: ListTile(
title: Text(
plans.content[index].task[0].toUpperCase() +
plans.content[index].task.substring(1),
style: TextStyle(
fontSize: 22,
fontFamily: agne,
color: Color(gradStartColor)),
),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Color(gradStartColor),
),
onPressed: () {
_plannerService
.deletePlan(plans.content[index].id)
.then((value) => handleDelete(value));
},
splashRadius: 25,
),
),
),
),
),
);
},
),
);
},
),
),
),
);
}
handleDelete(value) {
if (value == "deleted") {
Fluttertoast.showToast(
msg: 'Task deleted successfully',
fontSize: 20,
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.black);
} else {
Fluttertoast.showToast(
msg: 'Task deletion failed',
fontSize: 20,
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.black);
}
}
}
In this code, I can't even see the refresh indicator.
give a solution please thanks in advance
A quick solution is to use the setState((){}) function after the completion of delete operation. This will recall the build function, and it will refresh your widget tree.
You can create future variable and assign it to _plannerService.getPlans(). Use it in your future builder instead of _plannerService.getPlans(). Change onRefresh to setState((){future = _plannerService.getPlans()}). This code will rebuild your FutureBuilder with the updated data.
class ViewPlans extends StatefulWidget {
static const id = 'ViewPlans';
#override
_ViewPlansState createState() => _ViewPlansState();
}
class _ViewPlansState extends State<ViewPlans> {
PlannerService _plannerService = new PlannerService();
Future<void> _future;
#override
void initState() {
_future = _plannerService.getPlans();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(gradStartColor), Color(gradEndColor)])),
child: FutureBuilder(
future: _future,
builder: (context, snapshot) {
var plans = snapshot.data;
if (plans == 'empty' || plans == null) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
));
}
return RefreshIndicator(
onRefresh: () {
setState(() {
_future = _plannerService.getPlans();
})
return Future.value(true);
},
child: ListView.separated(
physics: BouncingScrollPhysics(),
itemCount: plans.content.length,
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 30),
separatorBuilder: (context, index) => null,
itemBuilder: (context, index) {
return Container(
height: 100,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Material(
elevation: 2,
shadowColor: Colors.white,
color: Colors.white,
borderRadius: BorderRadius.circular(10),
child: Center(
child: ListTile(
title: Text(
plans.content[index].task[0].toUpperCase() +
plans.content[index].task.substring(1),
style: TextStyle(
fontSize: 22,
fontFamily: agne,
color: Color(gradStartColor)),
),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Color(gradStartColor),
),
onPressed: () {
_plannerService
.deletePlan(plans.content[index].id)
.then((value) => handleDelete(value));
},
splashRadius: 25,
),
),
),
),
),
);
},
),
);
},
),
),
),
);
}

I am trying to put gesture dectector in the alert dialog to navigate to next page but the alert box overflows

I am not using any button in alert dialog, so in action how can we prevent the overflow the alert dialog, if am using gesture detector or inkwell to get ontap or onpress function or is there any other method to do it
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return UnicornAlertDialog(
title: Column(
children: <Widget>[
Container(
child: Image.asset('images/done.png'),
),
const SizedBox(height: 15.0),
Container(
child: Text(
'Verify',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
)
],
),
content: Text('You have successfully verified your mobile number',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 15.0)),
gradient: LinearGradient(
colors: <Color>[
Color(0xDD4a00e0),
Color(0xFF8e2de2),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
actions: <Widget>[
Container(
child: new GestureDetector(
onTap:(){
Navigator.push(context,
MaterialPageRoute(builder: (context) => ThirdRoute()));
} ,
),
),
]
);
});
}
You are getting overflow error due to GestureDetector used inside actions property of the dialog. If you just want user to tap anywhere on the alertDialog, you can wrap the AlertDialog with GestureDetector. With this, when user taps anywhere on the dialog, it will navigate them to thirdRoute. Working code below:
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return GestureDetector(
child: AlertDialog(
title:
Column(
children: <Widget>[
Container(
child: Image.asset('images/done.png'),
),
const SizedBox(height: 15.0),
Container(
child: Text(
'Verify',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
)
],
),
content:
Text('You have successfully verified your mobile number',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 15.0)),
// gradient: LinearGradient(
// colors: <Color>[
// Color(0xDD4a00e0),
// Color(0xFF8e2de2),
// ],
// begin: Alignment.topCenter,
// end: Alignment.bottomCenter,
// ),
actions: <Widget>[]
),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => NextScreen()));
}
);
});
}
Hope this answers your question.
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return GestureDetector(
child: UnicornAlertDialog(
title: Column(
children: <Widget>[
Container(
child: Image.asset('images/done.png'),
),
const SizedBox(height: 15.0),
Container(
child: Text(
'Verify',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
)
],
),
content: Text(
'You have successfully verified your mobile number',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 15.0)),
gradient: LinearGradient(
colors: <Color>[
Color(0xDD4a00e0),
Color(0xFF8e2de2),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
actions: <Widget>[ ]),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ThirdRoute()));
},
);
});
}
Unicorn alert dialog is used for background-color decoration, and since you cannot have gradient color in normal alert dialog, I used this.
code snippet
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return UnicornAlertDialog(
title: GestureDetector(
onTap: () { print("on tap title");},
child: Column(
children: <Widget>[
Container(
child: Image.asset('assets/images/background.jpg'),
),
const SizedBox(height: 15.0),
Container(
child: Text(
'Verify',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
)
],
),
),
content: GestureDetector(
onTap: () { print("on tap content");},
child: Text('You have successfully verified your mobile number',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 15.0)),
),
gradient: LinearGradient(
colors: <Color>[
Color(0xDD4a00e0),
Color(0xFF8e2de2),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
actions: <Widget>[
]
);
});
}
full code
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
class UnicornAlertDialog extends StatelessWidget {
const UnicornAlertDialog({
Key key,
#required this.gradient,
this.title,
this.titlePadding,
this.titleTextStyle,
this.content,
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
this.contentTextStyle,
this.actions,
this.backgroundColor,
this.elevation,
this.semanticLabel,
this.shape,
}) : assert(contentPadding != null),
super(key: key);
final Gradient gradient;
final Widget title;
final EdgeInsetsGeometry titlePadding;
final TextStyle titleTextStyle;
final Widget content;
final EdgeInsetsGeometry contentPadding;
final TextStyle contentTextStyle;
final List<Widget> actions;
final Color backgroundColor;
final double elevation;
final String semanticLabel;
final ShapeBorder shape;
#override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final ThemeData theme = Theme.of(context);
final DialogTheme dialogTheme = DialogTheme.of(context);
final List<Widget> children = <Widget>[];
String label = semanticLabel;
if (title != null) {
children.add(Padding(
padding: titlePadding ?? EdgeInsets.fromLTRB(24.0, 24.0, 24.0, content == null ? 20.0 : 0.0),
child: DefaultTextStyle(
style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.title,
child: Semantics(
child: title,
namesRoute: true,
container: true,
),
),
));
} else {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
label = semanticLabel;
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
label = semanticLabel ?? MaterialLocalizations.of(context)?.alertDialogLabel;
}
}
if (content != null) {
children.add(Flexible(
child: Padding(
padding: contentPadding,
child: DefaultTextStyle(
style: contentTextStyle ?? dialogTheme.contentTextStyle ?? theme.textTheme.subhead,
child: content,
),
),
));
}
if (actions != null) {
children.add(ButtonTheme.bar(
child: ButtonBar(
children: actions,
),
));
}
Widget dialogChild = IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
);
if (label != null)
dialogChild = Semantics(
namesRoute: true,
label: label,
child: dialogChild,
);
return Dialog(
backgroundColor: backgroundColor,
gradient: gradient,
elevation: elevation,
shape: shape,
child: dialogChild,
);
}
}
class Dialog extends StatelessWidget {
const Dialog({
Key key,
this.gradient,
this.backgroundColor,
this.elevation,
this.insetAnimationDuration = const Duration(milliseconds: 100),
this.insetAnimationCurve = Curves.decelerate,
this.shape,
this.child,
}) : super(key: key);
final Color backgroundColor;
final double elevation;
final Duration insetAnimationDuration;
final Curve insetAnimationCurve;
final ShapeBorder shape;
final Widget child;
final Gradient gradient;
static const RoundedRectangleBorder _defaultDialogShape =
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
static const double _defaultElevation = 24.0;
#override
Widget build(BuildContext context) {
final DialogTheme dialogTheme = DialogTheme.of(context);
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
duration: insetAnimationDuration,
curve: insetAnimationCurve,
child: MediaQuery.removeViewInsets(
removeLeft: true,
removeTop: true,
removeRight: true,
removeBottom: true,
context: context,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 280.0),
child: Material(
color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
type: MaterialType.card,
child: ClipRRect(
borderRadius: _defaultDialogShape.borderRadius,
child: Container(
decoration: BoxDecoration(
gradient: gradient
),
child: child,
),
),
),
),
),
),
);
}
}
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return UnicornAlertDialog(
title: GestureDetector(
onTap: () { print("on tap title");},
child: Column(
children: <Widget>[
Container(
child: Image.asset('assets/images/background.jpg'),
),
const SizedBox(height: 15.0),
Container(
child: Text(
'Verify',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
)
],
),
),
content: GestureDetector(
onTap: () { print("on tap content");},
child: Text('You have successfully verified your mobile number',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 15.0)),
),
gradient: LinearGradient(
colors: <Color>[
Color(0xDD4a00e0),
Color(0xFF8e2de2),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
actions: <Widget>[
]
);
});
}
Future<void> _ackAlert(BuildContext context) {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Not in stock'),
content: const Text('This item is no longer available'),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
enum ConfirmAction { CANCEL, ACCEPT }
Future<ConfirmAction> _asyncConfirmDialog(BuildContext context) async {
return showDialog<ConfirmAction>(
context: context,
barrierDismissible: false, // user must tap button for close dialog!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Reset settings?'),
content: const Text(
'This will reset your device to its default factory settings.'),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop(ConfirmAction.CANCEL);
},
),
FlatButton(
child: const Text('ACCEPT'),
onPressed: () {
Navigator.of(context).pop(ConfirmAction.ACCEPT);
},
)
],
);
},
);
}
Future<String> _asyncInputDialog(BuildContext context) async {
String teamName = '';
return showDialog<String>(
context: context,
barrierDismissible: false, // dialog is dismissible with a tap on the barrier
builder: (BuildContext context) {
return AlertDialog(
title: Text('Enter current team'),
content: new Row(
children: <Widget>[
new Expanded(
child: new TextField(
autofocus: true,
decoration: new InputDecoration(
labelText: 'Team Name', hintText: 'eg. Juventus F.C.'),
onChanged: (value) {
teamName = value;
},
))
],
),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop(teamName);
},
),
],
);
},
);
}
enum Departments { Production, Research, Purchasing, Marketing, Accounting }
Future<Departments> _asyncSimpleDialog(BuildContext context) async {
return await showDialog<Departments>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Select Departments '),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, Departments.Production);
},
child: const Text('Production'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, Departments.Research);
},
child: const Text('Research'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, Departments.Purchasing);
},
child: const Text('Purchasing'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, Departments.Marketing);
},
child: const Text('Marketing'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, Departments.Accounting);
},
child: const Text('Accounting'),
)
],
);
});
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: AppBar(
title: Text("Dialog"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
onPressed: () {
_showDialog(context);
},
child: const Text("Unicon Dialog"),
),
new RaisedButton(
onPressed: () {
_ackAlert(context);
},
child: const Text("Ack Dialog"),
),
new RaisedButton(
onPressed: () async {
final ConfirmAction action = await _asyncConfirmDialog(context);
print("Confirm Action $action" );
},
child: const Text("Confirm Dialog"),
),
new RaisedButton(
onPressed: () async {
final Departments deptName = await _asyncSimpleDialog(context);
print("Selected Departement is $deptName");
},
child: const Text("Simple dialog"),
),
new RaisedButton(
onPressed: () async {
final String currentTeam = await _asyncInputDialog(context);
print("Current team name is $currentTeam");
},
child: const Text("Input Dialog"),
),
],
),
),
);
}
}
void main() {
runApp(new MaterialApp(home: new MyApp()));
}

Categories

Resources