#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: const Icon(Icons.home),
automaticallyImplyLeading: true,
title: const Text('test app'),
foregroundColor: Colors.black,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.menu),
),
],
),
body: Container(
child: Column(
children: [
Row(
children: [
const Text(
'New',
style: TextStyle(
color: Colors.black54,
fontSize: 40,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
height: 2,
shadows: [
Shadow(color: Colors.black12, offset: Offset(4, 10))
]),
),
ElevatedButton.icon(onPressed: (){}, icon: Icon(Icons.navigate_next),label: Text(' '),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.grey),
),
),
],
),
Row(),
],
),
),
),
);
}
use the Row widget properties for laying out its childrens
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [....]
)
the official docs are helpful in that matter
https://api.flutter.dev/flutter/widgets/Row-class.html
sidenote: if you are not planning to use any of the first container() properties then its better to get rid of it
There are 4 options u can use depending on what you want
If u want it below new u can use Column instead of Row .
If u want to put some space next to new u can use SizedBox(width:X) between the Text and the elevated button.
You can use mainAxisAlignment or crossAxisAlignment inside the row or column to customize the position
you can find examples about them here https://docs.flutter.dev/development/ui/layout
you can use margin or padding on elevated button to customize its own position
Related
I want to increase CupertinoNavigationBar heigth. The code is like this:
child: CustomCupertinoNavigationBar(
padding: EdgeInsetsDirectional.zero,
backgroundColor: Colors.white,
middle: Semantics(
label: "dashboard-main-page-title",
child: Text(
"My Title",
style: TextStyles.HankenSans_Bold_18_PrimaryBlack,
key: Key('dashboard-main-page-title'),
),
),
leading: Semantics(
label: "dashboard-back-button",
child: Material(
color: Colors.white,
child: CustomBackButton(
onPressHandler: () {
Navigation().openMyAccountPage();
},
),
),
),
);
I tried creating my own custom cupertino. I copied the cupertino/nav_bar.dart and changed _kNavBarPersistentHeight parameter as const double _kNavBarPersistentHeight = 58.0; but it resulted at two navigation bars in IOS. Can anybody help me with this? Much appreciated.
I solved this problem as
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: Container(
height: 120,
child: CupertinoNavigationBar(
padding: EdgeInsetsDirectional.zero,
backgroundColor: Colors.white,
middle: Semantics(
label: "dashboard-main-page-title",
child: Text(
CustomerLoyaltyLocalizations.instance.dashboardMainPageTitle,
style: TextStyles.HankenSans_Bold_18_PrimaryBlack,
key: Key('dashboard-main-page-title'),
),
),
leading: Semantics(
label: "dashboard-back-button",
child: Material(
color: Colors.white,
child: CustomBackButton(
onPressHandler: () {
Navigation().openMyAccountPage();
},
),
),
),
),
),
),
First I used PreferredSize and then Container widget before CupertinoNavigationBar.
In this simple implementation code I added some PopupMenuButton items into AppBar actions argument and now I want to styling PopupMenuDivider color which that have default color.
You can do this very easily using the Theme class, using which you can change the icon color, text color and PopupMenuDivider color.
Again, you can easily do this on Divider at PopupMenuItem using PopupMenuDivider.
appBar: AppBar(
title: Text("PopUpMenu Flutter"),
centerTitle: true,
actions: [
Theme(
data: Theme.of(context).copyWith(
dividerTheme: DividerThemeData(
color: Colors.black,
),
iconTheme: IconThemeData(color: Colors.white),
textTheme: TextTheme().apply(bodyColor: Colors.white),
),
child: PopupMenuButton<int>(
color: Colors.indigo,
//onSelected: (item) => onSelected(context, item),
itemBuilder: (context) => [
PopupMenuItem<int>(
value: 0,
child: Text('Settings'),
),
PopupMenuDivider(),
PopupMenuItem<int>(
value: 1,
child: Text('Share'),
),
PopupMenuDivider(),
PopupMenuItem<int>(
value: 2,
child: Row(
children: [
Icon(Icons.logout),
const SizedBox(width: 8),
Text('Sign Out'),
],
),
),
],
),
),
],
),
You can use PopupMenuItem child and assign Column like
PopupMenuItem<WhyFarther>(
value: WhyFarther.harder,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Working a lot harder'),
Divider(
color: Colors.grey,
)
],
),
),
What I want to do is to when pressed a movie tab it shows NowPlayedMovies() and BestMovies(), and when pressed tv shows tab to show NowPlayedTV() and BestTV(). At first I was using ListView but because I'm using tabs i need to use TabBarView. So in my child method I created 2 methods buildPage1 and buildPage2 in which I have put my 2 methods as mentioned above.
When I tried to run the code it displayed this error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building _TabControllerScope:
The getter 'key' was called on null.
Receiver: null
Tried calling: key
The relevant error-causing widget was:
DefaultTabController
Here is my code:
class HomePageMovie extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePageMovie> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF151C26),
appBar: AppBar(
backgroundColor: Color(0xFF151C26),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
logo,
height: 195,
),
],
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.searchOutline,
color: Colors.white,
))
],
titleSpacing: 0.0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(75.0),
child: DefaultTabController(
length: 2,
child: TabBar(
indicatorColor: Color(0xFFf4C10F),
indicatorWeight: 4.0,
unselectedLabelColor: Colors.white,
labelColor: Colors.white,
tabs: [
Tab(
icon: Icon(Icons.movie),
child: Text(
"Movies",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
),
Tab(
icon: Icon(Icons.live_tv),
child: Text(
"TV Shows",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
)
]),
),
),
),
body: DefaultTabController(
length: 2,
child: TabBarView(
children: [buildPage1(), buildPage2()],
),
));
}
buildPage1() {
NowPlayingMovies();
BestMovie();
}
buildPage2() {
NowPlayingTV();
BestTV();
}
}
Here is visual representation of what I'm trying to achieve:
Any help would be great. Thanks in advance :)
Use only one DefaultTabBarController at the top of your widget tree (in this case, as a parent of your Scaffold and remove the other two).
You should only use a single DefaultTabBarController that is shared between the TabBar and the TabBarView.
So with help of Miguel what I did wrong was I didn't put a specific controller to connect these 2, in my case as a solution I wrapped them both in common default controller. As of the 2nd part of the problem what I did is simply put ListView to display these 2
The code of solution:
class _HomePageState extends State<HomePageMovie> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Color(0xFF151C26),
appBar: AppBar(
backgroundColor: Color(0xFF151C26),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
logo,
height: 195,
),
],
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.searchOutline,
color: Colors.white,
))
],
titleSpacing: 0.0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(75.0),
child: TabBar(
indicatorColor: Color(0xFFf4C10F),
indicatorWeight: 4.0,
unselectedLabelColor: Colors.white,
labelColor: Colors.white,
tabs: [
Tab(
icon: Icon(Icons.movie),
child: Text(
"Movies",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
),
Tab(
icon: Icon(Icons.live_tv),
child: Text(
"TV Shows",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
)
]),
),
),
body: TabBarView(
children: [
ListView(
children: <Widget>[NowPlayingMovies(), BestMovie()],
),
ListView(
children: <Widget>[
NowPlayingTV(),
BestTV(),
],
),
],
),
),
);
}
}
In Flutter I want to create an app bar that looks as follows:
I've easily managed to add the 2 icons on the left and right, but I am struggling to create a rectangle in the middle.
I've tried the following code:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Image.asset('assets/images/maps.png'),
onPressed: () => {},
),
title: Expanded( // The bit that's not working. A rectangle that fills the middle area.
child: Container(
color: Colors.blue,
),
),
actions: <Widget>[
IconButton(
icon: Image.asset('assets/images/search.png'),
onPressed: () => {},
),
],
),
);
but I get the following exception:
Expanded widgets must be placed inside Flex widgets.
Expanded(no depth, flex: 1, dirty) has no Flex ancestor at all.
Thanks for the help.
You can achieve this by setting the centerTile attribute of the AppBar to true
Like this
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
leading: IconButton(
icon: Icon(
Icons.location_on,
color: Colors.grey,
),
onPressed: () => {},
),
title: Container(
padding: EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.refresh),
Expanded(
child: Center(
child: Text("London"),
),
),
Opacity(child: Icon(Icons.refresh), opacity: 0,),
],
),
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(10)),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.grey,
),
onPressed: () => {},
),
],
),
);
}
}
The output:
An alternative solution (inspired by #Josteve Adekanbi answer), to create a rectangle that fills the title area is:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: ...
title: Container(
width: double.infinity,
height: 40,
child: Container(
color: Colors.blue,
),
),
actions: ...
),
);
I want to place two icons, side by side on the "trailing" side of a ListTile. I tried adding a Row widget with the two icons inside, but it completely messed up the layout of the entire ListTile, making it unusable. Is there any way to expand the space allocated for the trailing part?
Here's the code:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.play_arrow,),
title: Text("This is a title"),
subtitle: Text("This is subtitle"),
trailing: Row(
children: <Widget>[
Icon(Icons.flight),
Icon(Icons.flight_land)
]),
)
]
),
),
);
}
}
This is how it looks like:
Adding mainAxisSize: MainAxisSize.min to the Row() instance fixes the issue.
You can simply use Wrap in trailing
ListTile(
title: Text("This is my ListTile"),
trailing: Wrap(
spacing: 12, // space between two icons
children: <Widget>[
Icon(Icons.call), // icon-1
Icon(Icons.message), // icon-2
],
),
)
Try this code. I think this is working correctly:
trailing: FittedBox(
fit: BoxFit.fill,
child: Row(
children: <Widget>[
Icon(Icons.flight),
Icon(Icons.flight_land),
],
),
),
I took advantage of the FittedBox solution left above and solved my problem by displaying a TextButton and an IconButton when the screen is in landscape and when in portrait mode, only IconButton
trailing: MediaQuery.of(context).size.width > 480
? FittedBox(
fit: BoxFit.fill,
child: Row(
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
// padding: const EdgeInsets.all(16.0),
primary: Theme.of(context).errorColor,
textStyle: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold),
),
onPressed: () => onRemove(tr.id),
child: const Text('Excluir'),
),
IconButton(
icon: Icon(Icons.delete),
color: Theme.of(context).errorColor,
onPressed: () => onRemove(tr.id),
),
],
),
)
: IconButton(
icon: Icon(Icons.delete),
color: Theme.of(context).errorColor,
onPressed: () => onRemove(tr.id),
),
Given negative value to spacing did the trick:
trailing: Wrap(
spacing: -16,
children: [
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.delete,
color: Colors.redAccent,
),
onPressed: () {},
),
],
),