Keep Widget always visible while changing pages in flutter - flutter

I'm currently using Navigator.pushNamed for changing the content of my app and I would like to have a persistent widget on top of every page without loading it every time I change a page. Is it possible or I have to change my entire app to use one scaffold and update the content of the scaffold? I would like to avoid this solution.

import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Page1(),
builder: (context, child) {
return Scaffold(
appBar: AppBar(), // the common thing.
body: child,
);
},
);
}
}
class Page1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();// add button to go to Page2
}
}
class Page2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();
}
}
Description:
builder allows you to pass the different widget and each widget will be wrapped with the common widget, AppBar inside the scaffold here. Thus the scaffold and appbar is common for each page you visit.

Related

How to rebuild the root widget of flutter?

I am using provider package to detect changes in 'todaysTasks' but as you can see 'todayTasks' depends on DaysRecords which stores a list of DayTasks, so what I want is to rebuild my root widget (which is MyApp) whenever i push a DayTask in DaysRecords.recordsList but can't figure out any way to do that.
Is there any solution to this??
class MyApp extends StatelessWidget {
static const routeName = '/root';
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
DayTasks todaysTasks = DaysRecords.recordsList.last;
return ChangeNotifierProvider(
create: (context) => todaysTasks,
You can just wrap the parent widget of MyApp (I'm guessing, it is MaterialApp on main method) with ChangeNotifierProvider instead of wrapping inside MyApp.
Then initialize the correspondent provider in MyApp's build method or use a consumer to rebuild (manage your state).
void main() {
runApp(MaterialApp(
home: RootWidget(),
));
}
class RootWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => SomeProvider(),
child: MyApp(),
);
}
}
class MyApp extends StatelessWidget {
static const routeName = '/root';
#override
Widget build(BuildContext context) {
final provider = Provider.of<SomeProvider>(context, listen: true);
// DayTasks todaysTasks = provider.recordsList.last;
return Scaffold(
body: AppBar(
automaticallyImplyLeading: false,
),
);
}
}

Is home property in MaterialApp necessary to run Application?

At compile time it show no problem but after running a program, it shows following error in console.
For the "/" route, the "home" property, if non-null, is used
Here is my code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Hello world',
);
}
}
I am new in flutter and i want to know reasons why flutter give this error?
This error occurs because you don't have either routes or home properties in the MaterialApp class, so you can add either home property with the class that has build method that container Scaffold class.
so the easiest way, (if you don't have routes for multiple screens) is to add a home property like this:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Hello world',
home: YourClassName(),
);
}
}
After that, you can create YourClassName and it could be a stateless or stateful widget like this example:
class YourClassName extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text("some text")),
);
}
}
I wish that helps you

How to call a Stateless widget in MyApp's build method whose state is managed by its Stateful Parent

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()),
),
),
); } }

how can i make bloc available for all flutter app pages

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

Navigate between pages using Navigator issue

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');
)
}
}