How to use didChangeAppLifecycleState with Flutter Hooks - flutter

I am using Flutter with hooks and I am trying to get the App Life Cycle State. I followed documentation and created new hook (code shown below) which works ok for all situations with one exception. When the application state becomes "paused", the hook does not return the value back to the widget. I am not clear what to do at this point. Someone suggested using Isolates but I don't see how that can help. Updating App Life Cycle is not compute expensive.
Please let me know what else I could do make this work.
Thanks
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
AppLifecycleState useAppLifecycleState() {
return use(const _LifeCycleState());
}
class _LifeCycleState extends Hook<AppLifecycleState> {
const _LifeCycleState();
#override
__LifeCycleState createState() => __LifeCycleState();
}
class __LifeCycleState extends HookState<AppLifecycleState, _LifeCycleState>
with WidgetsBindingObserver {
AppLifecycleState _state;
#override
void initHook() {
super.initHook();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
#override
AppLifecycleState build(BuildContext context) {
return _state;
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_state = state;
});
super.didChangeAppLifecycleState(state);
}
}
Thanks for your help.

Related

super.initstate() not being called

Im a new flutter developer and have just started using the initState(). However, it seems like it never gets called, I tried all fixes I found on here, but none of them works! Here is a simplified example
import 'package:flutter/material.dart';
class example extends StatefulWidget {
#override
_State createState() => _State();
}
class _State extends State<example> {
#override
void Initstate() {
super.initState();
print('hello world');
}
#override
Widget build(BuildContext context) {
return Scaffold();
}
}
The hello world never gets printed though!
initState is not supposed to be inside the build function. You can create the initState function by going to the line above #override before build(), type init, hit ctrl space and it will autocomplete. This would be the correct version:
class _State extends State<Example> {
#override
void initState() {
super.initState();
print('hello world');
}
#override
Widget build(BuildContext context) {
return Scaffold();
}
}

How can I use GeoFire plugin to update my location in background

I am using this plugin to update my location in firebase. When the app is in foreground everything works perfectly but as soon as my app goes in background then the location update service stops,I tried using didChangeAppLifecycleState but I can't seem to get it to work,
This is my implementaion so far..
class HomeTabPage extends StatefulWidget {
#override
_HomeTabPageState createState() => _HomeTabPageState();
}
class _HomeTabPageState extends State < HomeTabPage >
with AutomaticKeepAliveClientMixin, WidgetsBindingObserver {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.inactive ||
state == AppLifecycleState.detached) return;
final isBackground = state == AppLifecycleState.paused;
if (isBackground) {
print("### paused");
StreamSubscription < Position > backgroundStreamSubscription =
Geolocator.getPositionStream().listen((Position position) {
initPositionPoint = position;
Geofire.setLocation(
currentFirebaseUser.uid, position.latitude, position.longitude);
});
}
}
From Github issues #53 and #444 of the flutter-geolocator repo it seems that it doesn't support background location tracking. It seems that some folks have been using background_locator as an alternative, so you might want to look at that.

Disposing Camera preview in CupertinoTabBar when switched in Flutter

I am building a QR code scanner app with a couple of tabs wrapped up within CupertinoTabBar in a CupertinoTabScaffold. I have a CupertinoTabController to take care of the switching between the tabs. One of this tabs has a CameraPreview widget from the Camera plugin of Flutter along with a proper dispose mechanism. However, whenever the tab are switched, the Camera stream still persists, causing the phone to heat up and also causes janky UX. Now I read that the BottomNavigationBar from Material widgets does not persist in this way. Any idea on how to achieve the same behaviour with CupertinoTabBar?
You can use the StatefulWidget for each a page of the tabs and then try to listening AppLifecycleState. Disponse controller if state inactive/paused.
In my case it's working fine.
class Example extends StatefulWidget {
#override
ExampleState createState() => ExampleState();
}
//Implement WidgetsBindingObserver to listen Lifecycle State
class ExampleState extends State<Example> with WidgetsBindingObserver {
late CameraController _controller;
...
...
#override
void initState() {
super.initState();
// Add Listener (Lifecycle State)
WidgetsBinding.instance!.addObserver(this);
}
Future<void> _setupController() async {
//todo setup/init controller
}
//Implements this method to listen Lifecycle State
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_controller.dispose();
_setupCameraAndControllerFuture = _setupController();
}
if (state == AppLifecycleState.inactive) {
_controller.dispose();
} else if (state == AppLifecycleState.paused) {
_controller.dispose();
}
}
#override
void dispose() {
// Remove Listener (Lifecycle State)
WidgetsBinding.instance!.removeObserver(this);
// dispose controller
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
...
...
);
}
}

Getting "Missing concrete implementation of State.build" Error in Flutter

I am receiving the error "Missing concrete implementation of State.build" when attempting to run this code for Angela Yu's FLutter course:
import 'package:flutter/material.dart';
import 'package:clima/services/location.dart';
import 'package:http/http.dart';
class LoadingScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _LoadingScreenState();
}
}
class _LoadingScreenState extends State<LoadingScreen> {
#override
void initState() {
super.initState();
getLocation();
}
}
void getLocation() async {
Location location = Location();
await location.getCurrentLocation();
print(location.latitude);
print(location.longitude);
}
void getData() async {
Response response = await get(
'https://samples.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=439d4b804bc8187953eb36d2a8c26a02');
print(response);
#override
Widget build(BuildContext context) {
return Scaffold();
}
}
I have tried the responses related to this question:
missing concrete implementation of state.build
...but have not had any success. Any insight as to what I'm doing wrong would be very much appreciated.
enter code hereYou have a extra } after
#override
void initState() {
super.initState();
getLocation();
}
Delete it
And another missed above
#override
Widget build(BuildContext context) {
return Scaffold();
}
Check your { }
Check your {}. This error mainly comes due to the missing of {} or using extra {}.

What is the equivalent of Android LiveData in Flutter?

Android's LiveData allows to update the UI when the activity is in an active state. So if a background operation has finished while the activity is paused, the activity won't be notified and thus the app won't crush. Can Flutter perform the same behavior?
For people interested in an equivalent of LiveData for other scenarios, I present you StreamController:
class ExampleViewModel {
StreamController<bool> loggedInStream = StreamController<bool>();
logIn() { loggedInStream.add(true); }
}
class ExampleScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => ExampleScreenState();
}
class ExampleScreenState extends State<ExampleScreen> {
ExampleViewModel _viewModel;
BuildContext _ctx;
#override
void initState() {
super.initState();
_viewModel = ExampleViewModel()
_viewModel.loggedInStream.stream.listen( (loggedIn) {
if ( loggedIn != null && loggedIn ) {
Navigator.of(_ctx).pushReplacementNamed("/home");
}
});
}
#override
Widget build(BuildContext context) {
_ctx = context;
var loginBtn =
RaisedButton(
onPressed: _viewModel.logIn(true),
child: Text(
"LOGIN",
style: new TextStyle(
fontSize: 24.0,
)
),
color: Colors.green,
textColor: Colors.white,
);
return loginBtn;
}
#override
void dispose() {
super.dispose();
_viewModel.loggedInStream.close();
}
}
You can subscribe to it just like a LiveData, using:
loggedInStream.stream.listen( (data) { code } )
And you should clear the listeners in dispose to avoid memory leaks:
loggedInStream.close()
This code basically do the following things:
Creates a screen with a button.
Listen to a Stream (observe a LiveData).
When you click the button, it changes the value.
The listener (observer) is triggered.
Launches new screen.
You can use WidgetsBindingObserver to listen to the application state.
class AppLifecycleReactor extends StatefulWidget {
const AppLifecycleReactor({ Key key }) : super(key: key);
#override
_AppLifecycleReactorState createState() => new _AppLifecycleReactorState();
}
class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
AppLifecycleState _notification;
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() { _notification = state; });
}
#override
Widget build(BuildContext context) {
return new Text('Last notification: $_notification');
}
}
Easy: Flutterx Live Data
There is no need to observe App lifecycle: widget are built only when the app is resumend
This library integrates perfectly LiveData concepts, also is well documented.
Is developed on Flutter 1.14.x-dev you need master flutter channel at the moment
Sorry to be late for the party,
My colleague and I have developed a library that mimics the live data of android, on flutter.
Check it out:
https://pub.dev/packages/stream_live_data