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
Related
Let's say I have this HomePage widget:
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(),
);
}
}
I am able to use a const constructor at the root (MaterialApp widget) because all children do have const constructors too.
If I add the AppBar widget, I will have to remove the const constructor from the root, because AppBar does not have a const constructor.
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp( // no const anymore
home: Scaffold(
appBar: AppBar(...),
),
);
}
}
But why am I able to use the HomePage widget with a const constructor ? See code below:
class App extends StatelessWidget {
const App({super.key});
#override
Widget build(BuildContext context) {
return const HomePage(); // using a const constructor
}
}
I thought it would be impossible because of the AppBar child widget.
Because the HomePage class is immutable. The build function implementation doesn't affect it.
The const keyword can be used when the object is immutable. A Compiler allocates the same portion of memory for all objects.
For more info, reference the Using constructors: Dart doc
Is there a recommended way how to force the whole Flutter app to re-render during runtime but without losing state?
I need to update the app according to the back-end response, and I can't use the regular approaches (updating the widget state, inherited widget - provider pattern, etc.). More precisely, the data I need to update is shown on the UI via one Flutter package that does not provide the ability to trigger re-rendering in case of change (data is loaded just once on startup).
In other words, is the below-posted solution valid? Are there any known drawbacks of this approach? Can I crash the app forcing re-rendering this way?
import 'package:flutter/material.dart';
main() {
runApp(Wrapper(child: MyApp()));
}
class Wrapper extends StatelessWidget {
final Widget child;
Wrapper({Key? key, required this.child}) : super(key: key);
updateIfNeeded(BuildContext context) {
// faking some API call...
Future.delayed(Duration(seconds: 5), () {
void rebuild(Element el) {
el.markNeedsBuild(); // can something go wrong here?
el.visitChildren(rebuild);
}
(context as Element).visitChildren(rebuild);
});
}
#override
Widget build(BuildContext context) {
updateIfNeeded(context);
return child;
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Wrapper(
child: MaterialApp(
title: 'Flutter App',
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(title: Text('Home Page')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text('Some content...')],
),
),
),
),
);
}
}
You can use a global key and assign it to MaterialApp key and change it's value whenever you want to refresh the app
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 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
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');
)
}
}