Disabling FloatingActionButton after list view and showing a message that the limit is exceeded - flutter

How can I disable a button, in this case a FAB(Floating Action Button), and prevent the user adding more items to the list because he is exceeding the limit and showing a message? I'm using a FutureBuilder and a ListView.builder, after the user adds 3 item to the list, I want to disable the FAB and prevent the user to add more items to the list and showing some sort of notification/message/floating over button message to the user that he is exceeding the limit of 3 items per list. Here is the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'screens/add_items_screen.dart';
import 'components/items_list.dart';
class ItemScreen extends StatelessWidget {
static const String id = 'item_screen';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.grey[600],
),
),
/// I want to disable this button after the limit of 3 items in the list view
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.grey,
child: Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: AddItemScreen(),
)));
},
),
body: SafeArea(
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(20.0),
color: Colors.grey[100],
child: Container(
height: 800,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Item List Display',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.w700,
),
),
SizedBox(
height: 20.0,
),
Expanded(
child: Column(
children: [
/// Here is where the items are rendered as a list
Expanded(child: ItemList()),
],
),
),
],
),
),
),
),
),
);
}
}
The Item list component:
import 'package:flutter/material.dart';
import 'common/api/api_caller.dart';
import 'utilities/item_api_helper.dart';
import 'models/item.dart';
import 'stores/item_store.dart';
import 'dart:async';
import 'package:provider/provider.dart';
class ItemList extends StatefulWidget {
#override
_ItemList createState() => _ItemList();
}
class _ItemList extends State<ItemList> {
Future<HTTPResponse<List<ItemData>>> _getItemList() async {
var _itemData = await APICaller.instance.getItems();
var provider = Provider.of<ItemDatStore>(context, listen: false);
provider.setItemList(_itemData.data, notify: false);
return _itemData;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: FutureBuilder<HTTPResponse<List<ItemData>>>(
future: _getItemList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Consumer<ItemDataStore>(
builder: (context, itemData, child) {
return ListView.builder(
itemCount: itemData.itemList.length,
itemBuilder: (context, index) {
ItemData items =
itemData.getItemByIndex(index);
return Card(
child: Container(
padding: EdgeInsets.all(10.0),
child: Text('items.title'),
),
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Container();
},
),
),
);
}
}
I've tried using an if statement where I can define if(itemData.itemList.length <3) it should return those three items, else {Text('Item limit of 3 is exceeded')} but I'm not sure if this is the right way or if I defined it right since I put it in the Item List component and I need to put it in the Item Screen. Thanks in advance for you help!

You can wrap your Floating action button with Visibility it hides and not woking anymore :)
Visibility(
visible: items.length > 3,
child : FAB here,
),

You can disable the FAB like this
onPressed: items.length < 3? addItemToList : null;
and addItemToList is
void addItemToList(){
// Do Something here
}

Related

Flutter : i want to pass (title,details,content) to details page display it in vertically in top of the details page?

eg: details about the questions ......................................................when i click to a gridview item i want to pass (title,details,content) to details page display in vertically in top of the details page but when i am pass the data not able to fetch the data in details page i created a constrctor in details page not able to set the data in text and image.
Home Page
----------
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'DetailsPage.dart';
var paddingBottom = 48.0;
class HomePage extends StatelessWidget {
final String apiUrl = "https://www.sofikart.com/MobileApi/banners";
final String apiUrl1 =
"https://wayindia.net/indigo/odia_rashifal/rasifhala.php";
Future<List<dynamic>> fetchUsers() async {
var result = await http.get(Uri.parse(apiUrl1));
return json.decode(result.body)['data'];
}
String id(dynamic user) {
return user['id'];
}
String title(dynamic user) {
return user['title'];
}
String content(dynamic user) {
return user['content'];
}
String eng_title(dynamic user) {
return user['eng_title'];
}
String main_img(dynamic user) {
return user['main_img'];
}
String image_2(dynamic user) {
return user['image_2'];
}
String image_3(dynamic user) {
return user['image_3'];
}
String image_4(dynamic user) {
return user['image_4'];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ଆଜିର ରାଶିଫଳ'),
centerTitle: true,
),
body: Container(
child: FutureBuilder<List<dynamic>>(
future: fetchUsers(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
print(id(snapshot.data[0]));
return GridView.builder(
itemCount: snapshot.data.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 20,
mainAxisSpacing: 25,
),
padding: EdgeInsets.all(13),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return InkWell(
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(12))),
child: Column(
children: [
Expanded(
flex: 9,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(12)),
child: Image.network(
snapshot.data[index]['main_img'],
fit: BoxFit.fill)),
),
Expanded(
flex: 2,
child: Text(
title(snapshot.data[index]),
style: TextStyle(
color: Colors.black, fontSize: 17),
)),
],
),
),
onTap: () {
print("Click event on Container");
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => DetailsPage()), (route) => false);
},
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}
Details Page
------------
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:odia_rasiphala/HomePage.dart';
import 'dart:convert';
class DetailsPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: new Scaffold(
appBar: new AppBar(
title: new Text('ଆଜିର ରାଶିଫଳ'),
leading: new IconButton(
icon: new Icon(Icons.arrow_back_outlined),
onPressed: () => Navigator.pushReplacement(context,
new MaterialPageRoute(builder: (context) => HomePage())),
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(Icons.share),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image.network(
'',
width: 200.0,
height: 200.0,
),
new Center(
child: new Text('',style: TextStyle(
color: Colors.black,fontSize: 17
)),
)
],
),
));
}
}
I am guessing you want to pass "eng_title" and "main_img" to details screen.
To do that first make a constructor in your details pages. Example:
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({Key? key, required this.eng_title, required this.main_img}) : super(key: key);
// Declare a field that holds the strings passed to this class.
final String eng_title;
final String main_img;
#override
Widget build(BuildContext context) {
// Use the final parameters to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(eng.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(main_img),
),
);
}
}
on your OnTap function, when you click an item on the list, just pass the required parameters like this
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(eng_title: snapshot.data[index]['eng_title'], main_img: snapshot.data[index]['main_img']),
),
);
},
This way you can pass data from onescreen to another. Do not use push and remove until, if you want the user to go back to the list in homepage.
For more info about passing data read the following article by flutter:
https://docs.flutter.dev/cookbook/navigation/passing-data

Flutter List View Builder Using API

I am able to fetch data from API and I can show it in the List View, but i want to show the first card as the latest updated data.
I tried to use the Reverse property of List View Builder, it some how solve my problem but gave rise to another problem. Now i need to scroll upward in order to see latest updated data.
Help me through it
I just want to show the latest updated data at the top and then scroll down to see another data.
Please Help Me.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class PromotersDetails extends StatefulWidget {
final String url,title;
PromotersDetails({Key key, #required this.url, #required this.title}) : super(key: key);
#override
_PromotersDetailsState createState() => _PromotersDetailsState(url,title);
}
class _PromotersDetailsState extends State<PromotersDetails> {
fetchSelfies() async {
var url1;
url1 = await http.get(Uri.parse(
url));
var res = json.decode(url1.body);
print(res);
return json.decode(url1.body)['selfies'];
}
String url,title;
_PromotersDetailsState(this.url, this.title);
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width * 0.6;
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: false,
title: Text(
title,
style: TextStyle(fontSize: 25.0, color: Colors.white),
),
elevation: 0.0,
backgroundColor: Colors.green,
),
body: FutureBuilder(
future: fetchSelfies(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
}
if (snapshot.hasData) {
return ListView.builder( **// List View Builder**
reverse: false,
cacheExtent: 10000.00,
itemCount: snapshot.data.length,
padding: EdgeInsets.all(8),
itemBuilder: (BuildContext context, int index) {
return Row(
children: [
Container(
height: 120,
alignment: Alignment.center,
child: Container(
height: 120,
width: 120,
child: Card(
child: Image.network(snapshot.data[index]['image']),
),
),
),
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 10,
),
Row(
children: [
Text(
"Time: ",
style: TextStyle(color: Colors.black),
),
Text(
snapshot.data[index]['time'],
style: TextStyle(color: Color(0xff868597)),
),
],
),
Container(
height: 50,
child: Text(
snapshot.data[index]['location'],
style: TextStyle(color: Color(0xff868597)),
),
),
],
),
),
),
],
);
},
);
}
return Center(
child: CircularProgressIndicator(),
);
})
);
}
}
If you just need to sort the API response backwards, you can use the reverse property of ListView.
ListView.builder(
reverse: true,
...
),
If the way you're populating the ListView is by appending new data, then it's better to store the data on a List then do sort/reversed. Though the sorting should be best done at the backend instead of passing the burden to the client app.

Flutter - Returning to previous page from AppBar is not refreshing the page, with Navigator.pop(context)

I was trying to get the list page refreshed if a method was run on another page. I do pass the context using the push navigation.
I tried to follow these 3 answers Answer 1 Answer 2 and Answer 3 and I am not able to manage the states here.
This is the first list page which needs to be refreshed. It calls a class
class _PageLocalState extends State<PageLocal> {
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: SafeArea(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: widget.allLocal.length,
//padding: const EdgeInsets.only(top: 10.0),
itemBuilder: (context, index) {
return LocalCard(widget.allLocal[index]);
},
)),
)
],
),
);
}
}
The next class:
class LocalCardState extends State<LocalCard> {
FavData localdet;
LocalCardState(this.localdet);
ListTile makeListTile() => ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
title: Text(
localdet.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(localdet.loc),
trailing: Icon(Icons.keyboard_arrow_right, size: 30.0),
onTap: () => navigateToDetail(localdet),
);
Widget get localCard {
return new Card(
elevation: 4.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Container(
child: makeListTile(),
));
}
#override
Widget build(BuildContext context) {
return new Container(
child: localCard,
);
}
navigateToDetail(FavData localdet) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavouriteDetailPage(
mndet: localdet,
)));
setState(() {});
}
}
Now this is routing to the final detail page:
class _FavouriteDetailPageState extends State<FavouriteDetailPage> {
bool isFav = false;
FavData mndet;
_FavouriteDetailPageState(this.mndet);
// reference to our single class that manages the database
final dbHelper = DatabaseHelper.instance;
#override
Widget build(BuildContext context) {
Widget heading = new Container(...);
Widget middleSection = new Expanded(...);
Widget bottomBanner = new Container(...);
Widget body = new Column(...);
final makeBottom = Container(
height: 55.0,
child: BottomAppBar(
color: Color.fromRGBO(36, 36, 36, 1.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new FavIconWidget(mndet),
],
),
),
);
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('The Details'),
backgroundColor: Color.fromRGBO(36, 36, 36, 1.0),
),
body: Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.white70, width: 1),
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.all(20.0),
child: Padding(
padding: new EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
child: body,
),
),
),
bottomNavigationBar: makeBottom,
);
}
void share(BuildContext context, FavData mndet) {
final RenderBox box = context.findRenderObject();
final String shareText = "${mndet.name} - ${mndet.desc}";
Share.share(shareText,
subject: mndet.loc,
sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
}
}
class FavIconWidget extends StatefulWidget {
final FavData mnforIcon;
FavIconWidget(this.mnforIcon);
#override
_FavIconWidgetState createState() => _FavIconWidgetState();
}
class _FavIconWidgetState extends State<FavIconWidget> {
final dbHelper = DatabaseHelper.instance;
Future<bool> get isFav async {
final rowsPresent = await dbHelper.queryForFav(widget.mnforIcon.id);
if (rowsPresent > 0) {
print('Card Loaded - Its Favourite already');
return false;
} else {
print('Card Loaded - It is not favourite yet');
return true;
}
}
void _insert() async {...}
void _delete() async {...}
#override
Widget build(BuildContext context) {
return FutureBuilder<bool>(
future: isFav,
initialData:
false, // you can define an initial value while the db returns the real value
builder: (context, snapshot) {
if (snapshot.hasError)
return const Icon(Icons.error,
color: Colors.red); //just in case the db return an error
if (snapshot.hasData)
return IconButton(
icon: snapshot.data
? const Icon(Icons.favorite_border, color: Colors.white)
: Icon(Icons.favorite, color: Colors.red),
onPressed: () => setState(() {
if (!snapshot.data) {
print('Its favourite so deleting it.');
_delete();
} else {
print('Wasnt fav in the first place so inserting.');
_insert();
}
}));
return CircularProgressIndicator(); //if there is no initial value and the future is not yet complete
});
}
}
I am sure this is just some silly coding I have done but just not able to find out. Where.
I tried adding Navigator.pop(context); in different sections of the detail page and it fails.
Currently, I have to navigate back to the Favourites list page and then HomePage and then back to Favourites ListPage to refresh the list.
try this.. Anywhere you are using Navigator.pop or Navigator.push .. Instead of this use this:
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => Password())
);
//instead of Password use the name of the page(the second page you want to go to)

Flutter Cannot show List item in Drawar

I am new to flutter.
I am trying to create list view dynamically using server response JSON data using futureBuilder. The code writen by me while wathing YouTube videos, but I can't understand what is the mistake.
//It looks like your post is mostly code; please add some more details.//
main.dart
import 'package:flutter/material.dart';
import 'home.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: home(),
));
}
home.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
class home extends StatefulWidget {
home({Key key}):super();
#override
homepage createState() =>new homepage();
}
class homepage extends State<home>{
Color theme = Colors.lightBlue;
Color theme_text = Colors.white;
Future<List<category>> _getCategory() async {
var data = await http
.get("https://next.json-generator.com/api/json/get/VJ6EHYFO_");
debugPrint(data.body);
var jsondata = json.decode(data.body);
List<category> list = [];
for (var u in jsondata) {
category c = category(u['name'], u['id']);
list.add(c);
}
return list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: theme,
title: Text('SIMS Home Page'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () => debugPrint("search pressed"),
)
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text(
"Not Signed",
textAlign: TextAlign.center,
style: TextStyle(color: theme_text, fontSize: 20),
),
decoration: BoxDecoration(
color: theme,
),
),
FutureBuilder(
future: _getCategory(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text(snapshot.data[index]),);
});
}
},
),
],
),
),
);
}
class category {
final name;
final id;
category(this.name, this.id);
}
You have to use shrinkwrap property of listView.builder to get it work. it will allow listview to grow only that much which is require.
Moreover, in text view you are assigning items directly you have to access name and id individually as shown in below code.
Container(
height: 150,
child: DrawerHeader(
child: Text(
"Not Signed",
textAlign: TextAlign.center,
style: TextStyle(color: theme_text, fontSize: 20),
),
decoration: BoxDecoration(
color: theme,
),
),
),
FutureBuilder(
future: _getCategory(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return Container(
height: MediaQuery.of(context).size.height - 150,
child: ListView.builder(
shrinkWrap: true, //added line
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(snapshot.data[index]
.toString()), //accessing name from json
);
}),
);
}
},
),

How to save downloaded data from an API to RAM in Flutter?

I'm writing a really simple app in Flutter, but I have a problem with state management.
Here's the video of what I have. Link: https://streamable.com/ir3ztr
The video shows my application, but when I switch a screen using Bottom Navigation Bar, the data loads again and again from the API. I don't want that. I want the once downloaded data to be saved in RAM and not being downloaded again from the API. Is that possible? I heard about Provider, but I don't know how to use that in my case.
Is there anyone who can help me?
My code:
World
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_placeholder_textlines/flutter_placeholder_textlines.dart';
import '../../models/world.dart';
import '../../data/world_service.dart';
class WorldScreenAndroid extends StatefulWidget {
#override
_WorldScreenAndroidState createState() => _WorldScreenAndroidState();
}
class _WorldScreenAndroidState extends State<WorldScreenAndroid> {
Future<World> futureWorld;
#override
void initState() {
super.initState();
futureWorld = fetchWorld();
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8.0),
child: FutureBuilder<World> (
future: futureWorld,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(
children: [
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('coronavirus_cases').tr(context: context),
subtitle: Text(NumberFormat('#,###,###', 'en_US').format(snapshot.data.cases).toString())
),
),
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('deaths').tr(context: context),
subtitle: Text(NumberFormat('#,###,###', 'en_US').format(snapshot.data.deaths).toString())
),
),
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('recovered').tr(context: context),
subtitle: Text(NumberFormat('#,###,###', 'en_US').format(snapshot.data.recovered).toString())
),
)
],
);
}
return ListView(
children: [
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('coronavirus_cases').tr(context: context),
subtitle: PlaceholderLines(
count: 1,
animate: true,
color: Colors.grey,
minWidth: 0.10,
maxWidth: 0.50,
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('deaths').tr(context: context),
subtitle: PlaceholderLines(
count: 1,
animate: true,
color: Colors.grey,
minWidth: 0.10,
maxWidth: 0.50,
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.public),
title: Text('recovered').tr(context: context),
subtitle: PlaceholderLines(
count: 1,
animate: true,
color: Colors.grey,
minWidth: 0.10,
maxWidth: 0.50,
),
),
)
],
);
},
)
);
}
}
Countries
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import '../../models/country.dart';
import '../../data/countries_service.dart';
class CountriesScreenAndroid extends StatefulWidget {
#override
_CountriesScreenAndroidState createState() => _CountriesScreenAndroidState();
}
class _CountriesScreenAndroidState extends State<CountriesScreenAndroid> {
Future<List<Country>> futureCountries;
#override
void initState() {
super.initState();
futureCountries = fetchCountries();
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8.0),
child: FutureBuilder(
future: futureCountries,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
TextField(),
SizedBox(height: 10.0),
Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final List<String> _countriesAllArgs = [
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].cases),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].todayCases),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].active),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].deaths),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].todayDeaths),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].recovered),
NumberFormat('#,###,###', 'en_US').format(snapshot.data[index].critical)
];
return Card(
child: Padding(
padding: EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
snapshot.data[index].country,
style: TextStyle(
fontSize: 18.0,
color: Colors.grey[600],
),
),
SizedBox(height: 6.0),
Text(
'countries_all',
style: TextStyle(
fontSize: 14.0,
color: Colors.grey[800],
),
).tr(args: _countriesAllArgs),
],
),
)
);
}
),
)
],
);
}
return Center(
child: CircularProgressIndicator(),
);
},
)
);
}
}
Make sure to keep the loaded data in a parent widget, not in the widget your switching.
Have you considered using the BLOC framework?
In that case, you could nicely sepearte Business Logic from UI code and keep the loaded data in the bloc.
In detail have a blocProvider on top, wrapping your app.
https://bloclibrary.dev/#/flutterbloccoreconcepts?id=blocprovider
Alternatively, but be carefull with the handling though, you can just create an object, anywhere outside of any widget, and access it from anywhere.
class Data {
List<String> stringsLoadedFromWeb;
}
Data data = Data();
// from anywhere else, where you import the above file
data.stringsLoadedFromWeb = ...