How to show a widget throughout app based on condition? - dart

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!
);
}

Related

Flutter grey screen on particular devices

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.

how I can enable when I click in. notch in iOS go top of screen [duplicate]

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

Flutter bring up a list when a button is pressed, and close said list after an option is selected

I'm building an application for a building that can navigate a user, one of the ways I am doing this is by using a floor plan of the building and I want to draw a path between nodes in this floor plan to create a route. The user enters where they want to be and then route finding algorithm outputs a path, the way I want to build this path is by having a user select a source node and a target node from two seperate lists, I want them to press a button on the map view screen and have a list with these nodes appear but no matter what I try the list will not display.
I've tried using setState and having a ListView returned but that seems to be where it's failing as such as I have print statements to help verify where in the code I've reached, I don't know if it's the search terms I'm using but nothing I have found so far seems to be related to this kind of use case. This is similar to what I want but this is just a list already being displayed and then being updated.
Widget build(BuildContext context) {
//currently inside of a scaffold
bottomNavigationBar: BottomAppBar(
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.trip_origin),
onPressed: () {
setState(() {
_sourceList();
});
},
),
],
)),
//extra code as part of scaffold
}
Widget _sourceList() {
print("working1"); //this prints
return ListView.builder(
padding: const EdgeInsets.all(10.0),
itemBuilder: (context, i) {
print("working2"); //this does not
return _buildRow();
});
}
Widget _buildRow() {
return new ListTile(title: Text(a.name));
}
So basically I just want a list to display when the user presses a button, then have that list disappear after a selection is made. The actual result is I can press the button and nothing is displayed, I only reach working1 in the code not working2.

Flutter Codelab: Update ListView on different screen

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.

Position FloatingActionButton on the left side

How do I position a FloatingActionButton on the left side inside a Scaffold?
Currently the only available options are centerFloat, centerDocked, endFloat and endDocked.
Maybe Material Design does not intend to position the FAB at startFloat or startDocked.
That would be fine if RTL changed endFloat and endDocked to appear on the left side, but that is not the case.
In April 2020, the available options have been expanded and startFloat as well as startDocked are included options now.
Here is the full list of available options (see the FloatingActionButtonLocation documentation):
centerDocked
centerFloat
centerTop
endDocked
endFloat
endTop
miniCenterDocked
miniCenterFloat
miniCenterTop
miniEndDocked
miniEndFloat
miniEndTop
miniStartDocked
miniStartFloat
miniStartTop
startDocked
startFloat
startTop
You can even easily define your own locations using StandardFabLocation.
As of 2020, you can use the following:
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat
A parameter that can be passed to the Scaffold Widget from material.dart
Source: PR 51465
There is also another solution to this problem. Fab button by default is always at the bottom end of the screen. So if we wrap our Scaffoldwith a Directionality and set its text direction to TextDirection.rtl, then the button goes left. but since now the body itself is mirrored, we can wrap the body with another Directionality and set its text direction to TextDirection.ltr
#override
Widget build(BuildContext context) {
return
Directionality(
textDirection: TextDirection.rtl,
child:Scaffold(
appBar: AppBar(
title: const Text('Something),
),
body: Directionality(
textDirection: TextDirection.ltr,
child: Center(child: const Text('Press the button below!'))),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
)
);
}

Resources