Flutter iOS Google maps: weird appear animation - ios

I'm having an issue with Flutter Google maps official plugin on iOS both in debug and release builds which occurs when you open an app from a terminated state. No issue on Android
There's a weird appear animation playing when I have Google Map in my widget, especially it's annoying when there's a centered floating action button as well, it has some slide in animation too
Check this video https://www.youtube.com/watch?v=94ee6cePbWw&feature=youtu.be
If you play it frame by frame, you'll see that app bar is colored correctly, floating action button is drawn, but then everything is flashed white and floating action button suddenly plays a slide in appearing animation, when it was already displayed. It all looks very glitchy
If I remove Google map from my widget, everything works fine: there's no FAB slide in animation and app bar is not flashed white, after they were drawn.
Running on Flutter v1.1.4. I want to get rid of this appear animation, thanks for the support
Here's my code
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: '',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: ''),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('')),
body: GoogleMap(
onMapCreated: (controller) {},
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

You should realize that this is a developer preview. Until the version number hits 1.0, all bets are off about how well it performs, and even if it's suitable.

Related

Flutter Firestore Read Write Response Very Slow in Ios

I have added flutter firestore my ios app. The read-write update delete request to firestore is very quick as usual, but when I want to get the response of the read write update delete back from firestore server, it is very slow and fails sometimes.
The code for write and read in my main.dart is
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
final firestoreInstance = FirebaseFirestore.instance;
final auth = FirebaseAuth.instance;
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<void> adduser() async {
await firestoreInstance.collection("users").add({
"mob": 9344122678292,
"email": "usehhr5",
"name": {"fname": "Sub", "lname": "Collec"},
"array": [
"raw",
"pin",
"hot",
],
"time": FieldValue.serverTimestamp(),
}).then((value) {
print("added_data");
}).catchError((error) => print("Failed to add user: $error"));
}
Future<void> readdata() async {
await firestoreInstance.collection("users").get().then((querySnapshot) {
//firestoreInstance.clearPersistence();
querySnapshot.docs.forEach((result) {
print(result.data());
print("read_data");
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//adduser();
readdata();
},
tooltip: 'Read/Add data',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
So i want to get the response from read and write in print() statemen, but it takes 2-3 seconds to get the response and some times i get this error message in log
console response
Also sometime get this response
7.3.0 - [Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
and this repsonse
[BackgroundTask] Background Task 22 ("GTMSessionFetcher-www.googleapis.com"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
Please provide help, I tried the read and write response from firestore in ios emulator and a physical android device, it was perfect. I was getting instant response from the firesotre server. The issue is showing when i run the app in physical ios device running ios 14.4
As it seems, you are calling async methods directly from the StatefulWidget , that's not good. Those async methods are interacting with Firestore , and any slowness will directly affect the user experience.
few suggestions:
accessing Firestore right from the widget is not the right way. This will your app unresponsive.
Widgets should be responsible for the user interaction and be responsive.
Data processing (Firestore etc) should be handled by BLoC and be done in an async way. State management plays essential role in building Flutter apps.

Why is there overlap between a Flutter CupertinoApp's header and slivers underneath unless I wrap it in a Material widget?

This seems like a bug, but I wanted to solicit feedback first. In my simple demo app below, you can see where the SliverChildBuilderDelegate is generating Text widgets as the SliverList. When you scroll up the text widgets overlap with the header. If you wrap the Text widget in a Material widget then that solves the problem (perhaps it's because of Material's clipping capability?). Mixing Material and Cupertino widgets isn't the best, however, particularly if you want to use a CupertinoTheme.
Any suggestions about what's going on and what to do about it is appreciated.
thanks
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Cupertino Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: SafeArea(
child: CustomScrollView(
shrinkWrap: true,
slivers: [
CupertinoSliverNavigationBar(
largeTitle: Text('Cupertino Demo'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => Material(child: Text('This is list item number $index')),
),
)
],
),
),
);
}
}
Because of the shrinkWrap:true, you can read more here:
https://github.com/flutter/flutter/issues/28197
I don't see why would you need that, so simply just remove and it will work.

Default back button not showing after pushing new screen

I had pushed a new Screen from my main screen and it had navigated smoothly and also showed the back button however now that I run the button, the default button is not showing in my code.
The only change that I made was that I changed the route in my main file from taskScreen() to task().
But this was essential as i wanted to make some more routes from my second screen and so it had to return a Material App.
How can i get the default back button back?
My code:
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 Demo',
home: DefaultTabController(length: 2,child: MyHomePage(title: '')),
routes: <String, WidgetBuilder>{
"/TaskScreen": (BuildContext context) => new task(), //CHANGED HERE
},
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
..
),
body: ...
}
}
My second screen
class task extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Task',
home: new taskScreen(),
routes: <String, WidgetBuilder>{
"/Completed": (BuildContext context) => new Completed()
}
);
}
}
class taskScreen extends StatefulWidget{
#override
taskState createState() => new taskState();
}
class taskState extends State<taskScreen> {
#override
Widget build(BuildContext context) {
Column taskScreen = Column (...)
return Scaffold(
appBar: AppBar(
title: Text('Task Screen')),
body: taskScreen,
);
}
}
Class name must to start with uppercase character. You have wrong structure, MaterialApp must to be only one time.
https://dart.dev/guides/language/language-tour
For me it happened when I added a draw to all my various AppBars ... quick googling provided a solution which worked for me:
I added to the AppBar the following which let flutter take a conscious decision whether there is or is not what to go back to ...
automaticallyImplyLeading: true,
Then I added defined how the "leading" should look like (also to the appbar):
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context, false),
),
Making a long story short: Adding the following to the respective AppBar did the work:
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context, false),
),
Remove the second routes MaterialApp and replace it with an AppBar

Flutter Globals losing their value

Okay, I am sure this is probably an easy to answer question, but after much searching I can't put my finger on the solution.
How does one in Flutter/Dart create a variable in app XYZ that maintains its' value during the time a user moves away from the app, uses another app, allows the phone to go to sleep, etc., then opens the XYZ app again.
I've created a tiny little app that demonstrates the issue as shown below.
The static variable Globals.UID can be incremented upwards, but if the app is moved away from (what term describes using another app correctly?) then as noted the phone goes to sleep, when the user comes back to the app the Globals.UID variable is reset back to -1.
Sometimes the reset is not immediate and I have to let the IOS phone sleep for perhaps 5 minutes to recreate the behavior.
Basically I need Globals.UID to retain its' value until the app is actually exited.
Any insight would truly be appreciated.
import 'package:flutter/material.dart';
import 'package:test_flutter/Globals.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 Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
Globals.UID ++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
Text ( "Global variable is:")
, Text ( Globals.UID.toString() )
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
And in a different file called Globals.dart
class Globals {
static int UID = -1;
}
Thank you!
Ultimately, the solution appears to be solved mostly by using the shared_preferences library. That solution brings with it a good many documented problems, but to maintain data while the app is placed in the background, or even killed by perhaps the user, shared_preferences appears to be the way to go.
Actually this happens to when you don't import with reference. This is a known issues which is already fixed, may be not landed yet. You can check the issue here.
Please try import package_name/globals.dart instead of just import globals.dart if you are doing so.
Hope that helps!

Flutter setEnabledSystemUIOverlays hide top statusbar

I encountered a problem when I set the SystemUiOverlay.bottom on my appbarwidget using SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]) and noticed that status bar is hidden but once I pull down upper side of the screen it shows and doesn't disappear again. So I came up with the idea to add a gesture detector for the whole widget app to hide it all the time when you press anywhere on the screen. And I am wondering if this is the best solution and there will not be any issues with the performance or whatever. Any thoughts?
void main() => runApp(PlanetsApp());
class PlanetsApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () => SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]),
child: new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Planets App',
color: Colors.purple,
home: HomeScreen(),
),
);
}
}
After switching to Flutter I also noticed this behavior :(
I dont want to use GestureDetector, and I am not sure where to place SystemChrome.setEnabledSystemUIOverlays so it hides the bar properly...
Instead, I did this: in the Android styles.xml where the App theme is I've added:
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
This makes the sys-bar to always disappear when the app gets clicked
change your code to this.
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
For the issue (https://github.com/flutter/flutter/issues/14432) mentioned in comment, I've found a temporary solution. When you hide status bar or bottom bar, Appbar's height remains same and it takes too much space, especially when you are using landscape mode. To fix this, set "primary" property of Scaffold and Appbar false.
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
SystemChrome.setEnabledSystemUIOverlays([]);
super.initState();
}
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
primary: false,
appBar: AppBar(
primary: false,
backgroundColor: Colors.blue,
),
body: Center(child: Text("It works!")),
),
);
}
}
Hope it helps!
There is not fix for this as of right now. When status bar is hidden, app bar's height remains the same.
See the github issue: https://github.com/flutter/flutter/issues/14432

Resources