Flutter, nested futurebuilder? How to refresh only one widget within futurebuilder - flutter

I am trying to build dashboard for sports app, which consists of calendar that holds events, some other info and list of players within team. Upon opening dashboard function getDashboard(teamid) gets called which loads all of the data including calendar and event data.
My calendar has button to switch months, data about next months isn't loaded just because it doesn't make sense to load years worth of data when most of the times only current months data is used.
Currently all of the code is wrapped in futurebuilder.
it looks something like this
FutureBuilder<TeamDashboardDto?>(
future: _teamDashboardDto,
builder: (context, snapshot) {
{
return SingleChildScrollView(
child: Column(
children: [
SomeWidgetsThatcontainInformation(),
Calendar( events: snapshot.data.eventList),
PlayerList(data: snapshotData),
], ), ), }, )
Although UI ir horrendous i hope you get the idea.
I dont want to reload all of the data, i just want to refresh Calendar data and while its being loaded I wish to replace calendar with loading icon. Is this possible? Or maybe I should just reload all dashboard?

Although I don't completely understand the question, I would recommend making future requests on initstate then on the click of a button make a new future request and use setstate to update your UI. This in turn gives you flexibility.

Related

I am having problem navigating same page and the data is not chaning in flutter

How can I navigate same page like I am tapping related products in Product details page and it will navigate to Product details page according to that related product? I want to call same page over and over again.
If you make your ProductDetails page take in a Product (or id, depends on your data) you should be able to call it. It depends on how you want to build your routes (and how you want to be able to go back), of course. Say you havce your ProductDetails take in a product to display:
ProductDetails(product: myProduct)
Then it can get the related products, and you can make the related product push another ProductDetails page:
// In your product details page
Widget relatedProductsWidget() {
return Row(
children: relatedProducts.map((product) => ProductCard(
product: product,
onTap: () => Navigator.of(context).push(
// Simply push another product on the stack
MaterialPageRoute(builder: (context) => ProductDetails(product: product))
),
)),
);
}
It depends, of course, on how you wish to go back. This way, a whole stack of ProductDetails pages will be pushed (and popped again when the back button is pressed). Alternatively, if you only want a single product details page to be present at any time, you can use Navigator.of(context).pushReplacement instead, to animate to the new location and then dispose the old route. Now when the user goes back, he is brought back to the main product list without seeing the old product first.
https://api.flutter.dev/flutter/widgets/Navigator/push.html
https://api.flutter.dev/flutter/widgets/Navigator/pushReplacement.html
I hope this gets you on the way to get your navigation sorted. If you have a specific issue, I recommend you to post a minimal version of your code to make it clear what you're trying to accomplish, as it's still a little bit vague from your question right now.
My answer only works if you use firebase.
Just complete the steps:
Create in the database a collection called products
Now add the products and in all products/documents you need to have a field called id. PS: any ids have to be used only one time.
Create in your code a global variable called id
If you tab on one of the products the id-variable need to be set to the id of the product you tabs on
In your Product-Details Page add a variable called productData
Create in your Product-Details class a method that looks like this:
getProductData() async {
await FirebaseFirestore.instance.collection("products").where("id", isEqualTo: id).get().then((value) {
productData = value.docs[0].data();
});}
In your initState() add this method:
asyncTasks() async {
await getProductData();
}
Call the method asyncTasks() in your initState
Now you can get data from the product document like this:
// Now you get the value that stands in the price field
productData["price"];
Hope it helps!

is it possible to do pull to refresh action in empty screen

I have this screen with no list of data to show in this empty screen also when I pull down I wanna perform the refresh indicator function but I don't know how to do it. when there is a list of data pull to refresh works perfectly fine but if there is no data pull to refresh doesn't work is there a way to achieve pull to refresh in an empty screen like this also. thanks
Yes, with RefreshIndicator Widget, it's very simple, wrap the whole page in RefreshIndicator Widget, and just keep in mind that you should make the onRefresh function to return Future, because after getting the data, there is 2 things to be handled:
the widget will handle the CircularProgressIndicator just after the onRefresh function gets the data, that is why I used await at the code example, to make the widget know when the function is finished.
you should update the state, like this code, I'm using bloc to update it, you are free to use any stage management else:
RefreshIndicator(
onRefresh: () async {
await _bloc.pull();
}
child: .....,
);
For more tutorial check this video.
YOU Can wrap your entire screen with a refreshIndicator, and you get access to the refresh function.
body: RefreshIndicator(
onRefresh: () async {
fetchData();
},
child:// your other widgets here

Keeping a route alive in Flutter

I have a flutter app where can see several cards. These cards are clickable, and will show a InAppWebView with a custom made viewer, which exists on the website I link to.
The loading of this InAppWebView is pretty taxing on the app however, and I would like to pre-load this as much as possible.
It is kinda hard to give a lot of details, since this is job-related and thus private information, so I can't be too specific. I am also the only one working with Flutter here, so no advice can be expected from colleagues.
I am hoping to reduce the loading times of the InAppWebView by having it opened in the background already, and then just swapping to the correct route instead of initializing it from scratch. The problem here is that the URL will change, but that can be handled inside the view instead of creating an entirely new InAppWebView.
In short:
How do I create a widget/route in the background of my Flutter application, and swap to it when necessary?
Maybe you can use a Stack and a Visibility widgets ? like this:
bool _isWebPageVisible = false;
Stack(
children: <Widget>[
MainWidget(),
Visibility(
visible: _isWebPageVisible,
child: WebPageWidget()
]
)
And you could change _isWebPageVisible whenever needed. When visible, the WebPageWidget will appear above the MainWidget.

Flutter: Changing Cards in Screen without rebuilding the whole page

I am pretty new to Flutter / Dart and right now, I have a problem. I have a homepage in my App and it displays an AppBar, a BottomNavigationBar and a body. The body is a simple card with content in it. The problem is: I need to be able to display three different cards, depending on the status I get from a server.
So there is the ActiveCard, the InactiveCard and the ErrorCard. The ErrorCard has a Button to go back to the InactiveCard and the ActiveCard as well as the InactiveCard should be wrapped in an Inkwell or similar to start a ride for example.
Now I am wondering: I am not sure how to implement all this. Can I just create three Stateless Widgets for each Card and depending on the server status just "replace" or "change" the body in my homepage? And where can I "control" the current status? Like I said, the Cards need to be clickable and "erase" themselves to make space for the following card (e.g: InactiveTrip gets clicked, now there should be the Card for ActiveTrip, because I started my trip and the user should see that my trip is currently active)
I cant provide code really, because so far I have not really something with will be even close to the result I expect.
Maybe you have some tips and packages I can use.
You can convert the statelessWidget to statefulWidget ans use setState() method.This is
recommended for small application but if your apps have more complexity then you have learn the state Management like provider,bloc pattern or Mvvm architechture.
yes, you can use statelessWidget for this purpose.
and you can use bloc pattern
to manage the page state.
I will use stateless for page and stream for the card content:
//Card model is your data modal
StreamController<Card> _streamController = StreamController();
Card _currentCard = /* default inactivate */;
StreamBuilder<bool>(
stream: _streamController.stream,
initialData: _currentCard,
builder: (BuildContext context, AsyncSnapshot<Card> snapshot) {
//return Container(/*content of your card*/);
},
),
//Everytime you need to change the card content, you sink the new value
_streamController.sink.add(_currentCard = /*new card data modal*/);

Creating a Flutter Alert/Dialog Without Context

I currently have a Flutter app which keeps track of the amount of time a user spends on the app with a timer which runs in the background. Users can set limits on the amount of time they spend in the app. Every minute, the timers checks if the user has exceeded their time limit. If so, I want to display a dialog or alert telling the user this.
The problem is that the timer has no way to access the current context and thus no way to create my dialog. Is there a way to get around this?
There is a package that enables you show dialogs with no need BuildContext from business layer. It's called OneContext.
That package also works with page navigation, overlays and other things with no need BuildContext.
Take a look at: https://pub.dev/packages/one_context
Use example:
// example dialog
OneContext().showDialog(
// barrierDismissible: false,
builder: (_) => AlertDialog(
title: new Text("The Title"),
content: new Text("The Body"),
)
);
// example snackBar
OneContext().showSnackBar(
builder: (_) => SnackBar(content: Text('My awesome snackBar!'))
);
You can achieve that by creating a custom Dialog Manager and a locator.
You can read the full tutorial here : https://medium.com/flutter-community/manager-your-flutter-dialogs-with-a-dialog-manager-1e862529523a
There is a package for it called Stacked_services
It provides: NavigationService, DialogService and SnackbarService.