long press for incrementing value - flutter

I have an increment button with a callback function:
class IncrementButton extends StatelessWidget {
final VoidCallback callback;
const IncrementButton({
Key? key,
required this.callback,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
callback();
},
onLongPressStart: ((details) {
callback();
}),
......
);
}
}
And using it as:
IncrementButton(
callback: _increment,
),
The _increment function is as:
_increment() {
value += 1;
}
What I want is when the user taps once, the _increment function will be called. But when the user keeps a long press on the button, the same increment function should be called. But that doesn't happen. The _increment method is getting called only once for long Press

I guess you want the number to be incremented continually while long pressing the button/container. You need a timer which starts when onLongPress gets called. The timer stops when ´onLongPressEnd` gets called.
Try this:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String action = "START";
Timer? timer;
int number = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Material App Bar'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(action),
SizedBox(height: 50),
Material(
borderRadius: BorderRadius.circular(20),
elevation: 20,
child: GestureDetector(
onTap: () => setState(() {
action = "Tap";
number++;
}),
onLongPress: () => setState(() {
timer = Timer.periodic(Duration(milliseconds: 50), (timer) {
setState(() {
action = "Longpress started";
number++;
});
});
}),
onLongPressEnd: (_) => setState(() {
action = "Longpress stopped";
timer?.cancel();
}),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red[50],
borderRadius: BorderRadius.circular(20)
),
width: 100,
height: 100,
child: Text('Tap')
),
),
),
SizedBox(height: 50,),
Text(number.toString())
],
),
),
),
);
}
#override
void dispose() {
timer?.cancel();
super.dispose();
}
}
Proof:

Change your onlongpressStart.
do{
callback();
} while(btnPressed);
And on onlongpressEnd
setState(() => btnPressed = false);

Related

How can I check the screen click status?

If nothing is done on the screen, I want to print something on the screen some time after the last action. How can I do that? How can I check the screen click status?
You can wrap Scaffold with GestureDetector and use onPanDown to capture the screen event, onTap doesn't win on hit test if there are inner clickable buttons. Also use behavior: HitTestBehavior.translucent,
Another notable thing is here, it is needed to be check on every second, because the checkup unit is on second. You can create a wrapper widget from it.
class ScreenT extends StatefulWidget {
const ScreenT({Key? key}) : super(key: key);
#override
State<ScreenT> createState() => _ScreenTState();
}
class _ScreenTState extends State<ScreenT> {
#override
void dispose() {
timer?.cancel();
super.dispose();
}
Timer? timer;
int maxDelaySec = 10;
int idleScreenCounter = 0;
#override
void initState() {
super.initState();
initTimer();
}
initTimer() {
timer = Timer.periodic(Duration(seconds: 1), (timer) {
idleScreenCounter++;
setState(() {}); //
});
}
onScreenTap() {
print("tapped on Screen");
idleScreenCounter = 0;
setState(() {});
}
#override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onPanDown: (_) => onScreenTap(),
child: Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (maxDelaySec - idleScreenCounter > 0)
SizedBox(
height: 200,
child: Text(
" Tap the screen within ${maxDelaySec - idleScreenCounter}"),
),
if (maxDelaySec - idleScreenCounter < 0)
Container(
height: 100,
width: 100,
color: Colors.cyanAccent,
child: Text("Tap on screen"),
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print("An action");
},
child: Text("A Button"),
),
ElevatedButton(
onPressed: () {
print("act");
},
child: Text("Elev"),
)
],
),
),
),
),
),
);
}
}
A naive approach could involve a Timer with dart:async.
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: _SomeWidget(),
);
}
}
class _SomeWidget extends StatefulWidget {
const _SomeWidget();
#override
State<_SomeWidget> createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<_SomeWidget> {
late Timer _timer;
#override
void initState() {
super.initState();
// It's up to you if you want the timer to start immediately with some effects or not.
_timer = Timer(const Duration(seconds: 1), () {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
// i.e. from the first interaction and so on
_timer.cancel();
_timer = Timer(const Duration(seconds: 1), () {
if (mounted) {
// !
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Some message')),
);
}
});
},
child: const Center(child: Text('My screen contents')),
),
);
}
}
The mounted check is very important, as Timer introduces an async gap, which may be dangerous when using context.
You can add a Gesture detector at the top level and start a timer on tap and on completion you can fire an event like the following
GestureDetector(
onTap: (){
startTimer();
}
child: Column(
children:[
//all other widgets
]
)
),
Then to define the timer
late Timer _timer;
void startTimer()
{
if(_timer != null && _timer.isActive) _timer.cancel();
_timer = Timer(
const Duration(seconds: 30),
() {
print("inactive for 30 seconds");
},
);
}
here in this case each time the user taps on the screen the timer is restarted and on 30th second the print is fired.

Flutter How to set Boolean from Settingpage

How to turn On/Off vibration on Homepage from Settings page with boolean SwitchListTile?
I want if the SwitchListTile in the Settings page is On, the Homepage will vibrate every time I tap it, and vice versa. basically I don't know how to control certain pages from other pages
this is MySettingPage
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MySettingPage extends StatefulWidget {
const MySettingPage({Key key}) : super(key: key);
#override
_MySettingPageState createState() => _MySettingPageState();
}
class _MySettingPageState extends State<MySettingPage> {
bool isVibrate = false;
#override
void initState() {
super.initState();
getSwitchValues();
}
getSwitchValues() async {
isVibrate = await getSwitchState();
setState(() {});
}
Future<bool> saveSwitchState(bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("switchState", value);
return prefs.setBool("switchState", value);
}
Future<bool> getSwitchState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isVibrate = prefs.getBool("switchState");
return isVibrate;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Text("Pengaturan"),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
}),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: [
SwitchListTile(
title: Text("Getar"),
value: isVibrate,
onChanged: (bool value) async {
setState(() {
isVibrate = value;
saveSwitchState(value);
});
},
),
//
],
),
),
);
}
}
this is MyHomePage
import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart';
import 'mysettingpage.dart';
class MyHomePage extends StatefulWidget {
final bool isVibrate;
MyHomePage({Key key, this.isVibrate}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
if (widget.isVibrate == true) {
Vibration.vibrate(duration: 70);
}
if (widget.isVibrate == false) {
Vibration.cancel();
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My Homepage"),
titleSpacing: 0,
leading: IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => MySettingPage(),
));
},
),
),
body: GestureDetector(
onTap: () {
_incrementCounter();
},
child: Container(
height: double.infinity,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.only(bottom: 120),
child: Column(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: FittedBox(
child: Text(
'$_counter',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 200,
fontFamily: 'DS-Digital',
color: Color(0xFF24F3E2),
),
),
),
),
],
),
),
],
),
),
),
),
);
}
}
To continue on the response from Allan C with the changes to your code: (untested)
HomePage:
import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart';
import 'mysettingpage.dart';
class MyHomePage extends StatefulWidget {
final bool isVibrate;
MyHomePage({Key key, this.isVibrate}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool _isVibrate;
#override
void initState() {
super.initState();
_isVibrate = widget.isVibrate;
}
void _onVibrateChange(bool value) {
setState(() {
_isVibrate = value;
})
}
void _incrementCounter() {
setState(() {
_counter++;
if (_isVibrate) {
Vibration.vibrate(duration: 70);
}
if (_isVibrate) {
Vibration.cancel();
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My Homepage"),
titleSpacing: 0,
leading: IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => MySettingPage(
onChange: _onVibrateChange
),
));
},
),
),
body: GestureDetector(
onTap: () {
_incrementCounter();
},
child: Container(
height: double.infinity,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.only(bottom: 120),
child: Column(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: FittedBox(
child: Text(
'$_counter',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 200,
fontFamily: 'DS-Digital',
color: Color(0xFF24F3E2),
),
),
),
),
],
),
),
],
),
),
),
),
);
}
}
using the initState() you set a default value of _isVibrate from the passed value from the widget.isVibrate.
The method _onVibrateChange(bool value) (as a callback) will update the local variable within the state. This method needs to be passed to the MySettingsPage also.
MySettingsPage:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MySettingPage extends StatefulWidget {
const MySettingPage({Key key, this.onChange}) : super(key: key);
final Function(bool value) onChange;
#override
_MySettingPageState createState() => _MySettingPageState();
}
class _MySettingPageState extends State<MySettingPage> {
bool isVibrate = false;
#override
void initState() {
super.initState();
getSwitchValues();
}
getSwitchValues() async {
isVibrate = await getSwitchState();
setState(() {});
}
Future<bool> saveSwitchState(bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("switchState", value);
widget.onChange(value);
return prefs.setBool("switchState", value);
}
Future<bool> getSwitchState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isVibrate = prefs.getBool("switchState");
return isVibrate;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Text("Pengaturan"),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
}),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: [
SwitchListTile(
title: Text("Getar"),
value: isVibrate,
onChanged: (bool value) async {
setState(() {
isVibrate = value;
saveSwitchState(value);
});
},
),
//
],
),
),
);
}
}
I have included a new variable passed to the Statefulwidget (Function(bool value) onChange), this will be the callback for when the switch changes it's value.
In the method Future saveSwitchState(bool value) async there is a call to the passed callback with the updated value from the SwitchListTiles onChange method.
Hope this clarifies what he meant in his answer.
One way to do this is to use a callback function.
So in MySettingPage(), add a constructor such as below:
MySettingPage({this.callback})
final void Function(bool) callback;
In MySettingPage, if you want to update the value of isVibrate in MyHomePage(), you can call widget.callback(true);
In MyHomePage, you can create a method to update the isVibrate variable.
void _updateIsVibrate(bool isVibrate){//...}
When you call MySettingsPage, you can pass in the method you created.
All my problems related to booleans above have been resolved by implementing MultiProvider. Thanks to the above masters who have helped me. have a nice day

I need to highlight the button with a tick in flutter and fade out other two buttons in FLUTTER

What I have done so far: I have three buttons in a row that have a picture and text on them(depicts reaction).
GOAL:
1)I need to highlight the button selected by the user and fade out the other two. (I am new to animation I don't know how to proceed further).
There are many ways of doing animation like you want, I will give you the most simple and not most elegant solution without Matrix4 transformations and AnimatedBuilders, so that it will be clear what is going on.
Here is what animation do:
and here is code to reproduce:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({
Key key,
}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool firstIsSelected = false;
bool secondIsSelected = false;
bool thirdIsSelected = false;
bool isSubmitted = false;
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
setState(() {
secondIsSelected = false;
thirdIsSelected = false;
firstIsSelected = !firstIsSelected;
});
},
child: Item(
selector: firstIsSelected,
color: Colors.red,
submitted: isSubmitted,
),
),
GestureDetector(
onTap: () {
setState(() {
firstIsSelected = false;
thirdIsSelected = false;
secondIsSelected = !secondIsSelected;
});
},
child: Item(
selector: secondIsSelected,
color: Colors.yellow,
submitted: isSubmitted,
),
),
GestureDetector(
onTap: () {
setState(() {
firstIsSelected = false;
secondIsSelected = false;
thirdIsSelected = !thirdIsSelected;
});
},
child: Item(
selector: thirdIsSelected,
color: Colors.green,
submitted: isSubmitted,
),
),
],
),
MaterialButton(
onPressed: () {
if (firstIsSelected||secondIsSelected||thirdIsSelected) {
setState(() {
isSubmitted = !isSubmitted;
});
}
},
color: Colors.blue,
child: Text('SUBMIT'),
),
],
);
}
}
class Item extends StatelessWidget {
final Color color;
final bool selector;
final bool submitted;
const Item({
Key key,
this.color = Colors.blue,
this.selector = false,
this.submitted = false,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AnimatedOpacity(
duration: Duration(milliseconds: 300),
opacity: submitted? selector ? 1 :0 : 1,
child: AnimatedContainer(
margin: EdgeInsets.all(10),
duration: Duration(milliseconds: 300),
color: color,
width: selector?120: 80,
height: selector?120: 80,
),
);
}
}

How to implement a Custom or Flutter Loading Indicator

I have wrapped the body of the code below using GestureDetector, thus enabling me to use onVerticalDragEnd method available in the widget. When the app detects a Vertical Drag the _onRefreshing function is called, where it updates the Text widget after a delay of 2 seconds.
I want to include a Loading indicator while the _onRefreshing function is running.
How do I implement this task in Flutter?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
dynamic balanceAvailable = 0;
void _onRefreshing(DragEndDetails details) async {
await Future.delayed(const Duration(seconds: 2));
if (details.velocity.pixelsPerSecond.dy > 0) {
setState(() {
balanceAvailable = 1000;
});
print('newbalance : $balanceAvailable');
print(details.velocity.pixelsPerSecond.dy);
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GestureDetector(
onVerticalDragEnd: _onRefreshing,
child: Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {},
child: Text("Button 1"),
),
SizedBox(height: 100.0),
Text('$balanceAvailable'),
],
),
),
),
),
);
}
}
You can return a CircularProgressIndicator inside a showdialog in your _onRefreshing method.
After the 2 seconds delay, you can remove it with Navigator.pop();
Maybe like this:
void _onRefreshing(DragEndDetails details) async {
showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: SizedBox(
height: MediaQuery.of(context).size.height/4,
width: MediaQuery.of(context).size.width/2,
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
),
),
);
});
await Future.delayed(const Duration(seconds: 2));
if (details.velocity.pixelsPerSecond.dy > 0) {
setState(() {
balanceAvailable = 1000;
});
print('newbalance : $balanceAvailable');
print(details.velocity.pixelsPerSecond.dy);
}
Navigator.pop(context);
}

How to get the page is not disposed

I have application which has mappage using location
class _MapPageState extends State<MapPage> {
LocationData currentLocation;
Location _locationService = new Location();
#override
void initState(){
super.initState();
_locationService.onLocationChanged().listen((LocationData result) async {
setState(() {
print(result.latitude);
print(result.longitude);
currentLocation = result;
});
});
}
In this case, setState() works well when mappage is shown.
However after mappage is disposed, there comes error like this.
E/flutter ( 6596): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter ( 6596): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
So, I have two ideas.
Remove onLocationChanged() listener when page is disposed.
Check if State is disposed or not before setState()
How can I solve this??
You can copy paste two files below and directly replace official example's code
https://github.com/Lyokone/flutterlocation/tree/master/location/example/lib
After Navigate to ListenLocationWidget page,
you can call _stopListen() in dispose()
code snippet
class _MyHomePageState
...
RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => ListenLocationWidget()),
);
},
),
PermissionStatusWidget(),
Divider(height: 32),
ServiceEnabledWidget(),
Divider(height: 32),
GetLocationWidget(),
Divider(height: 32),
//ListenLocationWidget()
class _ListenLocationState extends State<ListenLocationWidget> {
...
StreamSubscription<LocationData> _locationSubscription;
String _error;
#override
void initState() {
print("initState");
super.initState();
_listenLocation();
}
#override
void dispose() {
print("stopListen");
_stopListen();
super.dispose();
}
Future<void> _listenLocation() async {
_locationSubscription =
location.onLocationChanged.handleError((dynamic err) {
setState(() {
_error = err.code;
});
_locationSubscription.cancel();
}).listen((LocationData currentLocation) {
setState(() {
print("setState");
_error = null;
_location = currentLocation;
});
});
}
Future<void> _stopListen() async {
_locationSubscription.cancel();
}
working demo
full code ListenLocationWidget
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:location/location.dart';
class ListenLocationWidget extends StatefulWidget {
const ListenLocationWidget({Key key}) : super(key: key);
#override
_ListenLocationState createState() => _ListenLocationState();
}
class _ListenLocationState extends State<ListenLocationWidget> {
final Location location = Location();
LocationData _location;
StreamSubscription<LocationData> _locationSubscription;
String _error;
#override
void initState() {
print("initState");
super.initState();
_listenLocation();
}
#override
void dispose() {
print("stopListen");
_stopListen();
super.dispose();
}
Future<void> _listenLocation() async {
_locationSubscription =
location.onLocationChanged.handleError((dynamic err) {
setState(() {
_error = err.code;
});
_locationSubscription.cancel();
}).listen((LocationData currentLocation) {
setState(() {
print("setState");
_error = null;
_location = currentLocation;
});
});
}
Future<void> _stopListen() async {
_locationSubscription.cancel();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Listen location: ' + (_error ?? '${_location ?? "unknown"}'),
style: Theme.of(context).textTheme.body2,
),
Row(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 42),
child: RaisedButton(
child: const Text('Listen'),
onPressed: _listenLocation,
),
),
RaisedButton(
child: const Text('Stop'),
onPressed: _stopListen,
)
],
),
],
),
),
);
}
}
full code main.dart
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:url_launcher/url_launcher.dart';
import 'get_location.dart';
import 'listen_location.dart';
import 'permission_status.dart';
import 'service_enabled.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Location',
theme: ThemeData(
primarySwatch: Colors.amber,
),
home: const MyHomePage(title: 'Flutter Location Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Location location = Location();
Future<void> _showInfoDialog() {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Demo Application'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
const Text('Created by Guillaume Bernos'),
InkWell(
child: Text(
'https://github.com/Lyokone/flutterlocation',
style: TextStyle(
decoration: TextDecoration.underline,
),
),
onTap: () =>
launch('https://github.com/Lyokone/flutterlocation'),
),
],
),
),
actions: <Widget>[
FlatButton(
child: const Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.info_outline),
onPressed: _showInfoDialog,
)
],
),
body: Container(
padding: const EdgeInsets.all(32),
child: Column(
children: <Widget>[
RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => ListenLocationWidget()),
);
},
),
PermissionStatusWidget(),
Divider(height: 32),
ServiceEnabledWidget(),
Divider(height: 32),
GetLocationWidget(),
Divider(height: 32),
//ListenLocationWidget()
],
),
),
);
}
}