Related
As soon as I press the button I get the error code "Navigator operation requested with a context that does not include a Navigator." Code im using to navigate is in the RegisterPage and by the builder function should be displaying the MainPage.
void main() => runApp(RegisterPage());
class RegisterPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Register Your Account'),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => MainPage()
),
);
},
child: Text('Sign in as guest'),
)),
)
);
}
}
class MainPage extends StatefulWidget{
String get title => "Cykla i stockholm";
MapPage createState()=> MapPage();
}
That's because the widget which uses the navigator (RegisterPage) is at the same level in the widget tree with the widget which creates the navigator(MaterialApp)
SOLUTION:
make the RegisterPage below MaterialApp in order to be able to use its context:
class RegisterPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Register Your Account'),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Builder(
builder: (ctx)=> Center(//this context here has access to Navigator
child: RaisedButton(
onPressed: () {
Navigator.of(ctx)
.push(
MaterialPageRoute(
builder: (context) => MainPage()
),
);
},
child: Text('Sign in as guest'),
)),
),
)
);
}
}
This is my code so far. I dont know whats wrong, I tried a lots of youtube turolial and other things as well, but its looks like the pop wont give back the correct data. I really need help, i spend 2 days already
void main() {
List<String> names = [];
List<String> mgs = [];
runApp(MaterialApp(
title: 'Returning Data',
home: HomeScreen(names, mgs),
));
}
class HomeScreen extends StatelessWidget {
List<String> names = [];
List<String> mgs = [];
HomeScreen(this.names, this.mgs);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("Project_Drink"),
),
body: Container(
child: Column(
children: <Widget>[
new Expanded(
child: ListView.builder
(
itemCount: mgs.length,
itemBuilder: (context, Index) {
return Text("Name: " + names[Index]
+" "+ "Mg: " + mgs[Index]);
}
)
)
],
),
),
bottomNavigationBar :BottomAppBar (
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Expanded(child: Text("TOTAL : 200")),
FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddProduct()),
);
},
child: Icon(Icons.add),
),
],
),
),
),
);
}
}
This is the AddProduct i want this to send back the data and then i should be able to put in into a list.Lika a not pad
class AddProduct extends StatefulWidget {
#override
State createState() => new _AddProductState();
}
class _AddProductState extends State<AddProduct> {
List<String> names = [];
List<String> mgs = [];
//final TextEditingController eCtrl = new TextEditingController();
final nameController = TextEditingController();
final mgController = TextEditingController();
#override
Widget build (BuildContext ctxt) {
return new Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("New Drink"),
),
body: new Column(
children: <Widget>[
new TextField(
decoration: InputDecoration(
hintText: "Name",
),
controller: nameController,
),
new TextField(
decoration: InputDecoration(
hintText: "Mg",
suffixText: "Mg",
),
controller: mgController,
),
RaisedButton(
onPressed: (){
names.add(nameController.text);
mgs.add(mgController.text);
setState(() {});
nameController.clear();
mgController.clear();
Navigator.pop(context, names + mgs);
},
child: Text("ADD"),
),
],
)
);
}
}
I moved your lists to HomeScreen widget instead of main function. Your main function should just run the app
void main() {
runApp(
MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}
And I convert your HomeScreen widget to StatefulWidget insted of StatelessWidget because when you add new items and display it screen your state will change and StatelessWidget is not able to do that. It will be something like that
Navigator.push returns a future value so if you want to declare a variable with the data comes from that, you need to await for it. After you get the data you can add them into your lists but it needs to be inside setState function to update UI
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<String> names = [];
List<String> mgs = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("Project_Drink"),
),
body: Container(
child: Column(
children: <Widget>[
new Expanded(
child: ListView.builder(
itemCount: mgs.length,
itemBuilder: (context, index) {
return Text("Name: " + names[index] + " " + "Mg: " + mgs[index]);
}
),
),
],
),
),
bottomNavigationBar: BottomAppBar(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(child: Text("TOTAL : 200")),
FloatingActionButton(
onPressed: () async {
// Navigator.push returns a future value so you need to await for it
var data = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddProduct()),
);
// After you get the data from the other page you need to add them into your lists inside setState function to update UI
setState(() {
names.add(data[0]);
mgs.add(data[1]);
});
},
child: Icon(Icons.add),
),
],
),
),
),
);
}
}
I didn't change anything in your AddProduct widget.
class AddProduct extends StatefulWidget {
#override
State createState() => new _AddProductState();
}
class _AddProductState extends State<AddProduct> {
List<String> names = [];
List<String> mgs = [];
//final TextEditingController eCtrl = new TextEditingController();
final nameController = TextEditingController();
final mgController = TextEditingController();
#override
Widget build (BuildContext ctxt) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("New Drink"),
),
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: "Name",
),
controller: nameController,
),
TextField(
decoration: InputDecoration(
hintText: "Mg",
suffixText: "Mg",
),
controller: mgController,
),
RaisedButton(
onPressed: (){
names.add(nameController.text);
mgs.add(mgController.text);
setState(() {});
nameController.clear();
mgController.clear();
Navigator.pop(context, names + mgs);
},
child: Text("ADD"),
),
],
)
);
}
}
Although this code should work as you want, I would suggest you to have a look at some State Management methods such as Provider, Bloc and etc. It will be more effective to create what you want to do.
try this one with simple way , when press then call this method
goToView() async {
bool data=await Navigator.push(context, new CupertinoPageRoute(builder: (BuildContext context) {
return new CoolForgot();
}));
print(data);
}
My Next View is Forgot Screen so i have used CoolForgot(), you can use as per your requirement.
then when press on back button in Next View(In my case CoolForgot()) called this
Navigator.pop(context,true);
I have pass bool value and get bool value , you can pass any type of object and get from it.
I am a newbie to flutter, I am having a problem with passing the data to my search delegate class. The problem is that I have two tabs and I want to search within the active tab. So I am trying to send a variable that tells which tab is it and which table to look for value.
Here is what my code looks like:
class HomePage extends StatefulWidget {
static final String routeName = 'home';
#override
State<StatefulWidget> createState() {
return new _HomePageState();
}
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
var activeTab = "activity";
var _authToken, _id, _name, _emails, _userImage;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 2)..addListener(() {
setState(() {
switch (tabController.index) {
case 0:
activeTab = "activity";
break;
case 1:
activeTab = "subparticipants";
break;
}
});
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
// appBar: new AppBar(
// title: Text('Dashboard'),
// ),
body: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
labelColor: Color(0xFFFFFFFF),
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
//Tab(icon: Icon(Icons.directions_car)),
Tab(
text: "Activity Zone",
),
Tab(
text: "Sub Participant",
)
],
controller: tabController,
),
title: Text(
'Dashboard',
style: new TextStyle(
color: const Color(0xFFFFFFFF),
fontSize: 20.0,
fontWeight: FontWeight.w600,
letterSpacing: 0.3,
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch(activeTab));
},
)
],
),
body: TabBarView(
controller: tabController,
children: [
TabActivity(),
TabSubparticipant(),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print(
'Current Index: $activeTab');
},
),
drawer: _buildDrawer(context),
),
),
);
}
}
class DataSearch extends SearchDelegate{
final String activeTab;
DataSearch(this.activeTab);
#override
List<Widget> buildActions(BuildContext context){
return [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
query=activeTab;
},
)
];
}
#override
Widget buildLeading(BuildContext context) => IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
);
#override
Widget buildResults(BuildContext context) => Text('Result');
#override
Widget buildSuggestions(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Search by job id, asset name, client name $query',
style: new TextStyle(
color: Colors.black, fontWeight: FontWeight.bold, fontSize: 22.0),
),
);
}
}
When I try to get $activeTab and show it in query or somewhere else, It just gives out the error:
flutter: The following assertion was thrown building _SearchPage<dynamic>(dirty, dependencies:
flutter: [_LocalizationsScope-[GlobalKey#a02e3], _InheritedTheme], state: _SearchPageState<dynamic>#eceaa):
flutter: 'package:flutter/src/widgets/basic.dart': Failed assertion: line 6173 pos 15: 'child != null': is
I am a bit confused how should I pass value to it. I have seen some of similar questions but they are no help. Like this or this question. None of these have any of these errors. Can you please let me know what am I doing wrong. Whats the issue? Please help.
Well, For someone who dumb as me and is having the same problem as I am, Here is how you can fix the issue,
So I was not passing the correct value to Search delegate and was not picking it up properly. Here is the fixed part of code
class DataSearch extends SearchDelegate {
DataSearch({
#required this.activeTab,
});
final activeTab;
#override
Widget buildResults(BuildContext context) {
if (activeTab == "subparticipants") {
...... .
....
..
I made a chatbot with dialogflow and (https://github.com/diegodalbosco/flutter_dialogflow) this is working normaly with simple text response.
Then when I add Google Assistant on a respond (Intent) like: answers with Basic Card.
When i lunch this application on android phone, I can write normally and i can see normal answers. But when i try to write "Query" or "Intent" something to call the Google Assistant Basic Card response, application stop and error.
Could someone help?
I believe that Google Assistant response is supported by Flutter?
Could some one explain how to set, display rich message of Google Assistant response like Basic Card in flutter App?
ThankYou
I haded: "
and
"ChatMessage message = new ChatMessage(
text: response.queryResult.fulfillmentText
?? new df.BasicCard(),"
and
"new Container(
margin: const EdgeInsets.only(top: 5.0),
child: new Text(text?? new df.BasicCard()),
),
"
looking for docs on:
https://pub.dev/documentation/flutter_dialogflow_v2/latest/model_query_result/QueryResult/fulfillmentMessages.html
for fulfillmentMessages property
-
https://pub.dev/documentation/flutter_dialogflow_v2/latest/model_message_basic_card/BasicCard-class.html
for BasicCard
-
https://pub.dev/documentation/flutter_dialogflow_v2/latest/model_query_result/QueryResult-class.html
for QueryResult class
import 'package:flutter_dialogflow_v2/flutter_dialogflow_v2.dart' as df;
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Example Dialogflow Flutter',
theme: new ThemeData(
primarySwatch: Colors.deepOrange,
),
home: new MyHomePage(
title: 'Flutter Demo Dialogflow',
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
final List<df.BasicCard> fulfillmentMessages = <df.BasicCard>[];
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<ChatMessage> _messages = <ChatMessage>[];
final TextEditingController _textController = new TextEditingController();
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(color: Theme.of(context).accentColor),
child: new Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0),
child: new Row(
children: <Widget>[
new Flexible(
child: new TextField(
controller: _textController,
onSubmitted: _handleSubmitted,
decoration:
new InputDecoration.collapsed(hintText: 'Send a message'),
),
),
new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),
child: new IconButton(
icon: new Icon(Icons.send),
onPressed: () => _handleSubmitted(_textController.text)),
),
],
),
),
);
}
void response(query) async {
_textController.clear();
df.AuthGoogle authGoogle =
await df.AuthGoogle(fileJson: 'assets/project-id.json').build();
df.Dialogflow dialogflow =
df.Dialogflow(authGoogle: authGoogle, sessionId: '123456');
df.DetectIntentResponse response = await dialogflow.detectIntent(query);
ChatMessage message = new ChatMessage(
text: response.queryResult.fulfillmentText
?? new df.BasicCard()
,
name: 'Bot',
type: false,
);
setState(() {
_messages.insert(0, message);
});
}
void _handleSubmitted(String text) {
_textController.clear();
ChatMessage message = new ChatMessage(
text: text,
name: 'Rances',
type: true,
);
setState(() {
_messages.insert(0, message);
});
response(text);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Dialogflow V2'),
),
body: new Column(children: <Widget>[
new Flexible(
child: new ListView.builder(
padding: new EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (_, int index) => _messages[index],
itemCount: _messages.length,
)),
new Divider(height: 1.0),
new Container(
decoration: new BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTextComposer(),
),
]),
);
}
}
class ChatMessage extends StatelessWidget {
ChatMessage({this.text, this.name, this.type});
final String text;
final String name;
final bool type;
List<Widget> otherMessage(context) {
return <Widget>[
new Container(
margin: const EdgeInsets.only(right: 16.0),
child: new CircleAvatar(child: new Image.asset('img/placeholder.png')),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(this.name,
style: new TextStyle(fontWeight: FontWeight.bold)),
new Container(
margin: const EdgeInsets.only(top: 5.0),
child: new Text(text?? new df.BasicCard()),
),
],
),
),
];
}
List<Widget> myMessage(context) {
return <Widget>[
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Text(this.name, style: Theme.of(context).textTheme.subhead),
new Container(
margin: const EdgeInsets.only(top: 5.0),
child: new Text(text),
),
],
),
),
new Container(
margin: const EdgeInsets.only(left: 16.0),
child: new CircleAvatar(child: new Text(this.name[0])),
),
];
}
#override
Widget build(BuildContext context) {
return new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: this.type ? myMessage(context) : otherMessage(context),
),
);
}
}
I expect the output like:
when I ask the preset Intent for BasicCard, the app show response with BasicCard but the actual output is
error:
"
E/flutter ( 4203): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter ( 4203): Receiver: null
E/flutter ( 4203): Tried calling: "
and no response on the flutter chat App.
For Google Assistant Actions, you need to use one of our client libraries (Node.js or Java). The Dialogflow library are designed to support other platforms but not the Google Assistant specifically (some things might work cross-platform, but other like cards will not).
I'd like to make a widget that sticks to the bottom of the page, and then is pinned to the top of the keyboard (when it appears).
Note how the input textfield is pinned to the keyboard in the image below:
How would I do this? I tried putting it in the bottomNavigationBar, but this (obviously) didn't work. Is there a builtin way to do this?
This is a working example of the thing you want. I think!
Just copy/paste/run
What's important in this example is the Expanded. A really nice widget that expands to as much space as it can get. And in result pushing the chat box down as much as possible
(Bottom of the screen or bottom of the keyboard)
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('49715760 Stackoverflow'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Expanded(
child: new Material(
color: Colors.red,
child: new Text("Filled"),
),
),
new Container(
color: Colors.white,
padding: new EdgeInsets.all(10.0),
child: new TextField(
decoration: new InputDecoration(
hintText: 'Chat message',
),
),
),
],
),
);
}
}
The best way to resolve this is to use a dedicated widget.
MediaQuery.of(context).viewInsets.bottom will give you the value of the height covered by the system UI(in this case the keyboard).
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
var home = MyHomePage(title: 'Flutter Demo Home Page');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: home,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(widget.title),
),
body: _getBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _getBody() {
return Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sample.jpg"), fit: BoxFit.fitWidth)),
// color: Color.fromARGB(50, 200, 50, 20),
child: Column(
children: <Widget>[TextField()],
),
),
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: 0,
right: 0,
child: Container(
height: 50,
child: Text("Hiiiii"),
decoration: BoxDecoration(color: Colors.pink),
),
),
]);
}
}
there is a lib for that:
https://pub.dev/packages/keyboard_attachable
Widget build(BuildContext context) => FooterLayout(
footer: MyFooterWidget(),
child: PageMainContent(),
);
use of bottomSheet option from Scaffold.
Scaffold(
bottomSheet: chatBar(),
body: Column(
children: [
Expanded(
child: ListView()
)
]
)
)
the chatBar is top of keyboard, when keyboard is open.
for transparent chatBar: can wrap Scaffold by
Theme(
data: ThemeData.light().copyWith(
bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.transparent),
),
This worked for me,
showBottomSheet(
context: context,
builder: (context) => Container(
height: // YOUR WIDGET HEIGHT
child: // YOUR CHILD
)
showBottomSheet is a flutter inbuilt function.