How to remove padding of MaterialBanner? - flutter

I want to remove the following blue padding from MaterialBanner widget, but it doesn't seem to be customizable. I want to insert an image in the red region.
I looked into MaterialBanner for using across Scaffold widgets because ScaffoldMessenger doesn't allow me to insert widgets other than MaterialBanner.
Is there any suggestion?
dartpad.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Scaffold(body: JustBanner())));
}
class JustBanner extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _JustBannerState();
}
}
class _JustBannerState extends State<JustBanner> {
#override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () {
final messenger = ScaffoldMessenger.of(context);
messenger.clearMaterialBanners();
messenger.showMaterialBanner(MaterialBanner(
padding: EdgeInsets.zero,
leadingPadding: EdgeInsets.zero,
leading: const SizedBox.shrink(),
backgroundColor: Colors.blue,
content: Container(
color: Colors.red,
width: 200,
height: 50,
),
actions: const [SizedBox.shrink()]));
},
child: const Text('Banner')),
],
);
}
}

Container(
width: MediaQuery.of(context).size.width,
child: MaterialBanner(
content: Text('Hello'),
actions: [
Icon(Icons.add),
],
),
),

Its no possible without copy and re-create the class, buttonBar always appear:
final Widget buttonBar = Container( // <-- problematic widget
alignment: AlignmentDirectional.centerEnd,
constraints: const BoxConstraints(minHeight: 52.0),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: OverflowBar(
overflowAlignment: widget.overflowAlignment,
spacing: 8,
children: widget.actions,
),
);
final double elevation = widget.elevation ?? bannerTheme.elevation ?? 0.0;
final Color backgroundColor = widget.backgroundColor
?? bannerTheme.backgroundColor
?? theme.colorScheme.surface;
final TextStyle? textStyle = widget.contentTextStyle
?? bannerTheme.contentTextStyle
?? theme.textTheme.bodyText2;
Widget materialBanner = Container(
margin: EdgeInsets.only(bottom: elevation > 0 ? 10.0 : 0.0),
child: Material(
elevation: elevation,
color: backgroundColor,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: padding,
child: Row(
children: <Widget>[
if (widget.leading != null)
Padding(
padding: leadingPadding,
child: widget.leading,
),
Expanded(
child: DefaultTextStyle(
style: textStyle!,
child: widget.content,
),
),
if (isSingleRow)
buttonBar, // <----- here
],
),
),
if (!isSingleRow)
buttonBar, // <----- here
if (elevation == 0)
const Divider(height: 0),
],
),
),
);

Related

Customize agora video call UI in flutter

my video call output
when logged another person to this video call then shows like this.But I want when someone logged to video call then my video should be small.
like this.
and also when click my video then my video should be big and another person's video should be small. how to do that ? I couldn't find the any documentation how to do that
Code video call ui
// video view
Widget _viewRows() {
final views = _getRenderViews();
switch (views.length) {
case 1:
return Column(
children: <Widget>[_videoView(views[0])],
);
case 2:
return Column(
children: <Widget>[
_expandedVideoRow([views[0]]),
_expandedVideoRow([views[1]])
],
);
case 3:
return Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 3))
],
);
case 4:
return Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 4))
],
);
default:
}
return Container();
}
How customize the video UI like as I mentioned?
error
To create the layout which you want, edit _viewRow(CallNotifier notifier) and _expandedVideoRow(List views) function with following code : -
Widget _viewRows(CallNotifier notifier) : -
case 2:
return Container(
margin: EdgeInsets.only(top: 100, bottom: 100),
child: Stack(
children: [
_expandedVideoRow([views[secondScreen]]),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 10, bottom: 10),
child: GestureDetector(
onTap: () {
tempSwap = firstScreen;
firstScreen = secondScreen;
secondScreen = tempSwap;
setState(() {});
},
child: SizedBox(
height: 200,
width: 100,
child: _expandedVideoRow([views[firstScreen]])),
),
),
),
],
));
Above code contains _expandedVideoRow([views[secondScreen]]), which is just a simple Expandable Container and we are passing the index of the screen as a parameter. In our case, there are 2 screens hence 2 index that is 0 and 1. I have declared three integer variables here, int firstScreen = 0, int secondScreen = 1 and int tempSwap = 0. The second _expandedVideoRow([views[firstScreen]]) is wrapped by GesutreDector, so when the user taps on that screen the indexes of the variable are swapped which results in swapping the screens, SizedBox to reduce its width and height and Align widget to give the desired position to the second screen.
Widget _expandedVideoRow(List views) : -
Widget _expandedVideoRow(List<Widget> views) {
final wrappedViews = views.map<Widget>(_videoView).toList();
return Row(
children: wrappedViews,
);
}
Remove the Expanded widget that wraps the row like the above code because we can't use the Expanded under the Stack widget.
If you wish to change the bottom icons, then change _toolbar(CallNotifier notifier) function according to your need.
Widget _toolbar(CallNotifier notifier) {
return Container(
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawMaterialButton(
onPressed: () {
_onToggleMute(notifier);
setState(() {
isMute = !isMute;
});
},
child: Icon(
isMute ? Icons.mic_off : Icons.mic,
color: isMute ? Colors.white : Colors.teal,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: isMute ? Colors.teal : Colors.white,
padding: const EdgeInsets.all(12.0),
),
RawMaterialButton(
onPressed: () => _onCallEnd(context),
child: Icon(
Icons.call_end,
color: Colors.white,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.redAccent,
padding: const EdgeInsets.all(15.0),
),
],
),
);
}
Code which I use in my app, full code : -
class _CallScreenState extends State<CallScreen> {
double globalHeight;
int firstScreen = 0;
int secondScreen = 1;
int tempSwap = 0;
bool isMute = false;
void initState() {
super.initState();
}
List<Widget> _getRenderViews(CallNotifier model) {
final List<StatefulWidget> list = [];
list.add(RtcLocalView.SurfaceView());
model.users
.forEach((int uid) => list.add(RtcRemoteView.SurfaceView(uid: uid)));
return list;
}
Widget _videoView(view) {
return Expanded(child: Container(child: view));
}
Widget _expandedVideoRow(List<Widget> views) {
final wrappedViews = views.map<Widget>(_videoView).toList();
return Row(
children: wrappedViews,
);
}
Widget _viewRows(CallNotifier notifier) {
final views = _getRenderViews(notifier);
switch (views.length) {
case 1:
return Container(
margin: EdgeInsets.only(top: 100, bottom: 100),
child: Column(
children: <Widget>[_videoView(views[0])],
));
case 2:
return Container(
margin: EdgeInsets.only(top: 100, bottom: 100),
child: Stack(
children: [
_expandedVideoRow([views[secondScreen]]),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 10, bottom: 10),
child: GestureDetector(
onTap: () {
tempSwap = firstScreen;
firstScreen = secondScreen;
secondScreen = tempSwap;
setState(() {});
},
child: SizedBox(
height: 200,
width: 100,
child: _expandedVideoRow([views[firstScreen]])),
),
),
),
],
));
default:
}
return Container();
}
Widget _toolbar(CallNotifier notifier) {
return Container(
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawMaterialButton(
onPressed: () {
_onToggleMute(notifier);
setState(() {
isMute = !isMute;
});
},
child: Icon(
isMute ? Icons.mic_off : Icons.mic,
color: isMute ? Colors.white : Colors.teal,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: isMute ? Colors.teal : Colors.white,
padding: const EdgeInsets.all(12.0),
),
RawMaterialButton(
onPressed: () => _onCallEnd(context),
child: Icon(
Icons.call_end,
color: Colors.white,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.redAccent,
padding: const EdgeInsets.all(15.0),
),
],
),
);
}
void _onCallEnd(BuildContext context) {
Navigator.pop(context);
}
void _onToggleMute(CallNotifier notifier) {
notifier.isMuted = notifier.isMuted;
notifier.engine.muteLocalAudioStream(notifier.isMuted);
}
#override
Widget build(BuildContext context) {
return BaseWidget<CallNotifier>(
model: CallNotifier(),
onModelReady: (model) => model.init(widget.channelName, widget.token),
builder: (context, notifier, child) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Stack(
children: <Widget>[
_viewRows(notifier),
Align(
alignment: Alignment.bottomCenter,
child: _toolbar(notifier)),
],
),
),
);
});
}
}

Error show during compile time: The method '[]' was called on null. Receiver: null

I am getting an error with a single listing page or detailed page.
It shows the method [] was called on null.
But is as defined some itemData in main dart file it also showa same error. please help me to solve this error.
this is my DetailPage.dart file
import 'package:flutter/material.dart';
import 'package:uidesign/custom/BorderIcon.dart';
import 'package:uidesign/custom/OptionButton.dart';
import 'package:uidesign/utils/constants.dart';
import 'package:uidesign/utils/custom_functions.dart';
import 'package:uidesign/utils/widget_functions.dart';
class DetailPage extends StatelessWidget {
final dynamic itemData;
const DetailPage({super.key, #required this.itemData});
//DetailPage({Key? key,#required this.itemData}) : super(key: key);
#override
Widget build(BuildContext context){
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
final double padding = 25;
final sidePadding = EdgeInsets.symmetric(horizontal: padding);
return SafeArea(
child: Scaffold(
backgroundColor: COLOR_WHITE,
body: Container(
width: size.width,
height: size.height,
child: Stack(
children: [
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Image.asset(itemData["image"]),
Positioned(
width: size.width,
top: padding,
child: Padding(
padding: sidePadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: (){
Navigator.pop(context);
},
child: BorderIcon(
padding: new EdgeInsets.all(0.0),
height: 50,
width: 50,
child: Icon(
Icons.keyboard_backspace, color:COLOR_BLACK,
),
),
),
BorderIcon(
padding: new EdgeInsets.all(0.0),
width: 50,
height: 50,
child: Icon(Icons.favorite_border, color: COLOR_BLACK),
),
],
),
),
),
],
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("${formatCurrency(itemData["amount"])}",style: themeData.textTheme.headline1,),
addVerticalSpace(5),
Text("\$${itemData["address"]}",style: themeData.textTheme.subtitle2,),
]
),
BorderIcon(
width: 0,
height: 0,
child: Text("20 Hours ago",style: themeData.textTheme.headline5,),padding: const EdgeInsets.symmetric(vertical: 15,horizontal: 15),
)
],
),
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Text("House Information",style: themeData.textTheme.headline4,),
),
addVerticalSpace(padding),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
child: Row(
children: [
InformationTile(content: "${itemData["area"]}",name: "Square Foot",),
InformationTile(content: "${itemData["bedrooms"]}",name: "Bedrooms",),
InformationTile(content: "${itemData["bathrooms"]}",name: "Bathrooms",),
InformationTile(content: "${itemData["garage"]}",name: "Garage",)
],
),
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Text(
itemData["description"],
textAlign: TextAlign.justify,
style: themeData.textTheme.bodyText2,
),
),
addVerticalSpace(200),
],
),
),
Positioned(
bottom: 20,
width: size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OptionButton(text: "Message",icon: Icons.message,width: size.width*0.35,),
addHorizontalSpace(10),
OptionButton(text: "Call",icon: Icons.call,width: size.width*0.35,),
],
),
),
],
),
),
),
);
}
}
class InformationTile extends StatelessWidget{
final String content;
final String name;
const InformationTile({super.key, required this.content, required this.name});
#override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final Size size = MediaQuery.of(context).size;
final double tileSize = size.width*0.20;
return Container(
margin: const EdgeInsets.only(left: 25),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
BorderIcon(
padding: new EdgeInsets.all(0.0),
width: tileSize,
height: tileSize,
child: Text(content,style: themeData.textTheme.headline3,)),
addVerticalSpace(15),
Text(name,style: themeData.textTheme.headline6,)
],
),
);
}
}
this is my Sample_data.dart file
in this file i add some sample data in json format
and this is how i define my DetailPage file in main.dart file
import 'package:flutter/material.dart';
import 'package:uidesign/screens/LandingPage.dart';
import 'package:uidesign/screens/DetailPage.dart';
import 'package:uidesign/utils/constants.dart';
import 'dart:ui';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
double screenWidth = window.physicalSize.width;
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Design 1',
theme: ThemeData(primaryColor: COLOR_WHITE, accentColor: COLOR_DARK_BLUE, textTheme: screenWidth < 500 ? TEXT_THEME_SMALL : TEXT_THEME_DEFAULT, fontFamily: "Montserrat"),
//home: LandingPage(),
//home: DetailPage(itemData: 1),
home: const DetailPage(),
);
}
}
error in terminal: the line i select on terminal is the error
Please help me out how it get the data with the key
Pass your RE_DATA list here in MainScreen
home: DetailPage(itemData: RE_DATA)
And Change List<dynamic> itemData to List<Map<String,dynamic>> itemData in DetailPage.
You are getting list so access itemData like this itemData[index]['image']
If possible use model for your RE_DATA instead of passing List of Maps.

IconButton with Row

I would like, in this code, to put the IconButton in the top right corner of each ItemView. The ItemDescription and the ItemTitle centered at the top. I try to put them in the same Row but I can't get them to fit together, either the IconButton sticks to the text or it's in the middle.
I think it is easy but I didn't find a solution.
Here is the code:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
import 'package:watch/constants.dart';
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState(
);
}
}
class ListViewExampleState extends State<ListViewExample>{
List<Container> _buildListItemsFromItems(){
int index = 0;
return item.map((item){
var container = Container(
decoration: index % 2 == 0?
new BoxDecoration(color: const Color(0xFFFFFFFF)):
new BoxDecoration(
color: const Color(0xFFFAFAF5)
),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Expanded(
child: Row(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0 ),
child: Text(
item.title,
style: kItemTitle,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child:Text(
item.description,
style: kItemDescription,
),
),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: IconButton(
icon: Icon(Icons.favorite_border, color: Colors.black,),
iconSize: 24.0,
onPressed: null
),
)
],)
]),
),
]),
);
index = index + 1;
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Accueil', style: kAppBarStyle,),
backgroundColor: Colors.white,
elevation: 0,
),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}
Update : I have added a Spacer() and put all in the same row, and set CrossAxisAlignment to .center.
Put the Icon in the same row as the title and the description, with a Spacer() in between. That will then give you an overflow error, because the Spacer wants to take up as much space as physically possible, so with no restriction it goes on to infinity. To tell the Spacer that it is only allowed a finite amount of space, you have to set the mainAxisSize of the row to MainAxisSize.min
Here's the code, with a couple alterations so I was able to run it for myself.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: ListViewExample(),
);
}
}
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState();
}
}
class ListViewExampleState extends State<ListViewExample> {
var items = [
Item(),
Item(),
Item(),
Item(),
];
List<Container> _buildListItemsFromItems() {
int index = 0;
return items.map(
(item) {
var container = Container(
decoration: index % 2 == 0
? new BoxDecoration(color: const Color(0xFFFFFFFF))
: new BoxDecoration(color: const Color(0xFFFAFAF5)),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new Container(
color: Colors.red,
width: 150.0,
height: 100.0,
),
),
Expanded(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0),
child: Text(
item.title,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
item.description,
),
),
Spacer(),
GestureDetector(
child: Icon(
Icons.favorite_border,
size: 14,
color: Colors.black,
),
onTap: null,
),
],
),
),
],
),
);
index = index + 1;
return container;
},
).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Accueil'),
backgroundColor: Colors.white,
elevation: 0,
),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}
class Item {
final String title;
final String description;
Item({this.title = 'FooTitle', this.description = 'BarDescription'});
}

No Material widget found in flutter

this screenshot of an No Material widget found
I try to add stars RateBar as below code but i got an error no material widget found.
what i need to do is that when i pressed on this flatButton i got a window to rate the order and submit this rate, how can i do that through my code below, or to inform me how to handle it
this is the widget of StarRating
import 'package:flutter/material.dart';
typedef void RatingChangeCallback(double rating);
class StarRating extends StatelessWidget {
final int starCount;
final double rating;
final RatingChangeCallback onRatingchanged;
final Color color;
StarRating({this.starCount=5, this.rating = .0, this.onRatingchanged, this.color});
Widget buildStar(BuildContext context, int index){
Icon icon;
if (index >= rating) {
icon = Icon(
Icons.star_border,
color: Theme.of(context).buttonColor
);
}
else if(index > rating - 1 && index < rating){
icon = Icon(
Icons.star_half,
color: Theme.of(context).primaryColor,
);
}else{
icon = Icon(
Icons.stars,
color: Theme.of(context).primaryColor,
);
}
return InkResponse(
onTap: onRatingchanged==null ? null : ()=> onRatingchanged(index+1.0),
child: icon,
);
}
#override
Widget build(BuildContext context) {
return Row(
children: List.generate(starCount, (index)=>buildStar(context, index)),
);
}
}
and this is the Screen to view the starBar:
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
class StarRatingScreen extends StatefulWidget {
static const routeName = '/starRating';
#override
_StarRatingScreenState createState() => _StarRatingScreenState();
}
class _StarRatingScreenState extends State<StarRatingScreen> {
double rating =3.5;
#override
Widget build(BuildContext context) {
return StarRating(
rating: rating,
onRatingchanged: (rating) => setState(() => this.rating = rating),
);
}
}
and in orderDetails screen through the flatbutton i need to show this Star Rate:
import 'package:felsaree/providers/order_provider.dart';
import 'package:felsaree/screens/star_rating_screen.dart';
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class OrderDetails extends StatefulWidget {
static const routeName = '/orderDetails';
#override
_OrderDetailsState createState() => _OrderDetailsState();
}
class _OrderDetailsState extends State<OrderDetails> {
double rating = 3.5;
// Widget ratingChange(double rating){
// return StarRating(
// rating: rating,
// onRatingchanged: (rating)=>this.rating = rating,);
// }
#override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context).size.height;
final orderId = ModalRoute.of(context).settings.arguments as int;
final orderProvider = Provider.of<OrderProvider>(context, listen: false);
final order = orderProvider.findOrderById(orderId);
AppBar appBar = AppBar(title: Text(order.restaurantName),);
double _totalPrice =orderProvider.totalItemsPrice(order.orderItems);
bool _isAddress = orderProvider.checkUserAdress(order.address);
return Scaffold(
appBar: appBar,
body: Column(
children: <Widget>[
Card(
elevation: 4,
margin: EdgeInsets.all(10),
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Text(order.id.toString()),
SizedBox(height: 4,),
Text(order.restaurantName),
SizedBox(height: 4,),
Text(order.branchName),
SizedBox(height: 4,),
],
),
Column(
children: <Widget>[
Text(DateFormat.yMd().format(DateTime.now())),
SizedBox(height: 15,),
Text('InProgress'),
SizedBox(height: 15,)
],
)
],
),),
),
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(width: 2, color: Colors.grey)
) ,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Price'),
Text('${_totalPrice}L.E'),
Text('Total: ${order.price}L.E')
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('PC Discount'),
Text('${order.discountValue}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('service Tax'),
Text('${order.serviceTax}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Delivery'),
Text('${order.delivery}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Vat'),
Text('${order.vatAmount}L.E'),
Text(''),
],
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(bottom: 20),
height: (mediaQuery
- appBar.preferredSize.height
- MediaQuery.of(context).padding.top)*0.30,
width: MediaQuery.of(context).size.width*.8,
child: ListView.builder(
itemCount: order.orderItems.length,
itemBuilder: (ctx, index){
final item = order.orderItems[index];
if(item.userComments == ''){
String userComment= 'no comment';
item.userComments = userComment;
}
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(item.image,),
),
title: Text(item.itemName),
subtitle: Text('count: ${item.count}'),
trailing: Text(item.userComments),
);
}
),
),
Container(
width: double.infinity,
margin: EdgeInsets.only(right: 10, left: 10),
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
color: Colors.grey[100],
child: Text('Delivery Address', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
),
SizedBox(height: 8),
Container(
width: double.infinity,
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[100])
),
child: _isAddress? Text(order.address) : Text('no address found'),
),
FlatButton(
onPressed: ()=>Navigator.of(context).pushNamed(StarRatingScreen.routeName),
child: Text('Rate The Order', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),))
],
),
);
}
}
This can be fixed by ensuring that your main includes MaterialApp() and Scaffold() as ancestors of your widgets as so:
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: YourWidget(),
),
));
}
If, for whatever reason you don't want to use MaterialApp... you can use Material():
void main() {
runApp(
home: Scaffold(
appBar: AppBar(),
body: Material( child: YourWidget()),
),
);
}

How to fill vertical space in nested Column in ListView

I want the green box to fill the vertical space so MainAxisAlignment.spaceBetween will work.
import 'package:flutter/material.dart';
void main() => runApp(_app);
const title = "Layout test";
var _app = new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: const Text(title),
),
body: new _LayoutTest(),
),
);
class _LayoutTest extends StatelessWidget {
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return new ListView(
children: [
new Container(
color: Colors.orangeAccent,
margin: const EdgeInsets.only(bottom: 20.0),
child: new Row(
children: [
new Image.network(
// this can be any image
"http://via.placeholder.com/185x278",
width: size.width / 5,
),
new Expanded(
child: new Container(
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(8.0),
color: Colors.lightGreenAccent,
// this should fill vertical space
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
const Text("Top"),
const Text("Bottom"),
],
),
),
),
],
),
),
],
);
}
}
You can give the inner Container same height as outer container:
class _LayoutTest extends StatelessWidget {
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final newRandom = new Random().nextInt(50);
return new ListView(
children: [
new Container(
color: Colors.orangeAccent,
margin: const EdgeInsets.only(bottom: 20.0),
child: new Row(
children: [
new Container(
color: Colors.pinkAccent,
width: size.width / 5,
height: 200.0 + newRandom,
),
new Expanded(
child: new Container(
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(8.0),
color: Colors.lightGreenAccent,
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
const Text("Top"),
const Text("Bottom"),
],
),
height: 200.0 + newRandom,
),
),
],
),
),
],
);
}
}