Flutter setState double value not change? - dart

I'm using Dart Flutter for develop apps but It's not working?
      
void _goLondon() {
setState(() {
mapLat = 23.7807777;
mapLng = 90.3492857;
});
}

with only this code is not possible to know what is going on.
mapLat and mapLng can not be const or final
and your mapWidget need to be inside a StatefullWidget

Related

flutter real time face detection

I am currently developing an app that requires real time face detection. Right now I have the mlkit library in the app and I am using the firebase face detector. At the moment, it produces an error every time I try to detect a face from file:
DynamiteModule(13840): Local module descriptor class for com.google.android.gms.vision.dynamite.face not found.
As for the real time part, I tried using the RepaintBoundary in flutter to get a screenshot of the camera widget (almost)every frame and convert it into a binary file for face detection. But for some reason, flutter crashed every time I tried to screenshot the camera widget. It worked for other widgets.
After coming across both of these problems and spending quite a while trying to solve them, I've been thinking about just doing the camera part of the app in android/iOS native code(I would do this with OpenCV so that I can have real time detection). Is there a way I could use platform channels to implement a camera view in kotlin and swift and import that to a flutter widget? Or is there another easier way to implement this?
For the real-time access to camera image stream, I answered in another question How to access camera frames in flutter quickly that you want to use CameraController#startImageStream
import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: _MyHomePage()));
class _MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<_MyHomePage> {
dynamic _scanResults;
CameraController _camera;
bool _isDetecting = false;
CameraLensDirection _direction = CameraLensDirection.back;
#override
void initState() {
super.initState();
_initializeCamera();
}
Future<CameraDescription> _getCamera(CameraLensDirection dir) async {
return await availableCameras().then(
(List<CameraDescription> cameras) => cameras.firstWhere(
(CameraDescription camera) => camera.lensDirection == dir,
),
);
}
void _initializeCamera() async {
_camera = CameraController(
await _getCamera(_direction),
defaultTargetPlatform == TargetPlatform.iOS
? ResolutionPreset.low
: ResolutionPreset.medium,
);
await _camera.initialize();
_camera.startImageStream((CameraImage image) {
if (_isDetecting) return;
_isDetecting = true;
try {
// await doOpenCVDectionHere(image)
} catch (e) {
// await handleExepction(e)
} finally {
_isDetecting = false;
}
});
}
Widget build(BuildContext context) {
return null;
}
}
I did something this with OpenCV before, my solution was:
Start a new Activity or ViewController on Android and iOS respectively via platform channel. Example:
class FaceScanPlugin(val activity: Activity) : MethodCallHandler, PluginRegistry.ActivityResultListener {
var result: Result? = null
companion object {
#JvmStatic
fun registerWith(registrar: Registrar): Unit {
val channel = MethodChannel(registrar.messenger(), "com.example.facescan")
val plugin = BarcodeScanPlugin(registrar.activity())
channel.setMethodCallHandler(plugin)
registrar.addActivityResultListener(plugin)
}
}
override fun onMethodCall(call: MethodCall, result: Result): Unit {
if (call.method.equals("scan")) {
this.result = result
showFaceScanView()
} else {
result.notImplemented()
}
}
private fun showFaceScanView() {
val intent = Intent(activity, FaceScannerActivity::class.java)
activity.startActivityForResult(intent, 100)
}
override fun onActivityResult(code: Int, resultCode: Int, data: Intent?): Boolean {
if (code == 100) {
if (resultCode == Activity.RESULT_OK) {
return true
}
}
return false
}
}
Refer to Flutter QR scanner plugin on how to navigate to Android activity or iOS View.
Then do your OpenCV real-time face detection via Camera2 and AVFoundation.
Other than that, I supposed you can try out the new AndroidView or UIKitView if you want to embed the android or iOS into your Flutter app.

Flutter device shake iOS plugin

Evening guys,
Im looking into building a plugin for Flutter that detects if the device is shaking. Now i've found how to technically do it in Swift (Detect shake gesture IOS Swift) but im stuck on how to hook it up as a Flutter plugin, because i don't have direct access to the view controller lifecycle events.
Need a way to hook up
viewDidLoad
canBecomeFirstResponder
motionEnded
Can anyone nudge me in the right direction?
The Flutter Team has already published a plugin called sensors, which can be used to detect motion from the accelerometer (and gyroscope).
import 'package:sensors/sensors.dart';
accelerometerEvents.listen((AccelerometerEvent event) {
// "calculate" "shakes" here
});
The event contains x, y and z values. Combining this with time will make it possible to check for shakes.
I am just pointing this out because it is way less to go than creating a full plugin from scratch.
You could try this plugin: shake_event
It's pretty simple to work with and works both for iOS and Android.
I ran into the same issue, so I figured Reactive Programming and RxDart could help.
You can create a BLoC (Business logic component) called sensor_bloc.dart :
import 'dart:async';
import 'dart:math';
import 'package:rxdart/rxdart.dart';
import 'package:sensors/sensors.dart';
class SensorBloc {
StreamSubscription<dynamic> _accelerometerStream;
//INPUT
final _thresholdController = StreamController<int>();
Sink<int> get threshold => _thresholdController.sink;
// OUTPUT
final _shakeDetector = StreamController<bool>();
Stream<bool> get shakeEvent => _shakeDetector.stream.transform(ThrottleStreamTransformer(Duration(seconds: 2)));
SensorBloc() {
const CircularBufferSize = 10;
double detectionThreshold = 70.0;
List<double> circularBuffer = List.filled(CircularBufferSize,0.0);
int index = 0;
double minX=0.0, maxX=0.0;
_thresholdController.stream.listen((value){
// safety
if (value > 30) detectionThreshold = value*1.0;
});
_accelerometerStream = accelerometerEvents.listen((AccelerometerEvent event){
index = (index == CircularBufferSize -1 ) ? 0: index+1;
var oldX = circularBuffer[index];
if (oldX == maxX) {
maxX = circularBuffer.reduce(max);
}
if (oldX == minX) {
minX = circularBuffer.reduce(min);
}
circularBuffer[index] = event.x;
if (event.x < minX ) minX=event.x;
if (event.x> maxX) maxX = event.x;
if (maxX-minX>detectionThreshold)
{
_shakeDetector.add(true);
circularBuffer.fillRange(0, CircularBufferSize, 0.0);
minX=0.0;
maxX=0.0;
}
});
}
void dispose() {
_shakeDetector.close();
_accelerometerStream.cancel();
_thresholdController.close();
}
}
Then, just subscribe to its events in your widget :
Declare StreamSubscription<bool> shakeSubscriber ; in your state, and hook to lifecycle events
(NB: I use a InheritedWidget giving me access to the umbrella BLoC via the static function MainWidget.bloc(context)):
StreamSubscription<bool> shakeSubscriber ;
#override
Widget build(BuildContext context) {
if(shakeSubscriber == null ) {
MainWidget.bloc(context).sensorBloc.shakeEvent.listen((_){
print("SHAKE ! *************************");
});
}
return _buildMainScaffold();
}
#override
void dispose() {
if(shakeSubscriber != null ) shakeSubscriber.cancel();
super.dispose();
}

How to listen for document changes in Cloud Firestore using Flutter?

I would like to have a listener method that checks for changes to a collection of documents if changes occur.
Something like:
import 'package:cloud_firestore/cloud_firestore.dart';
Future<Null> checkFocChanges() async {
Firestore.instance.runTransaction((Transaction tx) async {
CollectionReference reference = Firestore.instance.collection('planets');
reference.onSnapshot.listen((querySnapshot) {
querySnapshot.docChanges.forEach((change) {
// Do something with change
});
});
});
}
The error here is that onSnapshot isn't defined on CollectionReference.
Any ideas?
Reading through cloud_firestore's documentation you can see that a Stream from a Query can be obtained via snapshots().
For you to understand, I will transform your code just a tiny bit:
CollectionReference reference = Firestore.instance.collection('planets');
reference.snapshots().listen((querySnapshot) {
querySnapshot.documentChanges.forEach((change) {
// Do something with change
});
});
You should also not run this in a transaction. The Flutter way of doing this is using a StreamBuilder, straight from the cloud_firestore Dart pub page:
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('books').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text('Loading...');
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['title']),
subtitle: new Text(document['author']),
);
}).toList(),
);
},
);
If you want to know any more, you can take a look at the source, it is well documented, where it is not self-explanatory.
Also take note that I changed docChanges to documentChanges. You can see that in the query_snapshot file. If you are using an IDE like IntelliJ or Android Studio, it is also pretty easy to click through the files in it.
Using this you can listen changes inside a single document.
DocumentReference reference = FirebaseFirestore.instance.collection('collection').doc("document");
reference.snapshots().listen((querySnapshot) {
setState(() {
field =querySnapshot.get("field");
});
});

What are the pros and cons of async, when to and when not to use it and what other alternatives to callback are there?

callbacks or asynchronous methods or other options
A solution to the callback plague is "await" and "async" or more specifacally 'dart:async' library.
Now, what is the cost of asynchrony?
When should we not use them?
What are the other alternatives?
The below is a badly coded non-polymer custom element that acts like a messageBox in desktop environment. It gives me less braces and parenthesis-es but requires the caller to be also async or use "show().then((v){print(v);});" pattern. Should I avoid the pattern like this?
Is callback better? Or there is an even smarter way?
Polling version
import 'dart:html';
import 'dart:async';
void init(){
document.registerElement('list-modal',ListModal);
}
class ListModal extends HtmlElement{
ListModal.created():super.created();
String _modal_returns="";
void set modal_returns(String v){
///use the modal_returns setter to
///implement a custom behaviour for
///the return value of the show method
///within the callback you can pass on calling append .
_modal_returns=v;
}
factory ListModal(){
var e = new Element.tag('list-modal');
e.style..backgroundColor="olive"
..position="absolute"
..margin="auto"
..top="50%"
..verticalAlign="middle";
var close_b = new DivElement();
close_b.text = "X";
close_b.style..right="0"
..top="0"
..margin="0"
..verticalAlign="none"
..backgroundColor="blue"
..position="absolute";
close_b.onClick.listen((_){
e.hide();
});
e.append(close_b,(_)=>e.hide());
e.hide();
return e;
}
#override
ListModal append(
HtmlElement e,
[Function clickHandler=null]
){
super.append(e);
if(clickHandler!=null) {
e.onClick.listen(clickHandler);
}else{
e.onClick.listen((_){
this.hide();
_modal_returns = e.text;
});
}
return this;
}
Future<String> show() async{
_modal_returns = '';
this.hidden=false;
await wait_for_input();
print(_modal_returns);
return _modal_returns;
}
wait_for_input() async{
while(_modal_returns=="" && !this.hidden){
await delay();
}
}
void hide(){
this.hidden=true;
}
Future delay() async{
return new Future.delayed(
new Duration(milliseconds: 100));
}
}
Non-polling version
In response to Günter Zöchbauer's wisdom(avoid polling), posting a version that uses a completer. Thanks you as always Günter Zöchbauer:
import 'dart:html';
import 'dart:async';
void init(){
document.registerElement('list-modal',ListModal);
}
class ListModal extends HtmlElement{
ListModal.created():super.created();
String _modal_returns="";
Completer _completer;
void set modal_returns(String v){
///use the modal_returns setter to
///implement a custom behaviour for
///the return value of the show method.
///Use this setter within the callback for
///append. Always call hide() after
///setting modal_returns.
_modal_returns=v;
}
factory ListModal(){
var e = new Element.tag('list-modal');
e.style..backgroundColor="olive"
..position="absolute"
..margin="auto"
..top="50%"
..verticalAlign="middle";
var close_b = new DivElement();
close_b.text = "X";
close_b.style..right="0"
..top="0"
..margin="0"
..verticalAlign="none"
..backgroundColor="blue"
..position="absolute";
close_b.onClick.listen((_){
e.hide();
});
e.append(close_b,(_){e.hide();});
e.hide();
return e;
}
#override
ListModal append(
HtmlElement e,
[Function clickHandler=null]
){
super.append(e);
if(clickHandler!=null) {
e.onClick.listen(clickHandler);
}else{
e.onClick.listen((_){
_modal_returns = e.text;
this.hide();
});
}
return this;
}
Future<String> show() async{
_modal_returns = '';
_completer = new Completer();
this.hidden=false;
return _completer.future;
}
void hide(){
hidden=true;
_completer?.complete(_modal_returns);
_completer=null;
}
}
Usually there is no question whether async should be used or not. Usually one would try to avoid it. As soon as you call an async API your code goes async without a possibility to choose if you want that or not.
There are situations where async execution is intentionally made async. For example to split up large computation in smaller chunks to not starve the event queue from being processed.
On the server side there are several API functions that allow to choose between sync and async versions. There was an extensive discussion about when to use which. I'll look it up and add the link.
The disadvantages of using async / await instead of .then() should be minimal.
minimal Dart SDK version with async / await support is 1.9.1
the VM needs to do some additional rewriting before the code is executed the first time, but this is usually neglectable.
Your code seems to do polling.
wait_for_input() async {
while(_modal_returns=="" && !this.hidden){
await delay();
}
}
This should be avoided if possible.
It would be better to let the modal manage its hidden state itself (by adding a hide() method for example), then it doesn't have to poll whether it was hidden from the outside.

How to listen for a keyboard event in dart programming

I'm new to google dart and been trying to learn it for a day now. I'm pretty novice to programming in general and I'm trying to read the documentation; however, I feel a bit overwhelmed.
I would like to know the most proper method of creating a interaction for spacebar here key. When one would push spacebar, it would toggle between function void startwatch() , void resetwatch()
I believe this is the correct documentation page also documentation for keyboardEventController
void main() {
}
void startwatch() {
mywatch.start();
var oneSecond = new Duration(milliseconds:1);
var timer = new Timer.repeating(oneSecond, updateTime);
}
void resetwatch() {
mywatch.reset();
counter = '00:00:00';
}
Any further information needed I'll try to respond immediately. Thnk you so much for your help.
To listen to keyboard events and toggle between startwatch() and resetwatch():
void main() {
var started = false;
window.onKeyUp.listen((KeyboardEvent e) {
print('pressed a key');
if (e.keyCode == KeyCode.SPACE) {
print('pressed space');
if (started) {
resetwatch();
} else {
startwatch();
}
started = !started; // A quick way to switch between true and false.
}
});
}
window is an instance of Window class. It's automatically provided for you.
There's also a handy class called KeyEvent, which attempts to eliminate cross-browser inconsistencies. These inconsistencies are usually related to special keys.

Resources