I'm new to flutter and I want to passe some data between screens.
I know a simular question was ask here but I try that solution but for my code did not work.
I try: "Passing data between screens in Flutter"
Search bar code:
import 'package:flutter/material.dart';
import 'Screen_4.dart';
class SearchList extends StatefulWidget {
SearchList({Key key}) : super(key: key);
#override
_SearchListState createState() => _SearchListState();
}
class _SearchListState extends State<SearchList> {
Widget appBarTitle = Text(
"Search ",
style: TextStyle(color: Colors.white),
);
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = TextEditingController();
List<String> _list;
bool _IsSearching;
String _searchText = "";
_SearchListState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_IsSearching = false;
_searchText = "";
});
} else {
setState(() {
_IsSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
#override
void initState() {
super.initState();
_IsSearching = false;
init();
}
void init() {
_list = List();
_list.add("Google");
_list.add("IOS");
_list.add("Andorid");
_list.add("Dart");
_list.add("Flutter");
_list.add("Python");
_list.add("React");
_list.add("Xamarin");
_list.add("Kotlin");
_list.add("Java");
_list.add("RxAndroid");
_list.add('Lenovo');
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: key,
appBar: buildBar(context),
body: ListView(
padding: EdgeInsets.symmetric(vertical: 8.0),
children: _IsSearching ? _buildSearchList() : _buildList(),
),
);
}
List<ChildItem> _buildList() {
return _list.map((contact) => ChildItem(contact)).toList();
}
List<ChildItem> _buildSearchList() {
if (_searchText.isEmpty) {
return _list.map((contact) => ChildItem(contact)).toList();
} else {
List<String> _searchList = List();
for (int i = 0; i < _list.length; i++) {
String name = _list.elementAt(i);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
return _searchList.map((contact) => ChildItem(contact)).toList();
}
}
Widget buildBar(BuildContext context) {
return AppBar(centerTitle: true, title: appBarTitle, actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = Icon(
Icons.close,
color: Colors.white,
);
this.appBarTitle = TextField(
controller: _searchQuery,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
prefixIcon: Icon(Icons.search, color: Colors.black),
hintText: "Search...",
hintStyle: TextStyle(color: Colors.white)),
);
_handleSearchStart();
} else {
_handleSearchEnd();
}
});
},
),
]);
}
void _handleSearchStart() {
setState(() {
_IsSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
this.actionIcon = Icon(
Icons.search,
color: Colors.white,
);
this.appBarTitle = Text(
"Search Sample",
style: TextStyle(color: Colors.white),
);
_IsSearching = false;
_searchQuery.clear();
});
}
}
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(this.name), //onTap: () => print(name));
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ShowData()));
},
);
}
}
The screen I want to to show the result:
import 'search_bar_no_API.dart';
class ShowData extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('The Name Here'),
),
What I want is the person to :
eg:
search: google
press: the name google
then go to other page with the name Google on the appbar.
In your ChildItem class do this:
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(this.name), //onTap: () => print(name));
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ShowData(title: this.name)));
},
);
}
}
you will notice, I passed in this.name to the property title of the ShowData class in the Navigator.push(...)
and so in your ShowData class, create a final variable of type String eg. final String title and create a Constructor of the class ShowData like this ShowData({this.title}). Below is a complete code of how the ShowDataclass should look like:
class ShowData extends StatelessWidget {
final String title;
ShowData({this.title});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text(title),
)
);
}
}
Related
I am trying to build a login page through firebase with the flutter framework but I have run into the problem of my screen resetting anytime I attempt to use the TextFormField, it'll load the keyboard, and then immediately kick me out and reset the page. I have looked on other threads but can't seem to find any fixes. Thanks for all the help in advance!
class SignInTwo extends StatefulWidget {
final Function toggleView;
SignInTwo({this.toggleView});
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignInTwo> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
bool loading = false;
// text fields state
String email = "";
String password = "";
String error = "";
#override
Widget build(BuildContext context) {
return loading ? Loading() : Scaffold(
backgroundColor: Colors.brown[100],
appBar: AppBar(
backgroundColor: Colors.brown[400],
elevation: 0.0,
title: Text('Sign in'),
actions: <Widget>[
FlatButton.icon(
label: Text("Register"),
icon: Icon(Icons.person),
onPressed: () {
widget.toggleView();
},
)
],
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
TextFormField(
decoration: textDecoration.copyWith(hintText: 'Email'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter email';
}
return null;
},
onChanged: (value) {
setState(() => email = value);
},
),
SizedBox(
height: 20.0,
),
TextFormField(
decoration: textDecoration.copyWith(hintText: 'Password'),
validator: (val) {
if (val.length < 6) {
return 'Enter password with more than 6+ characters';
}
return null;
},
onChanged: (value) {
setState(() => password = value);
},
obscureText: true,
),
SizedBox(
height: 20.0,
),
RaisedButton(
color: Colors.pink[400],
child: Text(
"Sign In",
style: TextStyle(color: Colors.white),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() {
loading = true;
});
dynamic result = await _auth.signInWithEmailAndPassword(
email, password);
if (result == null) {
setState(() {
error = "Something went wrong!!";
loading = false;
});
}
}
},
),
SizedBox(
height: 20,
),
Text(
error,
style: TextStyle(color: Colors.red),
)
],
),
)),
);
}
}
I am not sure if it is a problem with my main class or any of the others but I will leave them below just incase it might be the cause of the problem.
class MyApp extends StatefulWidget {
final SharedPreferences storage;
const MyApp({Key key, this.storage}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
fontFamily: "Audiowide",
primarySwatch: Colors.yellow,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Wrapper(),
);
}
}
This wrapper just decides if the user is already logged in or not. In my case it is not so it will return the Authenticate class.
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final player = Provider.of<Player>(context);
if(player == null){
return Authenticate();
}else{
return Home();
}
}
}
class Authenticate extends StatefulWidget {
#override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
bool showSignIn = true;
void toggleView() {
setState(() {
showSignIn = !showSignIn;
});
}
#override
Widget build(BuildContext context) {
if(showSignIn){
return SignInTwo(toggleView: toggleView);
}else{
return Register(toggleView: toggleView);
}
}
}
Every time you open keyboard the build function is called and check if its loading and create new Scaffold instance this the reason of your problem
you can fix it by adding key to Scaffold
something like this
Scaffold(key:scaffoldKey
...)
I am trying to find out about search navigation and could not find any suitable tutorial showing me how to navigate to specific pages after your search. I hope someone could explain me how I can do this.
After searching "Google" I would like to press on it and be redirected to a new page through navigation.
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
#override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
Widget appBarTitle = Text(
"Search",
style: TextStyle(color: Colors.white),
);
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = TextEditingController();
List<String> _list;
bool _isSearching;
String _searchText = "";
_SearchPageState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_isSearching = false;
_searchText = "";
});
} else {
setState(() {
_isSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
#override
void initState() {
super.initState();
_isSearching = false;
initData();
}
void initData() {
_list = List();
_list.add("google");
_list.add("IOS");
_list.add("Android");
_list.add("Linux");
_list.add("MacOS");
_list.add("Windows");
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: key,
appBar: buildBar(context),
body: new ListView(
padding: new EdgeInsets.symmetric(vertical: 8.0),
children: _isSearching ? _buildSearchList() : _buildList(),
),
);
}
List<ChildItem> _buildList() {
return _list.map((contact) => new ChildItem(contact)).toList();
}
List<ChildItem> _buildSearchList() {
if (_searchText.isEmpty) {
return _list.map((contact) => new ChildItem(contact))
.toList();
}
else {
List<String> _searchList = List();
for (int i = 0; i < _list.length; i++) {
String name = _list.elementAt(i);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
return _searchList.map((contact) => new ChildItem(contact))
.toList();
}
}
Widget buildBar(BuildContext context) {
return new AppBar(
centerTitle: true,
title: appBarTitle,
actions: <Widget>[
new IconButton(icon: actionIcon, onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close, color: Colors.white,);
this.appBarTitle = new TextField(
controller: _searchQuery,
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "search...",
hintStyle: new TextStyle(color: Colors.white)
),
);
_handleSearchStart();
}
else {
_handleSearchEnd();
}
});
},),
]
);
}
void _handleSearchStart() {
setState(() {
_isSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
this.actionIcon = new Icon(Icons.search, color: Colors.white,);
this.appBarTitle =
new Text("search", style: new TextStyle(color: Colors.white),);
_isSearching = false;
_searchQuery.clear();
});
}
}
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return new ListTile(title: new Text(this.name));
}
}
You can also do it with a SearchDelegate.
Query and navigation under the buildSuggestions.
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
The important part is pairing yourList's index with suggestionList index :
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index])))
Below is all the code with navigation.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Search Example"),
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: SearchItem());
}),
],
),
);
}
}
final List<String> myList = [
"google",
"IOS",
"Android",
"Linux",
"MacOS",
"Windows"
];
class SearchItem extends SearchDelegate<String> {
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
})
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
}
class DetailScreen extends StatelessWidget {
final int index;
DetailScreen(this.index);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("${myList[index]}"),),
body: Center(
child: Text(
"${myList[index]}",style: TextStyle(fontSize: 22),
),
));
}
}
Is there a way to set the value of a DropdownButtonFormField programatically?
I tried manipulating the value property, but it does no show any effect.
Example:
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget {
TestPage({Key key}) : super(key: key);
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
int _selectedId;
List<Item> _items = [];
#override
void initState() {
super.initState();
for (int i = 0; i < 5; i++) {
_items.add(Item(i, "choice " + i.toString()));
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: Column(
children: [
DropdownButtonFormField(
isExpanded: true,
items: _items.map((item) {
return new DropdownMenuItem(
value: item.id,
child: Text(item.text),
);
}).toList(),
onChanged: (value) {
setState(() => _selectedId = value);
},
value: _selectedId,
decoration: InputDecoration(
labelText: "select me",
),
),
RaisedButton(
child: Text('set selected'),
onPressed: () {
setState(() {
_selectedId = 3;
});
},
),
RaisedButton(
child: Text('get selected'),
onPressed: () {
print(_selectedId.toString());
},
)
],
),
);
}
}
class Item {
int id;
String text;
Item(this.id, this.text);
}
When setting _selectedId to 3 via the button, nothing happens, the dropdown does not update. If I set _selectedId to 3 on variable initialization, the third choice is selected when the page loads.
However I need it programatically.
I'm using a statefull widget to handle the length of my text. (show more, show less)
class DescriptionTextWidget extends StatefulWidget {
final String text;
DescriptionTextWidget({#required this.text});
#override
_DescriptionTextWidgetState createState() =>
new _DescriptionTextWidgetState();
}
class _DescriptionTextWidgetState extends State<DescriptionTextWidget> {
String firstHalf;
String secondHalf;
bool flag = true;
#override
void initState() {
super.initState();
if (widget.text.length > 400) {
firstHalf = widget.text.substring(0, 400);
secondHalf = widget.text.substring(400, widget.text.length);
} else {
firstHalf = widget.text;
secondHalf = "";
}
}
#override
Widget build(BuildContext context) {
return new Container(
padding: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: secondHalf.isEmpty
? new Text(firstHalf, style: TextStyle(color: Colors.white))
: new Column(
children: <Widget>[
new Text(
flag ? (firstHalf + "...") : (firstHalf + secondHalf),
style: TextStyle(color: Colors.white),
),
new InkWell(
splashColor: Colors.transparent,
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text(
flag ? "show more" : "show less",
style:
new TextStyle(color: Colors.white.withOpacity(0.8)),
),
],
),
onTap: () {
setState(() {
flag = !flag;
});
},
),
],
),
);
}
}
In my main class: I 'give' the text to that stfull widget like this:
GestureDetector(
onTap: () async {
},
child: DescriptionTextWidget(
text: myString,
),
If I update myString in my main statefull widget, the String doesn't get updated in the statefull widget 'DescriptionTextWidget'.
What's the best way to update the String in the class DescriptionTextWidget?
Thanks in advance!
Sample on DartPad
class DescriptionTextWidget extends StatefulWidget {
final ValueNotifier<String> text;
}
class _DescriptionTextWidgetState extends State<DescriptionTextWidget> {
#override
void initState() {
super.initState();
widget.text.addListener(() => setState(initText));
initText();
}
initText() {
if (widget.text.value.length > 400) {
firstHalf = widget.text.value.substring(0, 400);
secondHalf = widget.text.value.substring(400, widget.text.value.length);
} else {
firstHalf = widget.text.value;
secondHalf = "";
}
}
}
main class:
ValueNotifier<String> myString;
updateString(String value){
myString.value = value;
}
import 'package:flutter/material.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 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;
List<String> myString = ["test"];
void _replace() {
setState(() {
myString[0] = "tapped";
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: DescriptionTextWidget(
text: myString,
),
),
floatingActionButton: FloatingActionButton(
onPressed: _replace,
child: Icon(Icons.autorenew),
),
);
}
}
class DescriptionTextWidget extends StatefulWidget {
final List<String> text;
DescriptionTextWidget({#required this.text});
#override
_DescriptionTextWidgetState createState() =>
new _DescriptionTextWidgetState();
}
class _DescriptionTextWidgetState extends State<DescriptionTextWidget> {
bool flag = true;
#override
Widget build(BuildContext context) {
String firstHalf;
String secondHalf;
if (widget.text[0].length > 400) {
firstHalf = widget.text[0].substring(0, 400);
secondHalf = widget.text[0].substring(400, widget.text[0].length);
} else {
firstHalf = widget.text[0];
secondHalf = "";
}
return new Container(
padding: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: secondHalf.isEmpty
? new Text(firstHalf, style: TextStyle(color: Colors.black))
: new Column(
children: <Widget>[
new Text(
flag ? (firstHalf + "...") : (firstHalf + secondHalf),
style: TextStyle(color: Colors.black),
),
new InkWell(
splashColor: Colors.transparent,
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text(
flag ? "show more" : "show less",
style:
new TextStyle(color: Colors.black.withOpacity(0.8)),
),
],
),
onTap: () {
setState(() {
flag = !flag;
});
},
),
],
),
);
}
}
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.