I am using bloc to manage my app state, I want to provide the bloc for all my app pages so I have inserted in the top of the widget tree so I can use it from any place in the widget tree, I have used it as the follows
1- main page
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}}
class MyAppState extends State<MyApp>{
#override
Widget build(BuildContext context) {
return BlocProvider<MyBloc>(
create: (BuildContext context) {
return MyBloc();
},
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: secondPage()),
);
}
}
2- secondPage:
class SecondPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return SecondPage State();
}
}
class SecondPage State extends State<SecondPage > {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('secondPage')),
body: BlocBuilder<CityBloc, CityState>(
builder: (BuildContext context, CityState state) {
.......
},));}}
but the flutter display an error that
BlocProvider.of() called with a context that does not contain a Bloc of type MyBloc
and this is a screenshot of the app's widgets tree
, what is the error, I want to provide mybloc for all widgets
note: the app run ok if I write the MainPage class and the secondPage class in the same page, but when I separate them the error appears
I was shocked by the solution, the problem was only in import, I have replaced
import '../blocs/blocs.dart';
With
import 'package: loony_trips / blocs / blocs.dart';
And everything was fixed, even though the two sentences were supposed to be the same
Related
Being new to Flutter I want to know if it is a good practice to segregate the elements of Any page like HOME to different Classes or DART files.
If the answer is positive, I need some help with that.
I am aware that I have to Include the pages in both Mother and daughter .dart pages to each other.
Where I am confused is how much should I mention for a part of a page. (please forgive my nativity if there any)
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AppName',
home: MyHomePage(),
);
What should I return?
The Material App already runs the Mother or main page so how much to be included?
Or should I just Code the elements Like Row and Column and Card etc...
If the latter is true then how should I call them? Will those be automatically called when The MAIN .dart is executed?
~Addition~
Can I return any Layout Widget(Row/Column/Card) out of nothing !!
like
class MyHomePage extends StatelessWidget{
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
(I think it is logical because all the queries will be ultimately forwarded to MAIN.dart)
Any help is appreciated.
If I understand your question correctly, let me answer with an example:
Say your main.dart is as follows:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AppName',
home: MyHomePage(),
);
}
}
and your home_page.dart is:
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppName"),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CustomWidget1(),
CustomWidget2(),
],
),
);
}
}
Then CustomWidget1 can be (in a file named custom_widget_1.dart):
class CustomWidget1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("CustomWidget1"),
);
}
}
Then CustomWidget2 can be (in a file named custom_widget_2.dart):
class CustomWidget2 extends StatefulWidget {
CustomWidget2({Key key}) : super(key: key);
#override
_CustomWidget2State createState() => _CustomWidget2State();
}
class _CustomWidget2State extends State<CustomWidget2> {
#override
Widget build(BuildContext context) {
return Center(
child: Text("CustomWidget2"),
);
}
}
Yes you can create many directories and arrange your Dart files in it like services, model and config. As you call the main.dart the other Classes will not certainly be on main.dart, let me put this this way, maon.dart = >homepage.dart => productPage.dart=>.......
it is just navigation while navigation to some parameters classes be sure to parse the parameters
I was following flutter tutorials for managing state of a widget from its parent on this link [https://flutter.dev/docs/development/ui/interactive#parent-managed][1]
and i cant figure out how would call the widget in this case
it is very simple once you get the logic.
In practice, the parent (the "true" widget that you call), i.e.
class ParentWidget extends StatefulWidget {
#override
_ParentWidgetState createState() => _ParentWidgetState();
}
is the one that you call wherever and whenever you want in the rest of the code.
Since this is a Stateful widget, it means that it has stated (to keep it simple, it will manage any changes on the UI). Any change will occur, It will be changing its state and so, this code:
class _ParentWidgetState extends State<ParentWidget> {
bool _active = false;
void _handleTapboxChanged(bool newValue) {
setState(() {
_active = newValue;
});
}
#override
Widget build(BuildContext context) {
return Container(
child: TapboxB(
active: _active,
onChanged: _handleTapboxChanged,
),
);
}
}
Anyhow, once you use a Stateful widget, you change its state whenever you want to call the function
setState(() {
oldValue= newValue;
});
It will rebuild the entire widget changing the stuff you want (such as texts, images, widgets, and so on).
In a non-proper way, consider it as a particular widget that can change its UI during the time.
if you want to call it in MyApp's build method you will have to make MyApp a stateful widget so that it can manage the state of the said widget
void main() => runApp(MyApp());
//we make MyApp to be a stateful widget
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
//we define the state which will be used in the widget here
var myState = "something";
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Center(
child: Container(
//the data used by MyWidget is managed by MyApp which is a statefull widget.
child: MyWidget(state: myState),
),
),
),
);
}
}
Or rather wrap your widget with another stateful widget which you will use in MyApp's build method
//we create a widget which will manage the state of its children class MyStateManagingWidget extends StatefulWidget { #override
_MyStateManagingWidgetState createState() => _MyStateManagingWidgetState(); }
class _MyStateManagingWidgetState extends State<MyStateManagingWidget> { var myState = "some state"; #override Widget build(BuildContext context) {
//we put our widget who's state is to be managed here
return MyWidget(); } }
class MyApp extends StatelessWidget { #override Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Center(
child: Container(
//we now use the state managing widget here
child: MyStateManagingWidget()),
),
),
); } }
I am working on a flutter app and I want to update the second level parent's state when a button is pressed. When the "PressMe" button is pressed, I want MyHomePage's state to have Widget2's title string saved in it's own state. Can someone please help me out with this? The button is a lower level widget and I want to pass the data up two levels. Thanks!
//main.dart
import 'package:flutter/material.dart';
import 'Widget1.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(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String title2;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
),
body: Center(
child: Widget1(),
),
);
}
}
///////////////////////////////
//Widget1.dart
import 'package:flutter/material.dart';
import 'Widget2.dart';
class Widget1 extends StatefulWidget {
_Widget1State createState() => _Widget1State();
}
class _Widget1State extends State<Widget1> {
#override
Widget build(BuildContext context) {
return Widget2();
}
}
///////////////////////////////
//Widget2.dart
import 'package:flutter/material.dart';
class Widget2 extends StatefulWidget {
final String title = "Hello from Widget2";
_Widget2State createState() => _Widget2State();
}
class _Widget2State extends State<Widget2> {
String title = "Hello from Widget2";
#override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: null,
child: Text(
'PressMe',
style: TextStyle(fontSize: 20)
),
);
}
}
Thanks!
The easiest way to update your parent widget/class from a child is to pass down a function you create in the parent, then call that function from your child when you need to update it. However, that gets messy if you need to pass it down through multiple children. Usually in this case you'll want your parent to be a StatefulWidget and call setState inside the function you create when you assign the new title.
The next solution is to use InheritedWidgets or ChangeNotifiers.
The ideal solution would be to use some form of state management such as Provider or Bloc.
I am studying Flutter and building my first app using this framework.
Now I am facing a problem.
My scenario is very simple I want to navigate from the main screen to another screen.
this is the code of the from the home view
class HomeView extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return HomeViewState();
}
}
class HomeViewState extends State<HomeView> {
...
and I want to navigate to to another screen using Navigator
#override
Widget build(BuildContext context) {
return Container(
child: InkWell(
onTap: () {
Navigator.of(context).pushNamed('/userdetailsview');
},
child: Card(
...
this is my App.Dart
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
home: Scaffold(
body: Center(
child: HomeView(),
),
),
routes: <String,WidgetBuilder>{
'/homeview': (BuildContext context) => new HomeView(),
'/userdetailsview': (BuildContext context) => new UserDetails(),
},
);
}
}
finally this is the code for the page I want to navigate
class UserDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Text('test');
}
}
As you can see my scenario is very simple but this is the result .
As you can see for some reason the second page is overlapping the main page.
I am developer using Xamarin Forms and XAML applications Flutter is very easy to understand and I really like it but there is a lack of information about simple task like this one.
I would appreciate if someone could help to fix my issue
Thank you!.
Try this in UserDetails.dart
class UserDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Text('test');
)
}
}
I created an app with Flutter that contains a ListView that i build up with a StreamBuilder working with Firestore.
The code is written cleanly and ready to go but as soon as i run the app on my device, it tells me that " [The app] has been ended."
Android Studio doesnt really give out an error message. Within my logcat it tells me "Please configure Android SDK". Unfortunately i dont know how to proceed from here.
I made the Google Services setup step by step and the app is registered for Firestore usage.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.purple,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// ignore: non_constant_identifier_names
Stream<QuerySnapshot> tours_collection;
#override
void initState() {
super.initState();
tours_collection = Firestore.instance.collection('tours_collection').snapshots();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("ToursList"),
),
body: new ToursList(),
);
}
}
class ToursList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new StreamBuilder(
stream: Firestore.instance.collection('tours_collection').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text('Loading...');
return new ListView(
children: snapshot.data.documents.map((document) {
return new ListTile(
title: new Text(document['name']),
);
}).toList(),
);
},
);
}
}