I have an issue regarding a grey screen popping up on a particular part of my application. More specifically, the app works on every screen (testing on a physical iPhone device + Android simulator) except when pressing the 'Register' option. This means that there must be an issue arousing within the body of the register section, but the problem is that no grey screens appear on certain devices (Nexus 5X, iPhone XS Max) but it shows up on an iPhone 11. Any ideas? I will link the body where the error persists below:
Widget build(BuildContext context) => Scaffold(
body: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator());
} else if(snapshot.hasError){
return Center(child: Text('Something Went Wrong'));
} else if(snapshot.hasData){
return WelcomeScreen();
}else{
return Body();
}
},
),
);
As a side note, the "Body()" function works well if I simply do:
Widget build(BuildContext context) => Scaffold(
body: Body(),
);
But I am trying to implement Google Sign In, hence the stream builder.
Related
This question already has an answer here:
Flutter iOS: taps on the status bar can't scroll to top
(1 answer)
Closed 1 year ago.
Generally speaking, it is only available on ios.
When I click on the notch above it takes me to the top of the page
It works on a pre-application for me, but in the current application it does not work, I don't know how to do it or something like that.
Explanation of the location of the notch
may this help:
Scaffold(
body:
Builder(builder: (BuildContext context) =>
CustomScrollView(controller: PrimaryScrollController.of(context))
OR
may be this will help, scrolls_to_top:
#override
Widget build(BuildContext context) {
return ScrollsToTop(
onScrollsToTop: _onScrollsToTop,
scaffold: Scaffold(
appBar: AppBar(title: const Text('Scroll to top')),
body: Container(),
),
);
}
Future<void> _onScrollsToTop(ScrollsToTopEvent event) async {
//TODO: Your code
}
reference: reference
I tried cursorColor and wrapping the TextField in a Theme where textSelectionHandleColor and textSelectionColor are set to whatever colors, however, the text cursor stays blue.
To be clear, I am talking about the handle. None of the following adjust it for me:
https://github.com/flutter/flutter/issues/14598
https://github.com/flutter/flutter/issues/15571
Sadly, it is currently not possible to change the textSelectionHandleColor of a TextField by modifying its parent Theme. The only Theme that changes the textSelectionHandleColor is the Theme directly inside the MaterialApp (source).
Issue on GitHub: textSelectionHandleColor is not working/changing. #20219
The reason this problem exists is that the handles are rendered inside an Overlay. The Overlay is not a child from the TextField, but instead always a child of the MaterialApp. Here is a failed try from another developer to solve the problem: textSelectionHandleColor taken from parent's context. Fixes #20219
Therefore you can currently only adjust the MaterialApp inside your application:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: Theme.of(context).copyWith(textSelectionHandleColor: Colors.red),
home: Scaffold(
body: Center(
child: TextField(
autofocus: true,
),
),
),
);
}
}
I show a snackbar if network connectivity isn't there. I have created a separate stateful widget to check the connectivity and show the bar but I will have to add it to all the screens and so was wondering if there is a better way to include it in all the screens somehow.
Your question is not clear, but I think you want to show the snack bar if the network is not available,?
to get the connectivity status you can use this,
var connectivityResult = await (new Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile ||
connectivityResult == ConnectivityResult.wifi) {
} else {
Scaffold(
appBar: AppBar(
title: Text('SnackBar Demo'),
),
body: Center(
child: Text('No Internet'),
), // You'll fill this in below!
);
}
I completed the Flutter NameGenerator code lab and wanted to extend it to remove items directly from the "Saved suggestions list".
To do so, I've added the onTap handler below which removes the pair from the list.
However, the list doesn't update until I navigate back and reopen the screen again.
How do I immediately update the list on the second screen?
void _pushSaved() {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) {
final Iterable<ListTile> tiles = _saved.map((WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
onTap: () => setState(() {
_saved.remove(pair);
}),
);
});
final List<Widget> divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return Scaffold(
appBar: AppBar(
title: const Text('Saved Suggestions'),
),
body: new ListView(children: divided),
);
}),
);
}
Why your code doesn't work
The reason your list doesn't update is that it's a different screen pushed on the Navigator.
Because your _pushSaved method is inside the original screen, you call setState on that screen and rebuild all the widgets of the original screen.
The pushed screen isn't affected because it's not a child of your original screen.
Rather, the original screen told the Navigator to create a new screen, so it's some subtree of the Navigator of your MaterialApp and not accessible to you.
Solution
Accessing the same live data on different screens is something that's not that easy to do just with StatefulWidgets.
Basically, your project has grown complex enough so that it's time to think about a more sophisticated state management solution.
Here's a video from Google I/O about state management that you could check out for some inspiration.
I am trying to draw a widget whenever a user presses the screen.
Currently I am doing this by storing a list of widgets and when ontapup is fired on the gesture i am adding to a list of widgets.
Widget build(BuildContext context) {
Widget draw = new Text("A");
List<Widget> children = new List<Widget>();
return new Scaffold(
appBar: new AppBar(
title: const Text('Heading'),
leading: new Icon(Icons.question_answer),
),
body: new GestureDetector(
onTapUp: (details) {
setState(() {
children.add(new Positioned(
left: details.globalPosition.dx,
top: details.globalPosition.dy,
child: draw,
));
});
},
child: new Stack(children: children)
...
So my code is working I am drawing the widget when I click but my problem is that when adding the new Positioned() to stack the position is based on the screen which does not include the appbar offset. Is there a way to get the stacks initial x/y position? Or is there a way to get the appbars height? How do I get a widgets position or height/width?
Ok for anyone else who has the same issue I needed to create my own widget and use
context.findRenderObject()
and
globalToLocal()
Just FYI global to local did not work while in the one solution I needed to make it its own widget.
To get the offset of a widget, you must get the renderObject, cast it as a RenderBox, and then convert it's local position to a global position. Like this:
#override
Widget build(BuildContext context) {
RenderBox renderBox = context.findRenderObject();
Offset widgetOffset = renderBox.localToGlobal(Offset.zero);
print("X: ${widgetOffset.dx}");
print("Y: ${widgetOffset.dy}");
}
If you need the position of a child widget, you can wrap that child in a LayoutBuilder, like this:
Container(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints box) {
RenderBox renderBox = context.findRenderObject();
Offset widgetOffset = renderBox.localToGlobal(Offset.zero);
print("X: ${widgetOffset.dx}");
print("Y: ${widgetOffset.dy}");
}
)
)