How to modify Scaffold widget for the whole app - flutter

I have a big app and there's multi files with same scaffold tap action to hide the keyboard.
Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: Container(
///Textfields
),
),
),
);
Is there way to edit Scaffold widget for the whole app?

short answer, you can not customize your scaffold for the whole app because each scaffold has its own body, but you can customize the theme of the app such as the text colour or the font for the whole app on the main screen using the materialApp widget.
-If you are willing to make something fixed in the whole app like the same app bar or the navbar for the whole app that's possible and you have to create a separate screen for it.
-or if you are using a customized widget a lot, Flutter let you extract it, give it a name and use it again without rewriting the whole code again but by just writing the name you chose for it

In that case you can create your custom scaffold wrapper.
class ScaffoldWrapper extends StatelessWidget {
const ScaffoldWrapper({Key? key, required this.child}) : super(key: key);
final Widget child;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
child: child,
),
),
);
}
}
Now you can replace all occurrence of your mentioned code block with this..
ScaffoldWrapper(child: Container()); // your widget contents

Related

Screen independent way to detect clicks outside a widget

I'm looking for a screen independent way to detect clicks outside a widget.
Normally to detect clicks outside a widget I would need to wrap my screen around a GestureDetector with behavior: HitTestBehavior.opaque (or something like that).
Example:
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => handleClickOutside(),
child: Container(
child: MyWidget(),
),
),
);
}
The problem is that if I want to use this widget anywhere, I would have to wrap every screen...
So my question is, is there a way to achieve what I'm trying to do without the mandatory screen wrap?
You can reduce the amount of boiler plate code by creating you own widget that collects all the stuff you need on every page:
class MyPage extends StatelessWidget {
final Widget child;
MyPage({super.key, required this.child});
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: handleClickOutside,
child: child,
),
);
}
void handleClickOutside() {
// here is where you handle the click outside any widget
}
}
Note that you Container in you sample is not necessary.
Note the use of a method tear-off for the onTap parameter

can you navigate between widgets with only one scaffold

I have created a widget with a scaffold and called a widget in it as
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Everything Store"),
),
body: Register(),
);
}
}
the Register component doesn't have a scaffold in it, but when I try to navigate from the Register widget to another one that also doesn't have a scaffold too, so I used
onPressed: () => {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => login_page()))
},
I got an error as " No Material widget found. "
So is there a way to have one scaffold or should I make a scaffold for each widget?
The scaffold is one of the main widgets that helps you build up the UI screen on a device but a screen doesn't necessarily need it. The error that you are getting it might be because you are not passing the Widget class correctly.
Try to replace login_page() with the class name like so Register().

(Flutter) Is it possible to make bottomSheet of Scaffold transparent?

I've recently developed comment view below the detail posts.
Like the image I attached, I'd like to show images for each comment but the image Container should be transparent to see the last comment.
But I think Scaffold doesn't allow bottomSheet to have transparent children.
Are there anyone having an idea to solve this problem?
class PostDetail extends StatelessWidget {
final int maxRenderImgCnt = 4;
final Post post;
PostDetail(this.post);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar( ... ),
body: SingleChildScrollView( ... ),
bottomSheet: CommonTextField(onTap: null, editTarget: null),
You can wrap the widget with an opacity widget but there is also another way which is more efficient even for changing it later, that is the ThemeData widget:
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.black.withOpacity(0),
),

How to implement and extend from a Base Page in Flutter

Let's say I have a base page in a Material App.
The basepage only has one widget, a scaffold.
The scaffold contains an appbar, that is to remain constant through the app, in every page.
The scaffold also contains a body, which should be overriden by the pages that extend the base to display their contents.
How can I go about to do this?
Thanks for the help!
You could create a globally accessible page like this:
base_page.dart
import 'package:flutter/material.dart';
class BasePage extends StatelessWidget {
/// Body of [BasePage]
final Widget body;
const BasePage({#required this.body, Key key})
: assert(body != null),
super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Your appbar content here
),
body: body,
);
}
}
And when you want to use it, just provide the body to the new class like this:
main.dart
import 'package:flutter/material.dart';
import 'base_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return BasePage(
// This is where you give you custom widget it's data.
body: Center(child: Text('Hello, World')),
);
}
}
One way to do this is to create a variable holding the current route in your StatefulWidget.
Widget currentBody = your initial body ;
and then change that variable whenever you want to switch the body using setState:
SetState(() { currentBody = your new body widget }) ;
and in your scaffold after the appbar you put !
body : currentBody ;
You have many ways to do this, one is to use the Bloc package, but another way is to use a Bottom Navigation Bar](https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html)
The bottom navigation bar consists of multiple items in the form of text labels, icons, or both, laid out on top of a piece of material. It provides quick navigation between the top-level views of an app. For larger screens, side navigation may be a better fit.
A bottom navigation bar is usually used in conjunction with a Scaffold, where it is provided as the Scaffold.bottomNavigationBar argument.
I provided an example in my answer for transparent appbar, of course you do not need your appbar to be transparent.
class HomePageState extends State<Homepage> {
List<Widget> widgets = [Text("haha"), Placeholder(), Text("hoho")]; // as many widgets as you have buttons.
Widget currentWidget = widgets[0];
void _onItemTapped(int index) {
setState(() {
NavigationBar._selectedIndex = index;
currentWidget = widgets[index];
});
}
#override
Widget build(BuildContext context) {
return return MaterialApp(
home: Scaffold(
extendBody: true, // very important as noted
bottomNavigationBar: BottomNavigationBar(
currentIndex: NavigationBar._selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
backgroundColor: Color(0x00ffffff), // transparent
type: BottomNavigationBarType.fixed,
unselectedItemColor: Colors.blue,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.grade),
title: Text('Level'),
),
[...] // remaining in the link
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: ExactAssetImage("assets/background.png"), // because if you want a transparent navigation bar I assume that you have either a background image or a background color.
fit: BoxFit.fill
),
),
child: currentWidget
),
),
);
}
}
...
The Bloc architecture is harder to understand, you will need to read documentation and try tutorials, but it is also very interesting to implement.

Flutter Search bar in ActionBar like yelp app

I am trying to build an application location base and I want a search bar like this image shows. That search bar should be able search for locations and text. Does anyone have a pre-built search bar like this?
You can create you own custom app Bar.Simply give appBar property(in Scaffold) an PreferredSize and design as you like. Below is the implementation:
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar:PreferredSize(
preferredSize: Size.fromHeight(45.0),
//give child any Widget you like
child: Center(
child: Container(
width:MediaQuery.of(context).size.width*0.9,
height:100,
child:Center(child: Text("CUSTOM APP BAR")),
color:Colors.blueAccent,
),
),
),
);
}
}