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,
),
),
),
);
}
}
Related
I understand that it is used to adjust AppBar, but what is PreferredSize after all?
What is the use of PreferredSize widget in flutter?
The following text is found in the official documents, but I do not understand what it means.
https://api.flutter.dev/flutter/widgets/PreferredSize-class.html
It just advertises a preferred size which can be used by the parent.
The explanation in the official documentation is also limited to the AppBar, which I could not understand further.
I wrote the following code as a test, but the height of the green container was spread across the entire screen.
import 'package:flutter/material.dart';
void main() {
runApp(const _MyApp());
}
class _MyApp extends StatelessWidget {
const _MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: PreferredSize(
preferredSize: const Size.fromHeight(100.0),
child: Container(
width: 300,
color: Colors.green,
),
),
),
),
);
}
}
Here is the Short Details about it:
Preferred Size is a custom widget lets you allow to design your custom appbar for you with the same height, width, elevation and feel similar to Appbar.
Sometimes you want to create tabs or more effective design for your appbar then you can create a customChild for your appBar with the help of PreferredSizeWidget.
The size this widget would prefer if it were otherwise unconstrained.
In many cases it's only necessary to define one preferred dimension.
For example the [Scaffold] only depends on its app bar's preferred
height. In that case implementations of this method can just return
Size.fromHeight(myAppBarHeight).
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),
),
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
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.
I'm still trying to understand how to structure widgets. I have placed a container in the body already so how can I now add another row. I've removed some code to simplify my situation but hopefully this gives an idea of how my project is structured at the moment.
class AddButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.bottomCenter,
//Stats Button
child: Row(
), //container
//How can I enter a new row here <------- WHERE I WANT TO ENTER A ROW
);
}
}
The short answer is, you cannot. You can take advantage of the children property of a Column, the most common layout widget in all of Flutter. Flutter works on a system of nested widgets, you cannot have many parents as it all starts with one widget.
class AddButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.bottomCenter,
//Stats Button
child: Column(
children: <Widget>[
Row(
children: <Widget>[
// nested widgets
],
),
],
),
),
);
}
}
Judging by your class name, you just want a button. Not every widget starts with a Scaffold, that's only if you want an entire layout with an app bar or a bottom navigation bar. For simple widgets like a button, you can get rid of Scaffold entirely and just use MaterialButton like this.
class AddButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialButton(
onPressed: () {}, //empty function
);
}
}
More reading:
https://flutter.dev/docs/development/ui/layout
https://pusher.com/tutorials/flutter-building-layouts
https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e