Flutter/Dart Android App NoSuchMethodError - android

I got a quick question about a flutter/dart app I am making throwing this certain error.
It has something to do with my showadddialog class. When I press the flatbutton with the text "save" in _showAddDialog() it works fine but my app crashes if I tap out of the alert dialog window without entering anything or if I press the flatbutton named "delete", and both actions give the same error. however, when I restart I can see that the delete button still worked to delete the events from the shared preferences, it just crashed afterward. What could be causing this in my code? Idk where it could be calling a map on null...
Screenshot reference: https://gyazo.com/f894ae742ea50cd714026b1bbe753678
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building HomePage(dirty, dependencies: [_LocalizationsScope-[GlobalKey#42494], _InheritedTheme], state: _HomePageState#acde6):
The method 'map' was called on null.
Receiver: null
Tried calling: map<Widget>(Closure: (dynamic) => ListTile)
The relevant error-causing widget was
HomePage
package:hello_world/main.dart:16
When the exception was thrown, this was the stack
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 _HomePageState.build
package:hello_world/main.dart:135
#2 StatefulElement.build
package:flutter/…/widgets/framework.dart:4334
#3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4223
#4 Element.rebuild
package:flutter/…/widgets/framework.dart:3947
...
════════════════════════════════════════════════════════════════════════════════
Code here:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:table_calendar/table_calendar.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Calendar',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
CalendarController _controller;
Map<DateTime, List<dynamic>> _events;
List<dynamic> _selectedEvents;
TextEditingController _eventController;
SharedPreferences prefs;
#override
void initState() {
super.initState();
_controller = CalendarController();
_eventController = TextEditingController();
_events = {};
_selectedEvents = [];
initPrefs();
}
initPrefs() async {
prefs = await SharedPreferences.getInstance();
setState(() {
_events = Map<DateTime, List<dynamic>>.from(
decodeMap(json.decode(prefs.getString("events") ?? "{}"))
);
});
}
Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
Map<String, dynamic> newMap = {};
map.forEach((key, value) {
newMap[key.toString()] = map[key];
});
return newMap;
}
Map<DateTime, dynamic> decodeMap(Map<String, dynamic> map) {
Map<DateTime, dynamic> newMap = {};
map.forEach((key, value) {
newMap[DateTime.parse(key)] = map[key];
});
return newMap;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Calendar'),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TableCalendar(
events: _events,
initialCalendarFormat: CalendarFormat.week,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
todayColor: Colors.orange,
selectedColor: Theme.of(context).primaryColor,
todayStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white
)
),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonDecoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(20.0),
),
formatButtonTextStyle: TextStyle(color: Colors.white),
formatButtonShowsNext: false,
),
startingDayOfWeek: StartingDayOfWeek.sunday,
onDaySelected: (date, events) {
setState(() {
_selectedEvents = events;
});
},
builders: CalendarBuilders(
selectedDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10.0)
),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)
),
todayDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(10.0)
),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)
),
),
calendarController: _controller,
),
..._selectedEvents.map((event) => ListTile(
title: Text(event),
)),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _showAddDialog,
),
);
}
_showAddDialog() async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
content: TextField(
controller: _eventController,
),
actions: <Widget>[
FlatButton(
child: Text("Save"),
onPressed: () {
if (_eventController.text.isEmpty) return;
if (_events[_controller.selectedDay] != null) {
_events[_controller.selectedDay].add(_eventController.text);
} else {
_events[_controller.selectedDay] = [
_eventController.text
];
}
prefs.setString("events", json.encode(encodeMap(_events)));
_eventController.clear();
Navigator.pop(context);
},
),
FlatButton(
child: Text("Delete Events"),
onPressed: () {
setState(() {
_events.remove(_controller.selectedDay);
prefs.setString("events", json.encode(encodeMap(_events)));
_eventController.clear();
Navigator.pop(context);
},
);
}
)
],
)
);
setState(() {
_selectedEvents = _events[_controller.selectedDay];
});
}
}

I have gone through your code, and handled delete event null exception as per below.
Change your last setState code with below:
setState(() {
_selectedEvents = _events[_controller.selectedDay] ?? [];
});
Conclusion:
_selectedEvents null value can be handled by ?? [] in your code.

Related

Wondering this error Type 'Future<dynamic>' is not a subtype of type 'Widget'

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:diary_sangiboo/utils.dart';
class Calendar extends StatefulWidget {
#override
_CalendarState createState() => _CalendarState();
}
class _CalendarState extends State<Calendar> {
late Map<DateTime, List<Event>> selectedEvents;
CalendarFormat format = CalendarFormat.month;
DateTime selectedDay = DateTime.now();
DateTime focusedDay = DateTime.now();
TextEditingController _eventController = TextEditingController();
#override
void initState() {
selectedEvents = {};
super.initState();
}
List<Event> _getEventsfromDay(DateTime date) {
return selectedEvents[date] ?? [];
}
#override
void dispose() {
_eventController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("한달 기록"),
centerTitle: true,
),
body: Column(
children: [
TableCalendar(
focusedDay: selectedDay,
firstDay: DateTime(1990),
lastDay: DateTime(2050),
calendarFormat: format,
onFormatChanged: (CalendarFormat _format) {
setState(() {
format = _format;
});
},
startingDayOfWeek: StartingDayOfWeek.sunday,
daysOfWeekVisible: true,
//Day Changed
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
selectedDay = selectDay;
focusedDay = focusDay;
});
print(focusedDay);
},
selectedDayPredicate: (DateTime date) {
return isSameDay(selectedDay, date);
},
eventLoader: _getEventsfromDay,
//To style the Calendar
calendarStyle: CalendarStyle(
isTodayHighlighted: true,
selectedDecoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
),
selectedTextStyle: TextStyle(color: Colors.white),
todayDecoration: BoxDecoration(
color: Colors.purpleAccent,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
),
defaultDecoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
),
weekendDecoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
),
),
headerStyle: HeaderStyle(
formatButtonVisible: true,
titleCentered: true,
formatButtonShowsNext: false,
formatButtonDecoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5.0),
),
formatButtonTextStyle: TextStyle(
color: Colors.white,
),
),
),
..._getEventsfromDay(selectedDay).map(
(Event event) => ListTile(
title: Text(
event.title,
),
),
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("출석체크를 하시겠습니까?"),
content: TextFormField(
controller: _eventController,
),
actions: [
TextButton(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text("Ok"),
onPressed: () {
if (_eventController.text.isEmpty) {
} else {
if (selectedEvents[selectedDay] != null) {
selectedEvents[selectedDay]?.add;
} else {
selectedEvents[selectedDay] = [
];
}
}
Navigator.pop(context);
_eventController.clear();
setState((){});
return;
},
),
],
),
),
label: Text("Add button"),
icon: Icon(Icons.add),
),
);
}
}
This is my code. type 'Future' is not a subtype of type 'Widget' error. Where should I fix this error and what code should I add?
I want to make it in the form of attendance check on the calendar. If today is May 28th, I would like to make a check mark or a color mark on May 28th to make an attendance mark. But there's an error. I don't know why. I'd like you to help me. Help me plz..
Your issue is not clear, I tested the code and you have an issues in adding to events list logic,
onPressed: () {
if (_eventController.text.isEmpty) {
} else {
if (selectedEvents[selectedDay] != null) {
selectedEvents[selectedDay]?.add;
} else {
selectedEvents[selectedDay] = [
];
}
}
Navigator.pop(context);
_eventController.clear();
setState((){});
return;
},
here, what do you mean by selectedEvents[selectedDay]?.add;?
also, in the else block, you are reinitializing the list, so the List<Event> will always be empty,
a proper code would be:
(selectedEvents[selectedDay] ??= []).add(Event(_eventController.text));
this code line will add an Event object to the list if its not null,
and if its null, it will create a new list and add the event to it,
NOTE: Your code did not add any Event object to the lists

Making spinner background transparent in flutter

I'm new to flutter and making my first webview app. Here I'm trying to add a spinner every time when a user tries to click the link or page load. I want to make spinner background opacity a bit low just like the given example, but opacity doesn't work at all.
My approach
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white.withOpacity(0.5),
child: Center(
child: SpinKitDualRing(
color: Colors.pinkAccent,
size: 45.0,
controller: AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
),
),
),
)
I'm using here flutter_spinkit package as a spinner.
Full code
// ignore_for_file: prefer_const_constructors
// ignore: use_key_in_widget_constructors
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:splash_screen_view/SplashScreenView.dart';
void main(){
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Color(0xff1e2229)
));
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
Widget spalshfirst = SplashScreenView(
navigateRoute: WebViewClass(),
duration: 3000,
imageSize: 80,
imageSrc: 'assets/splash.png',
text: "Food Delivery",
textType: TextType.TyperAnimatedText,
textStyle: TextStyle(
fontSize: 25.0,
),
colors: const [
Colors.purple,
Colors.blue,
Colors.yellow,
Colors.red,
],
backgroundColor: Colors.white,
);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: spalshfirst
)
);
}
}
class WebViewClass extends StatefulWidget {
WebViewState createState() => WebViewState();
}
class WebViewState extends State<WebViewClass> with TickerProviderStateMixin{
late WebViewController _controller;
final Completer<WebViewController> _controllerCompleter =
Completer<WebViewController>();
//Make sure this function return Future<bool> otherwise you will get an error
Future<bool> _onWillPop(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
return Future.value(true);
}
}
#override
void initState() {
super.initState();
// Enable hybrid composition.
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
bool isLoading = false;
final key = UniqueKey();
int position = 0;
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _goBack(context),
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: null,
body: SafeArea(
child: IndexedStack(
index: position,
children: [
WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
key: key,
onPageStarted: (value) {
setState(() {
position = 1;
});
},
onPageFinished: (value) {
setState(() {
position = 0;
});
},
onWebViewCreated: (WebViewController webViewController) {
_controllerCompleter.future
.then((value) => _controller = value);
_controllerCompleter.complete(webViewController);
},
),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white.withOpacity(0.5),
child: Center(
child: SpinKitDualRing(
color: Colors.pinkAccent,
size: 45.0,
controller: AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
),
),
),
)
],
),
),
),
);
}
Future<bool> _goBack(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Do you want to exit from Foodrive?'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('No'),
),
TextButton(
onPressed: () {
SystemNavigator.pop();
},
child: Text('Yes'),
),
],
));
return Future.value(true);
}
}
}
Since the container is containing only the spinner, and not the background widget, settings its opacity won't work,
I'd suggest using the Stack widget with the Opacity widget
Something like this (just a reference point):
return Stack(children: [
Opacity(opacity: 0.5, child: resetOfTheWidgetTree),
Container(child: spinWidgetHere),
]);

Make a list out of arguments received from second page in the home page

I am new to Flutter and I am creating a notes app. i want to pass the title and text of the new note from a "new note" page to the home page where all other notes are.
I want to pass the title and text to the first page where I can create a list of saved notes as the number of notes grow using a List view. What am I doing wrong?
Here is my code for the home page:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:notes/newnote.dart';
void main() {
runApp(MaterialApp(home: MyApp(), initialRoute: 'main.dart', routes: {
'/home': (context) => MyApp(),
'/newnote': (context) => NewNote(),
}));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notes',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirstPage(),
);
}
}
int x = 0;
class FirstPage extends StatefulWidget {
String title ;
String text ;
FirstPage({Key key, #required this.title,#required this.text}) : super(key: key);
void pri() {print(title);}
#override
_MyAppState createState() => _MyAppState();
}
Map data = {};
class _MyAppState extends State<FirstPage> {
#override
Widget build(BuildContext context) {
//final dat args = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text(
"Note-It!",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.black,
),
body: Column(
//
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 19.0),
),
Expanded(
child: ListView.builder(
itemCount: x,
itemBuilder: (context, index) {
return ListTile(
title: Text(widget.title),
// onTap: () {
// Navigator.push( context,MaterialPageRoute( builder: (context) =>
// DetailScreen(notedata: datas[index])));
// }
);
}),
),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.black,
onPressed: () {
setState(() {
Navigator.push(context, new MaterialPageRoute(
builder: (context) =>
new NewNote(t1: null, t2: null)
));
});
}),
),
],
),
);
}
}
and here is my code for "new note" page
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:notes/main.dart';
void main() {
runApp(MaterialApp(home: NewNote()));
}
final fromController1 = TextEditingController();
final fromController2 = TextEditingController();
var instance;
class NewNote extends StatelessWidget {
String t1; //requesting data here
String t2;
NewNote({Key key, #required this.t1,#required this.t2}) : super(key: key);
// final String d;
//
// NewNote({
// Key key,
// #required this.d,
// }) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New Note"),
backgroundColor: Colors.black,
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 19.0),
child: SingleChildScrollView(
child: Column(children: <Widget>[
TextField(
controller: fromController1,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Title"),
style: TextStyle(fontSize: 28.0),
),
Padding(padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 0.0)),
TextField(
controller: fromController2,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Text"),
style: TextStyle(fontSize: 20.0),
maxLines: null,
),
Padding(padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 0.0)),
Align(
alignment: Alignment.bottomCenter,
child: FloatingActionButton.extended(
label: Text("Save Note"),
icon: Icon(Icons.save),
backgroundColor: Colors.black,
onPressed: () {
x++;
t1 = fromController1.text;
t2 = fromController2.text;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyApp(), //pass your title and text to NewNote
),
).then((value){
FirstPage(title: t1, text: t2);
});
},
),
),
]),
),
),
),
);
}
}
You have already passed the title and string in the first page from new note page. You are just not displaying it onto the screen with right syntax.
Change this
title: Text(
"Note-It!",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
to
title: Text(
this.widget.title,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),

ListTile at Home screen is not updating with InheritedWidget

I'm getting started with flutter/dart and I'm trying to implement a simple note app using InheritedWidget and TextControllers, but when I add or edit some note it doesn't update the main screen. I printed the new notes list in console and it is updated with the addings and editings but is not updated in main screen, still showing the initial note list ({'title': 'someTitle1', 'text': 'someText1'}, ...).
main.dart :
void main() => runApp(NoteInheritedWidget(
MaterialApp(
title: 'Notes App',
home: HomeList(),
),
));
home screen scaffold body :
List<Map<String, String>> get _notes => NoteInheritedWidget.of(context).notes;
...
body: ListView.builder(
itemCount: _notes.length,
itemBuilder: (context, index) {
return Card(
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 7),
child: ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Editing, index: index))
);
print(_notes);
},
trailing: Icon(Icons.more_vert),
title: _NoteTitle(_notes[index]['title']),
subtitle: _NoteText(_notes[index]['text']),
),
);
},
),
Add/Edit Note page :
enum NoteMode {
Adding,
Editing
}
class NotePage extends StatefulWidget {
final NoteMode noteMode;
final int index;
const NotePage ({this.noteMode, this.index});
#override
_NotePageState createState() => _NotePageState();
}
class _NotePageState extends State<NotePage> {
final TextEditingController _titleController = TextEditingController();
final TextEditingController _textController = TextEditingController();
List<Map<String, String>> get _notes => NoteInheritedWidget.of(context).notes;
#override
void didChangeDependencies() {
if (widget.noteMode == NoteMode.Editing) {
_titleController.text = _notes[widget.index]['text'];
_textController.text = _notes[widget.index]['title'];
}
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.noteMode == NoteMode.Adding ? 'Add Note' : 'Edit Note'
),
centerTitle: true,
backgroundColor: Colors.indigo[700],
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
TextField(
controller: _titleController,
decoration: InputDecoration(
hintText: 'Note Title',
border: OutlineInputBorder(),
),
),
SizedBox(height: 20),
TextField(
controller: _textController,
maxLines: 20,
decoration: InputDecoration(
hintText: 'Note Text',
border: OutlineInputBorder(),
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_NoteButton(Icons.save, 'Save', () {
final title = _titleController.text;
final text = _textController.text;
if (widget.noteMode == NoteMode.Adding) {
_notes.add({'title': title, 'text': text});
print(_notes);
} else if (widget.noteMode == NoteMode.Editing) {
_notes[widget.index] = {'title': title, 'text': text};
print(_notes);
}
Navigator.pop(context);
}),
_NoteButton(Icons.clear, 'Discard', () {
Navigator.pop(context);
}),
if (widget.noteMode == NoteMode.Editing)
_NoteButton(Icons.delete, 'Delete', () {
_notes.removeAt(widget.index);
Navigator.pop(context);
}),
],
),
],
),
),
),
);
}
}
InheritedWidget :
class NoteInheritedWidget extends InheritedWidget {
final notes = [
{'title': 'someTitle1', 'text': 'someText1'},
{'title': 'someTitle2', 'text': 'someText2'},
{'title': 'someTitle3', 'text': 'someText3'}
];
NoteInheritedWidget(Widget child) : super(child: child);
static NoteInheritedWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<NoteInheritedWidget>();
}
#override
bool updateShouldNotify(NoteInheritedWidget old) {
return old.notes != notes;
}
}
Home screen after add a note :
HomeScreen
List of notes printed in console after add a note :
I/flutter (18079): [{title: someTitle1, text: someText1}, {title: someTitle2, text: someText2}, {title: someTitle3, text: someText3}, {title: NewAddNoteTitle, text: NewAddNoteText}]
I'm using Android Studio and a real device instead an emulator.
I can't find the error and if you have another way to do this 'update' please show me.
I found a solution using the onPressed method as async and then an empty setState, is there any problem for the code doing this?
code:
child: ListTile(
onTap: () async {
await Navigator.push(context,
MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Editing, index: index))
);
setState(() {});
print(_notes);
},
...
floatingActionButton: FloatingActionButton(
onPressed: () async {
await Navigator.push(context,
MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Adding))
);
setState(() {});
print(_notes.length);
print(_notes);
},

How to navigate to another screen from dropdownbutton in Flutter?

I am trying to get a dropdownlist to navigate to another screen once one of the items in the list is pressed via the dropdownbutton. I have tried using Navigator.push straight into onChanged but that doesnt work. And i have tried creating a new button in set state in onChanged. How can I do this because I do not know how?
import 'package:flutter/material.dart';
void main() => runApp(new HomeNavigator());
class HomeNavigator extends StatefulWidget {
#override
_HomeNavigator createState() => _HomeNavigator();
}
class _HomeNavigator extends State<HomeNavigator> {
List<DropdownMenuItem<String>> listMunicipalities = [];
String selected = null;
void loadData() {
listMunicipalities = [];
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Port Moody'),
value: 'Port Moody',
));
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Vancouver Downtown'),
value: 'Vancouver Downtown',
));
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Coquitlam'),
value: 'Coquitlam',
));
}
#override
Widget build(BuildContext context) {
loadData();
Color gradientStart = Colors.deepOrange[700];
Color gradientEnd = Colors.purple[500];
return new MaterialApp(
home: new Scaffold(
body: new Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [gradientEnd, gradientStart],
begin: new FractionalOffset(0.0, 0.5),
end: new FractionalOffset(0.5, 0.0),
stops: [0.0, 1.0]),
),
child: Stack(children: [
Container(
child: Text('',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 30.0,
fontFamily: 'College-Block',
color: Colors.white.withOpacity(0.7))),
alignment: Alignment(0.0, -0.5)),
Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Container(
alignment: Alignment(0.0, 0.05),
child: Container(
width: 350.0,
child: DropdownButtonHideUnderline(
child: new DropdownButton(
value: selected,
items: listMunicipalities,
hint: Text(
'Select City',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white.withOpacity(0.5)),
),
onChanged: (value){
}),
)),
)))
]))));
}
}
class HomePage extends StatefulWidget{
#override
_HomePage createState() => _HomePage();
}
class _HomePage extends State<HomePage> {
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('')
),
);
}
}
you can just use simple switch case over there. refer below example to clear idea.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstScreen(),
));
}
class FirstScreen extends StatelessWidget {
String _selectedGender=null;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Column(
children: <Widget>[
DropdownButton(
value: _selectedGender,
items: _dropDownItem(),
onChanged: (value){
_selectedGender=value;
switch(value){
case "Male" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
break;
case "Others" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
break;
case "Female" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => third()),
);
break;
}
},
hint: Text('Select Gender'),
),
],
),
);
}
List<DropdownMenuItem<String>> _dropDownItem() {
List<String> ddl = ["Male", "Female", "Others"];
return ddl.map(
(value) =>
DropdownMenuItem(
value: value,
child: Text(value),
)
).toList();
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
class third extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("tgird Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
for detail go to document https://flutter.io/cookbook/navigation/navigation-basics/
Add below line in your code for Navigation
onChanged: (value){
Navigator.push(context,MaterialPageRoute(builder: (context) =>
YourScreenInstance()),);
}
Navigator.popAndPushNamed(context, "/YourScreenInstance");
Navigator.of(context).pushNamed('/NewPage');

Categories

Resources