Can't get data from api - flutter

While I am passing value from home page in API page after applying logic how I am not getting data in my result variable. What I am doing wrong?
Here is my home page where I passes the value -
import 'package:flutter/material.dart';
import 'sourceScreen.dart';
import 'models/API.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value=0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =1;
API(value: value);
});
},
child:Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =0;
API(value: value);
});
},
child:Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
Here is my API page where I wanna use that value with some logic which is given below hope u will understand-
import 'model.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class API{
int value;
API({this.value});
Future<List<Source>> fetchNewsSource() async {
final world ='https://newsapi.org/v2/sources?apiKey=';
final india = 'https://newsapi.org/v2/sources?language=en&country=in&apiKey=';
String result;
void logic(){
if(value==1){
result = india;
}
else if(value==0){
result = world;
}
}
final response = await http.get(result);
if (response.statusCode == 200) {
List sources = json.decode(response.body)['sources'];
return sources.map((source) => new Source.formJson(source)).toList();
} else {
throw Exception('Fail to load data');
}
}
}
Here is home page -
import 'package:flutter/material.dart';
import 'sourceScreen.dart';
import 'models/API.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value=0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =1;
API(value: value);
});
},
child:Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =0;
API(value: value);
});
},
child:Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
Source screen
import 'package:flutter/material.dart';
import 'models/model.dart';
import 'models/card.dart';
import 'article.dart';
import 'models/API.dart';
class SourceScreen extends StatefulWidget {
SourceScreen(Map<int, int> map);
#override
_SourceScreenState createState() => _SourceScreenState();
}
class _SourceScreenState extends State<SourceScreen> {
var list_source;
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
refreshListSource();
}
Future<Null> refreshListSource() async {
API api = new API();
refreshKey.currentState?.show(atTop: false);
setState(() {
list_source = api.fetchNewsSource();
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
appBar: AppBar(
elevation: 1.0,
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
title: Text('uTTerNews'),
),
body: Center(
child: RefreshIndicator(
child: FutureBuilder<List<Source>>(
future: list_source,
builder: (context, snapshot) {
if (snapshot.hasError) {
Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
List<Source> sources = snapshot.data;
return new ListView(
children: sources
.map((source) =>
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
articleScreen(source: source,)));
},
child: card(source),
))
.toList());
}
return CircularProgressIndicator();
},
),
onRefresh: refreshListSource),
),
),
);
}
}

Output:
Try this full code:
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: () async {
value = 1;
List list = await API(value: value).fetchNewsSource();
Navigator.push(context, MaterialPageRoute(builder: (context) => SourceScreen(list)));
},
child: Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: () async {
value = 0;
List list = await API(value: value).fetchNewsSource();
Navigator.push(context, MaterialPageRoute(builder: (context) => SourceScreen(list)));
},
child: Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
class API {
int value;
API({#required this.value});
Future<List<dynamic>> fetchNewsSource() async {
final world = 'https://newsapi.org/v2/sources?apiKey=$apiKey';
final india = 'https://newsapi.org/v2/sources?language=en&country=in&apiKey=$apiKey';
String result;
if (value == 1)
result = india;
else if (value == 0) result = world;
final response = await http.get(result);
if (response.statusCode == 200) {
List sources = json.decode(response.body)['sources'];
return sources;
} else {
throw Exception('Fail to load data');
}
}
}
class SourceScreen extends StatefulWidget {
final List list;
SourceScreen(this.list);
#override
_SourceScreenState createState() => _SourceScreenState();
}
class _SourceScreenState extends State<SourceScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Channels")),
body: ListView(
children: widget.list.map((map) => ListTile(title: Text(map["name"]))).toList(),
),
);
}
}

Related

setState() not updating UI elements even though the state variable, a Future, is updated?

I have a HomePage screen which has a FutureBuilder List implemented with a Future function as the state variable. I am updating this Future in another dart file by using keys to access the future. The Future gets updated and I'm sure of this as I've seen the print statements, but when I call the setState method, the UI doesn't show the newly added entry.
Here's my HomePage.dart:
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
Future<List<Model>> getData() async {
return await DatabaseHelper.instance.getModels();
}
Future? userFuture;
#override
void initState() {
super.initState();
userFuture = getData();
print(userFuture);
}
#override
Widget build(BuildContext context) {
print('Building listview');
return Center(
child: FutureBuilder<List<Model>>(
future: userFuture as Future<List<Model>>,
builder: ((context, AsyncSnapshot<List<Model>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
if (snapshot.data!.isEmpty) {
return Text('No data present');
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: ((context, index) {
return MyCard(
key: ValueKey(snapshot.data![index].id),
snapshot.data![index].id,
snapshot.data![index].title,
snapshot.data![index].purpose);
}),
);
}
return Text('data');
}
}),
),
);
}
}
Here's my other dart file. Under the AddEntryState I'm updating the Future state variable and then right after calling the setState method.
class RootPage extends StatefulWidget {
const RootPage({super.key});
#override
State<RootPage> createState() => RootPageState();
}
class RootPageState extends State<RootPage> {
static final GlobalKey<HomePageState> homepageKey =
GlobalKey<HomePageState>();
int currentPage = 0;
List<Widget>? pages;
#override
void initState() {
super.initState();
pages = [
HomePage(key: homepageKey),
StatsPage(),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App Title'),
),
body: pages?[currentPage],
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddEntry()));
},
child: Icon(Icons.add),
),
bottomNavigationBar: NavigationBar(
destinations: [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.data_usage), label: 'Stats'),
],
onDestinationSelected: (int index) {
setState(() {
currentPage = index;
print(index);
});
},
selectedIndex: currentPage,
),
);
}
}
class AddEntry extends StatefulWidget {
const AddEntry({super.key});
#override
State<AddEntry> createState() => _AddEntryState();
}
class _AddEntryState extends State<AddEntry> {
final GlobalKey<FormState> _key = GlobalKey<FormState>();
Map<String, String?> formField = <String, String?>{};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Entry'),
),
body: Form(
key: _key,
child: Column(
children: [
Flexible(
child: MyTextField('Title', callback),
),
Flexible(
child: MyTextField('Purpose', callback),
),
Flexible(
child: MyTextField('Password', callback, obscure: true),
),
TextButton(
onPressed: () async {
if (_key.currentState!.validate()) {
_key.currentState?.save();
formField.forEach((label, value) => print('$label = $value'));
await DatabaseHelper.instance.insertModel(Model(
id: null,
title: formField['Title'],
purpose: formField['Purpose'],
lastAccess: DateTime.now().toString(),
dateAdded: DateTime.now().toString(),
password: formField['Password']));
print(await DatabaseHelper.instance.getModels());
// await DatabaseHelper.instance.deleteAllData();
// print(await DatabaseHelper.instance.getModels());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Data Saved!'),
action: SnackBarAction(
label: 'Edit',
onPressed: () {
print('edit pressed!');
},
),
),
);
Navigator.pop(context);
print("HomePage userFuture: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
print("getData function: ");
print(RootPageState.homepageKey.currentState!
.getData()
.then((result) => print(result)));
print("New Future: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
setState(() {
RootPageState.homepageKey.currentState!.userFuture =
RootPageState.homepageKey.currentState!.getData();
});
//add logic to rebuild home screen after every addition of entry
}
},
child: Text('Submit'),
),
],
),
),
);
}
callback(varLabel, varValue) {
formField[varLabel] = varValue;
}
}

Flutter build not behaving as expected

I'm trying to make a note app but there is a yellow square showing on the screen.
I've included the main.dart code and also allnotesscreens.dart. I think there is something wrong with allnotesscreens code, but I don't know what.
Maybe _loadViewMode() part.
Why this problem is happening?!!!
Main.dart:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'providers/label_provider.dart';
import 'providers/note_provider.dart';
import 'package:provider/provider.dart';
import 'constants/app_constants.dart';
import 'screens/all_labels_screen.dart';
import 'screens/all_notes_screen.dart';
import 'screens/drawer_screen.dart';
main() {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: ColorsConstant.grayColor,
),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => NoteProvider()),
ChangeNotifierProvider(create: (_) => LabelProvider()),
],
builder: (context, child) => MaterialApp(
title: 'Note-App',
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.dark,
theme: customThemeData(context),
initialRoute: '/',
routes: {
'/': (context) => const AllNotesScreen(),
DrawerScreen.routeName: (context) => const DrawerScreen(),
AllLabelsScreen.routeName: (context) => const AllLabelsScreen(),
},
),
);
}
}
allnotesscreens.dart:
class AllNotesScreen extends StatefulWidget {
const AllNotesScreen({Key? key}) : super(key: key);
#override
State<AllNotesScreen> createState() => _AllNotesScreenState();
}
class _AllNotesScreenState extends State<AllNotesScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:
Container(
height: 200,
width: 100,
color: Colors.yellow,
),
),
);
}
String _viewMode = ViewMode.staggeredGrid.name;
bool _isLoading = false;
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState() {
super.initState();
setState(() {
_isLoading = true;
});
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
Future _loadViewMode() async {
final prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('view-mode')) return;
setState(() {
_viewMode = prefs.getString('view-mode') ?? ViewMode.staggeredGrid.name;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text(
"all notes",
style: TextStyleConstants.titleAppBarStyle,
),
actions: [
if (context
.watch<NoteProvider>()
.items
.isNotEmpty)
IconButton(
onPressed: () {
showSearch(
context: context,
delegate: NoteSearch(isNoteByLabel: false),
);
},
icon: const Icon(Icons.search),
),
IconButton(
onPressed: () async {
final result = await changeViewMode(_viewMode);
setState(() {
_viewMode = result;
});
},
icon: _viewMode == ViewMode.staggeredGrid.name
? const Icon(Icons.view_stream)
: const Icon(Icons.grid_view),
),
const SizedBox(
width: 6,
)
],
),
drawer: const DrawerScreen(),
body: _isLoading
? const Center(
child: CircularProgressIndicator(),
)
: RefreshIndicator(
onRefresh: () => refreshOrGetData(context),
child: Consumer<NoteProvider>(
builder: (context, noteProvider, child) =>
noteProvider.items.isNotEmpty
? NoteListViewWidget(
notes: noteProvider.items,
viewMode: _viewMode,
scaffoldContext: _scaffoldKey.currentContext!,
)
: child!,
child: const NoNoteUIWidget(
title: "your notes after adding will appear here",
),
),
),
floatingActionButton: FloatingActionButton(
child: linearGradientIconAdd,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const EditNoteScreen(),
));
},
),
);
}
}
}
The first few lines of your _AllNotesScreenState class are why there's a yellow square; that's what you're telling it to build.
class _AllNotesScreenState extends State<AllNotesScreen> {
// this build function here is what is drawing to the screen
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:
Container(
height: 200,
width: 100,
color: Colors.yellow,
),
),
);
}
Maybe it's just how you've pasted it in, but it appears as though you have a build function defined within the didChangeDependencies function. If you took it out of there, it would then make it apparent that you have two build functions defined for the class.
I'm assuming it's the second one that you actually want building.
#override
void didChangeDependencies() {
super.didChangeDependencies();
Future _loadViewMode() async {
final prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('view-mode')) return;
setState(() {
_viewMode = prefs.getString('view-mode') ?? ViewMode.staggeredGrid.name;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
...

Switch toggle between time format (am/pm and 24H) from settings page

i want to have switch widget in settings page. i can figured switching theme using switch widget, but this is too complicated
my main_page:
import 'package:intl/intl.dart';
Column(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Text("Summary"),
),
SizedBox(height: 45),
_time24(snapshot), //show this if switch is off
_time12(snapshot), //show this if switch is on
],
)
Widget _time12(AsyncSnapshot snapshot){
return Column(
children: <Widget>[
_time(Icons.home, Text(DateFormat("hh:mma").format(DateFormat("HH:mm").parse(snapshot.data.home)))),
_time(Icons.work, Text(DateFormat("hh:mma").format(DateFormat("HH:mm").parse(snapshot.data.work)))),
_time(Icons.restaurant, Text(DateFormat("hh:mma").format(DateFormat("HH:mm").parse(snapshot.data.restaurant)))),
]);
}
Widget _time24(AsyncSnapshot snapshot){
return Column(
children: <Widget>[
_time(Icons.home, Text(snapshot.data.home)),
_time(Icons.work, Text(snapshot.data.work)),
_time(Icons.restaurant, Text(snapshot.data.restaurant)),
]);
}
Thank you for your time :)
You can copy paste run full code below
You can await Navigator.push then call setState()
code snippet
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => Setting()),
);
setState(() {});
}
...
else if (snapshot.hasData) {
if (is24) {
return _time24(snapshot);
} else {
return _time12(snapshot);
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class Payload {
String home;
String work;
String restaurant;
Payload({this.home, this.work, this.restaurant});
}
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;
Future _future;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget _time12(AsyncSnapshot snapshot) {
var a = DateFormat("HH:mm").parse(snapshot.data.home);
print("a ${a}");
return Column(children: <Widget>[
_time(
Icons.home,
Text(DateFormat("hh:mma")
.format(DateFormat("HH:mm").parse(snapshot.data.home)))),
_time(
Icons.work,
Text(DateFormat("hh:mma")
.format(DateFormat("HH:mm").parse(snapshot.data.work)))),
_time(
Icons.restaurant,
Text(DateFormat("hh:mma")
.format(DateFormat("HH:mm").parse(snapshot.data.restaurant)))),
]);
}
Widget _time24(AsyncSnapshot snapshot) {
return Column(children: <Widget>[
_time(Icons.home, Text(snapshot.data.home)),
_time(Icons.work, Text(snapshot.data.work)),
_time(Icons.restaurant, Text(snapshot.data.restaurant)),
]);
}
Widget _time(IconData iconData, Text _text) {
return ListTile(
leading: Icon(iconData),
title: _text,
);
}
Future<Payload> getData() {
print("getData");
return Future.value(
Payload(home: "18:00", restaurant: "13:00", work: "08:00"));
}
#override
void initState() {
// TODO: implement initState
_future = getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FutureBuilder<Payload>(
future: _future,
builder: (BuildContext context, AsyncSnapshot<Payload> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Press button to start.');
case ConnectionState.active:
case ConnectionState.waiting:
return Text('Awaiting result...');
case ConnectionState.done:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else if (snapshot.hasData) {
if (is24) {
return _time24(snapshot);
} else {
return _time12(snapshot);
}
}
}
return null; // unreachable
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => Setting()),
);
setState(() {});
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
bool is24 = true;
class Setting extends StatefulWidget {
#override
_SettingState createState() => _SettingState();
}
class _SettingState extends State<Setting> {
void _changed(value) {
setState(() {
is24 = value;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Container(
child: Switch(
value: is24,
onChanged: _changed,
)));
}
}

Flutter Shared Preferences acces in other class

In the following class I have created a ListView of Strings which are stored sing shared preferences. Now I need to access the content of List<String> categoryList in another class. I do not know where to implement a get function to give other classes access to this List.
One Idea was to create a class for the List (But I dont want to mess up everything)
That is my Class with the List View
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Categories extends StatefulWidget {
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
List<String> categoryList = List<String>();
TextEditingController _textFieldController = TextEditingController();
#override
Widget build(BuildContext context) {
_update();
return Scaffold(
appBar: AppBar(
title: Text("Categories"),
),
body: SafeArea(
child: Container(
color: Colors.white,
child: getCategoriesListView(),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
_displayDialog(context);
});
},
),
);
}
ListView getCategoriesListView() {
return ListView.builder(
itemCount: categoryList.length,
itemBuilder: (context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(categoryList[position]),
trailing: GestureDetector(
child: Icon(
Icons.delete,
color: Colors.grey,
),
onTap: () {
setState(() {
_delete(context, categoryList[position]);
});
},
),
),
);
});
}
void _add(BuildContext context, String category) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
categoryList.add(category);
prefs.setStringList('Categories', categoryList);
}
void _delete(BuildContext context, String category) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
categoryList.remove(category);
prefs.setStringList('Categories', categoryList);
}
void _update() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
categoryList = prefs.getStringList('Categories');
});
}
void showSnackBar(BuildContext context, String message) async {
final snackBar = SnackBar(content: Text(message));
Scaffold.of(context).showSnackBar((snackBar));
}
_displayDialog(BuildContext context) async {
_textFieldController.clear();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Add new category'),
content: TextField(
controller: _textFieldController,
),
actions: <Widget>[
FlatButton(
child: Text('ADD'),
onPressed: () {
setState(() {
String name = _textFieldController.text;
_add(context, name);
Navigator.of(context).pop();
});
},
),
FlatButton(
child: Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
}
Second Class
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MonthlyOverview extends StatefulWidget {
#override
_MonthlyOverviewState createState() => _MonthlyOverviewState();
}
class _MonthlyOverviewState extends State<MonthlyOverview> {
List<String> _categories = new List<String>();
#override
Widget build(BuildContext context) {
_getCategory().then((value) {
_categories = value;
});
print(_categories);
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.white,
),
);
}
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
}
Console output
I/flutter (13417): []
#Frederik, have you tried implementing a get function in your second class and accessing the list? It could be something like this in your second class,
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
Call (depends on where you're calling it but this should give you an idea):
List<String> _categories = new List<String>();
_getCategory().then((value) {
_categories = value;
});
//Your _categories has the value now , use it here.
Full code:
void main() {
runApp(MaterialApp(
home: new MyApp(),
routes: <String, WidgetBuilder>{
"/monthlyOverview" : (BuildContext context)=> new MonthlyOverview(),
//add more routes here
}
));
}
class MyApp extends StatefulWidget {
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: Center(
child: FlatButton(
child: Text('Next', style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),),
onPressed: () async {
List<String> categoryList = ['Item 1', 'Item 2', 'Item 3'];
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList('Categories', categoryList);
Navigator.of(context).pushNamed("/monthlyOverview");
},
)
)
),
);
}
}
class MonthlyOverview extends StatefulWidget {
#override
_MonthlyOverviewState createState() => _MonthlyOverviewState();
}
class _MonthlyOverviewState extends State<MonthlyOverview> {
List<String> _categories = new List<String>();
#override
void initState() {
super.initState();
_getCategory().then((value) {
_categories = value;
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.white,
child: _categories.length > 0 ? Text(_categories[0] + '\n' + _categories[1] + '\n' + _categories[2], style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),) : Text(''),
)
),
);
}
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
}
Hope this helps.

error: The argument type 'Future' can't be assigned to the parameter type 'void Function()'

While I am passing value from home page to source page it shows an error: The argument type 'Future' can't be assigned to the parameter type 'void Function()'. (argument_type_not_assignable at [strong text]
lib\home.dart:15)
Where I am doing wrong??
Home page -
import 'package:flutter/material.dart';
import 'sourceScreen.dart';
class Home extends StatefulWidget {
int value;
Home({this.value});
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FlatButton(
onPressed: Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({value:value}))), child: null,
),
),
);
}
}
Below page is where I wanna use home page value-
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'models/model.dart';
import 'models/card.dart';
import 'article.dart';
final API_KEY = '***';
Future<List<Source>> fetchNewsSource() async {
final response = await http.get(
'https://newsapi.org/v2/sources?language=en&country=in&apiKey=$API_KEY');
if (response.statusCode == 200) {
List sources = json.decode(response.body)['sources'];
return sources.map((source) => new Source.formJson(source)).toList();
} else {
throw Exception('Fail to load data');
}
}
class SourceScreen extends StatefulWidget {
#override
_SourceScreenState createState() => _SourceScreenState();
}
class _SourceScreenState extends State<SourceScreen> {
var list_source;
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
refreshListSource();
}
Future<Null> refreshListSource() async {
refreshKey.currentState?.show(atTop: false);
setState(() {
list_source = fetchNewsSource();
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
appBar: AppBar(
elevation: 1.0,
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
title: Text('uTTerNews'),
),
body: Center(
child: RefreshIndicator(
child: FutureBuilder<List<Source>>(
future: list_source,
builder: (context, snapshot) {
if (snapshot.hasError) {
Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
List<Source> sources = snapshot.data;
return new ListView(
children: sources
.map((source) =>
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
articleScreen(source: source,)));
},
child: card(source),
))
.toList());
}
return CircularProgressIndicator();
},
),
onRefresh: refreshListSource),
),
),
);
}
}
Replace
onPressed: Navigator.push(...)
with
onPressed: () => Navigator.push(...)
If you need to use await keyword, you can do
onPressed: () async {
await Navigator.push(...);
await anyOtherMethod();
}
This one worked for me in latest versions
onPressed: () {
selectHandler();
},
#CopsOnRoad -- Here is the sample code that is working for me.
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.grey,
textColor: Colors.black,
child: Text('Answer 1'),
**onPressed: () => selectHandler()**,
),
);
}
}
simply change the final Function selectHandler to final VoidCallback selectHandler;