A design like I want:
This is the current design:
Hello. How to change the position of the button and make the button design like the picture I show. I have tried to make it myself but still failed to get the design as in the picture I showed. I am new to flutter. Please guide me and hope someone is willing to help me.
This is my current code:
Container(
padding: const EdgeInsets.symmetric(horizontal: 150),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 35),
Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
border: Border.all(
color: Colors.transparent,
width: 1.0,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child: Center(
child: FutureBuilder(
future:
_getSignedURL(widget.patientProfile.avatar),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
color: Colors.white,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color:
Color.fromRGBO(255, 255, 255, 0.3),
border: Border.all(
color: Colors.black12,
width: 1.0,
),
borderRadius: BorderRadius.all(
Radius.circular(200.0)),
),
),
);
} else {
return CircleAvatar(
radius: 100,
backgroundImage:
NetworkImage(snapshot.data),
);
}
},
),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
border: Border.all(
color: Colors.transparent,
width: 1.0,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.centerRight,
child: ButtonTheme(
minWidth: 100.0,
height: 38.0,
buttonColor: mainColor,
// ignore: deprecated_member_use
child: RaisedButton(
padding: EdgeInsets.fromLTRB(30, 0, 30, 0),
textColor: Colors.white,
color: mainColor,
child: Text('Save'),
onPressed: () => _updatePatientProfile(),
),
),
)),
),
],
),
),
],
),
),
Play with Stack widget, there are others way of doing this.
class B extends StatefulWidget {
B({Key? key}) : super(key: key);
#override
State<B> createState() => _BState();
}
class _BState extends State<B> {
Color mainColor = Colors.blue;
#override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Column(
children: [
Column(
children: [
Container(
color: Colors.cyanAccent,
height: 200 + 70 + 60, // based on circle+ text space
child: Stack(
clipBehavior: Clip.none,
children: <Widget>[
// divider
Align(
alignment: Alignment(0, -.35),
child: Container(
width: constraints.maxWidth,
height: 8,
color: mainColor,
)),
Positioned(
top: 40,
left: 100,
child: Column(
children: [
CircleAvatar(
radius: 100,
),
SizedBox(
height: 70,
),
Text(
"Dumasd Text A",
textAlign: TextAlign.center,
),
],
),
),
Align(
alignment: Alignment(.7, .25),
child: saveProfile(),
)
],
),
),
],
),
],
),
),
);
}
ButtonTheme saveProfile() {
return ButtonTheme(
minWidth: 100.0,
height: 38.0,
buttonColor: mainColor,
// ignore: deprecated_member_use
child: RaisedButton(
padding: EdgeInsets.fromLTRB(30, 0, 30, 0),
textColor: Colors.white,
color: mainColor,
child: Text('Save'),
onPressed: () {}),
);
}
}
Play with Positioned and Alignment
I have the following view.
I would like the "confirm" button to always appear at the bottom of the slide up panel no matter what device is being used. If I position at the bottom correctly using padding or empty containers it is cut off on smaller screen size. Or if I position correctly on a smaller screen I am now running into issues with white space at the bottom. I am using the safe area widget which I thought ensured all widgets stay within the SafeArea?
Here is my code so far:
class ChooseAppointmentView extends StatefulWidget {
#override
_ChooseAppointmentViewState createState() => _ChooseAppointmentViewState();
}
class _ChooseAppointmentViewState extends State<ChooseAppointmentView> {
final List<Appointment> appointmentList = [
Appointment("Monday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Tuesday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Wednesday", DateTime.now(), DateTime.now(), "PM"),
Appointment("Thursday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Friday", DateTime.now(), DateTime.now(), "PM"),
];
DateTime _dateSelected = DateTime.now();
DateTime _initialiseDate = DateTime.now();
#override
Widget build(BuildContext context) {
BorderRadiusGeometry radius = BorderRadius.only(
topLeft: Radius.circular(24.0),
topRight: Radius.circular(24.0),
);
return BaseView<ConfirmDetailsViewModel>(
builder: (context, model, child) => Scaffold(
backgroundColor: AppColours.primaryColour,
body: SafeArea(
child: WillPopScope(
onWillPop: () async {
return false;
},
child: SlidingUpPanel(
maxHeight: MediaQuery.of(context).size.height * .80,
minHeight: 75.0,
parallaxEnabled: true,
parallaxOffset: .5,
panel: Stack(
children: <Widget>[
Center(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.02),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 30,
height: 5,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius:
BorderRadius.all(Radius.circular(12.0))),
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.02),
Container(
child: Text(
"Select a date in here.",
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 24.0,
),
),
),
Container(
height: MediaQuery.of(context).size.height * 0.05),
Container(
height: 200,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
minimumDate: _initialiseDate,
maximumDate: _initialiseDate.add(Duration(days: 7)),
initialDateTime: _initialiseDate,
onDateTimeChanged: (dateSelected) {
setState(() {
_dateSelected = dateSelected;
});
},
),
),
Container(
height: MediaQuery.of(context).size.height * 0.05),
Container(
height: 50.0,
width: MediaQuery.of(context).size.width - 50,
child: RaisedButton(
onPressed: () async {
//await model.submit();
Navigator.push(
context,
SizeRoute(
page: ChooseAppointmentView(),
),
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
child: Text('Confirm'),
color: AppColours.primaryLightColour,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
),
),
],
),
),
],
),
collapsed: Center(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.02),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 30,
height: 5,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius:
BorderRadius.all(Radius.circular(12.0))),
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.02),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: radius),
child: Center(
child: Text(
"Select a different date",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 20.0,
),
),
),
),
],
),
),
body: Container(
decoration: BoxDecoration(color: Colors.white),
child: ListView.builder(
padding: EdgeInsets.only(bottom: 100.0),
itemCount: appointmentList.length,
itemBuilder: (BuildContext context, int index) =>
buildAppointmentCards(context, index),
),
),
borderRadius: radius,
),
),
),
),
);
}
Widget buildAppointmentCards(BuildContext context, int index) {
final appointment = appointmentList[index];
return Padding(
padding: const EdgeInsets.all(10.0),
child: Material(
color: Colors.white.withOpacity(0.0),
child: InkWell(
splashColor: Colors.red,
onTap: () {
print('card tapped');
},
child: new Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
gradient: LinearGradient(
colors: [
AppColours.primaryColour,
AppColours.primaryLightColour,
AppColours.primaryLighterColour,
//add more colors for gradient
],
begin: Alignment.topLeft, //begin of the gradient color
end: Alignment.bottomRight, //end of the gradient color
stops: [0, 0.2, 0.5] //stops for individual color
//set the stops number equal to numbers of color
),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: Container(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: Row(
children: <Widget>[
Text(
appointment.day,
style:
TextStyle(fontSize: 30.0, color: Colors.white),
),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 80.0),
child: Row(
children: <Widget>[
Text(
"${DateFormat('hh:mm').format(appointment.date).toString()} - ${DateFormat('hh:mm').format(appointment.date).toString()}",
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Row(
children: <Widget>[
Text(
DateFormat(
'dd/MM/yyyy',
).format(appointment.date).toString(),
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
Spacer(),
Text(
appointment.ampm,
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
],
),
)
],
),
),
),
),
),
),
);
}
}
[enter link description here][2]
I think you can use the Align widget for positioning your widget in Stack. For more information can see in this link in this link you will see examples including explanation in the video.
I have a web application with the following layout:
I am trying to create a flutter application with a similar layout and this is what I have so far:
For reproduction purposes, my layout logic is the following (all my code is in the main.dart file for this example):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Assemblers Tasks',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepOrange,
),
home: MyHomePage(title: 'Assembly Tasks'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownValue;
List<Map<String, dynamic>> buildItems = [];
getBuilds() {
List<Map<String, dynamic>> items = [];
items.add({"id": 10, "vehicleModel": "A10", "vehicleNumber": "TEST-00010"});
setState(() {
buildItems = items;
});
}
List<Map<String, dynamic>> buildSections = [];
getSections() {
List<Map<String, dynamic>> items = [];
items.add({
"id": 5,
"section": "Front",
});
items.add({
"id": 15,
"section": "Rear",
});
setState(() {
buildSections = items;
});
}
Future<List<Map<String, dynamic>>> getSystems(String buildSectionId) async {
List<Map<String, dynamic>> items = [];
if (int.parse(buildSectionId) == 5) {
items.add({
"id": 4,
"system": "Hydraulics",
});
items.add({
"id": 20,
"system": "High Voltage",
});
}
return items;
}
#override
void initState() {
getBuilds();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 275.0,
child: DropdownButton(
value: dropdownValue,
hint: Text("Choose Build"),
isExpanded: true,
items: buildItems
.map<Map<String, String>>((Map<String, dynamic> item) {
String id = item["id"].toString();
String name = item["vehicleModel"] + " " + item["vehicleNumber"];
return {"id": id, "name": name};
})
.toList()
.map<DropdownMenuItem<String>>((Map<String, String> item) {
return DropdownMenuItem<String>(
value: item["id"],
child: Text(item["name"]),
);
})
.toList(),
onChanged: (String newValue) {
getSections();
setState(() {
dropdownValue = newValue;
});
}),
),
],
),
Row(
children: <Widget>[
Container(
width: 150.0,
height: 60.0,
color: Colors.black,
child: Align(
alignment: Alignment.center,
child: Text(
"SECTION",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Container(
width: 150.0,
height: 60.0,
color: Color(0xff444444),
child: Align(
alignment: Alignment.center,
child: Text(
"SYSTEM",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Expanded(
child: Container(
height: 60.0,
padding: EdgeInsets.only(left: 36.0),
margin: EdgeInsets.only(right: 72.0),
color: Color(0xff666666),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"TASK",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.black12, width: 1.0, style: BorderStyle.solid)),
height: MediaQuery.of(context).size.height - 225,
child: ListView.builder(
shrinkWrap: true,
itemCount: buildSections.length,
itemBuilder: (BuildContext context, int index) {
String section = buildSections[index]["section"] != null ? buildSections[index]["section"] : "";
String buildSectionId = buildSections[index]["id"].toString();
return Row(
children: <Widget>[
Container(
width: 150.0,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.black12,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
padding: EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: Center(
child: RotatedBox(
quarterTurns: -1,
child: Text(
section.toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
),
Padding(
padding: EdgeInsets.all(12.0),
),
Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(Icons.image),
),
),
],
),
),
FutureBuilder(
future: getSystems(buildSectionId),
builder: (BuildContext context, AsyncSnapshot systemsSnap) {
if (systemsSnap.connectionState == ConnectionState.waiting) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Please wait..."),
);
} else if (systemsSnap.hasError) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Oops! There was an error!"),
);
}
return Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width - 256.0,
child: ListView.builder(
shrinkWrap: true,
itemCount: systemsSnap.data.length,
itemBuilder: (context, index) {
Map<String, dynamic> system = systemsSnap.data[index];
String systemName = system["system"];
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
width: 150.0,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.black12,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
child: Column(
children: <Widget>[
Align(
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
systemName.toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
Padding(
padding: EdgeInsets.all(12.0),
),
Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(Icons.image),
),
),
],
),
),
],
);
},
),
),
],
);
},
),
],
);
},
),
),
),
Container(
padding: EdgeInsets.fromLTRB(16.0, 16.0, 0.0, 0.0),
child: Column(
children: <Widget>[
Container(
child: FloatingActionButton(
child: Icon(Icons.photo_library),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.library_books),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.list),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.history),
onPressed: () {
//TODO action
},
),
),
],
),
),
],
),
],
),
),
);
}
}
The above code is ready to be pasted into the main.dart file and preview on a the virtual device (preferably tablet).
So far I have tried the solutions I found on these posts to no avail:
- Make container widget fill parent vertically
- Flutter Container height same as parent height
- Flutter expand Container to fill remaining space of Row
- The equivalent of wrap_content and match_parent in flutter?
Since the Row that contains the section Container also has a ListView being generated with the FutureBuilder, the height of the Row automatically expands to fit the ListView. I also want the section Container to expand to the same height as the how the Row widget is expanding; i.e., The bottom border of the section Container that says FRONT, should be aligned with the bottom border of the Hight Voltage system and the right border of the FRONT section Container, should go all the way to the top.
I already spent 3 days without a resolution.
Edit
I have tried the suggestion on the answer provided by #MaadhavSharma but I get the following exception:
════════ Exception Caught By rendering library ════════════════════════════
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite height.
I changed a little the structure to make it work, here is the entire build() method:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 275.0,
child: DropdownButton(
value: dropdownValue,
hint: Text("Choose Build"),
isExpanded: true,
items: buildItems
.map<Map<String, String>>((Map<String, dynamic> item) {
String id = item["id"].toString();
String name = item["vehicleModel"] + " " + item["vehicleNumber"];
return {"id": id, "name": name};
})
.toList()
.map<DropdownMenuItem<String>>((Map<String, String> item) {
return DropdownMenuItem<String>(
value: item["id"],
child: Text(item["name"]),
);
})
.toList(),
onChanged: (String newValue) {
getSections();
setState(() {
dropdownValue = newValue;
});
}),
),
],
),
Row(
children: <Widget>[
Container(
width: 150.0,
height: 60.0,
color: Colors.black,
child: Align(
alignment: Alignment.center,
child: Text(
"SECTION",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Container(
width: 150.0,
height: 60.0,
color: Color(0xff444444),
child: Align(
alignment: Alignment.center,
child: Text(
"SYSTEM",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Expanded(
child: Container(
height: 60.0,
padding: EdgeInsets.only(left: 36.0),
margin: EdgeInsets.only(right: 72.0),
color: Color(0xff666666),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"TASK",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.black12, width: 1.0, style: BorderStyle.solid)),
height: MediaQuery.of(context).size.height - 225,
child: ListView.builder(
shrinkWrap: true,
itemCount: buildSections.length,
itemBuilder: (BuildContext context, int index) {
String section = buildSections[index]["section"] != null ? buildSections[index]["section"] : "";
String buildSectionId = buildSections[index]["id"].toString();
return IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 150.0,
decoration: BoxDecoration(
color: Colors.green,
border: Border(
right: BorderSide(
color: Colors.black12,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
padding: EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: Center(
child: RotatedBox(
quarterTurns: -1,
child: Text(
section.toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
),
Padding(
padding: EdgeInsets.all(12.0),
),
Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(Icons.image),
),
),
],
),
),
FutureBuilder(
future: getSystems(buildSectionId),
builder: (BuildContext context, AsyncSnapshot systemsSnap) {
if (systemsSnap.connectionState == ConnectionState.waiting) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Please wait..."),
);
} else if (systemsSnap.hasError) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Oops! There was an error!"),
);
}
return
Container(
width: MediaQuery.of(context).size.width - 256.0,
child: Column(
children: systemsSnap.data.map<Widget>((e) => Container(
padding: EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
width: 150.0,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.black12,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
child: Column(
children: <Widget>[
Align(
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
e["system"].toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
Padding(
padding: EdgeInsets.all(12.0),
),
Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(Icons.image),
),
),
],
),
)).toList(),
),
);
// Row(
// children: <Widget>[
// Container(
// width: MediaQuery.of(context).size.width - 256.0,
// child: ListView.builder(
// shrinkWrap: true,
// itemCount: systemsSnap.data.length,
// itemBuilder: (context, index) {
// Map<String, dynamic> system = systemsSnap.data[index];
// String systemName = system["system"];
// return Row(
// children: <Widget>[
//
// ],
// );
// },
// ),
// ),
// ],
// );
},
),
],
),
);
},
),
),
),
Container(
padding: EdgeInsets.fromLTRB(16.0, 16.0, 0.0, 0.0),
child: Column(
children: <Widget>[
Container(
child: FloatingActionButton(
child: Icon(Icons.photo_library),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.library_books),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.list),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.history),
onPressed: () {
//TODO action
},
),
),
],
),
),
],
),
],
),
),
);
}
Basically I changed the ListView of the second element of the Row for a Column, since it already was inside a ListView and that was making it have double scroll and the heights weren't expanding the height of the row properly, and also I wrapped the Row inside an IntrinsicHeight and put crossAxisAlignment: CrossAxisAlignment.stretch to the Row so the content will fit the height of the Row.
The use of IntrinsicHeight is expensive, but I don't see another solution for the way you structured the widgets. I recommend you to try to optimize all the structure so you could find a better and optimal solution.
If you want to stretch the Container to match its parent, use double.infinity for the height and width properties
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container as a layout')),
body: Container(
height: double.infinity,
width: double.infinity,
color: Colors.yellowAccent,
child: Text("Hi"),
),
);
}
The trick is to use constraints: BoxConstraints.expand() in some of your containers that you want to expand to fill the row height.
Try something like this:
Scaffold(
appBar: AppBar(
title: Text("Title"),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
color: Colors.yellow,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints: BoxConstraints.expand(),
color: Colors.blue,
child: Text("box 1")),
),
Expanded(
flex: 2,
child: Container(
constraints: BoxConstraints.expand(),
color: Colors.red,
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
padding:
EdgeInsets.fromLTRB(0, 0, 0, 0),
color: Colors.yellow,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints:
BoxConstraints.expand(),
color: Colors.lightGreen,
child: Text("box 2")),
),
Expanded(
flex: 2,
child: Container(
constraints:
BoxConstraints.expand(),
color: Colors.lightBlue,
child: Text("box 3")),
),
],
),
),
),
Expanded(
flex: 1,
child: Container(
padding:
EdgeInsets.fromLTRB(0, 0, 0, 0),
color: Colors.yellow,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints:
BoxConstraints.expand(),
color: Colors.purple,
child: Text("box 4")),
),
Expanded(
flex: 2,
child: Container(
constraints:
BoxConstraints.expand(),
color: Colors.orange,
child: Text("")),
),
],
),
),
),
],
)),
),
],
),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
color: Colors.yellow,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints: BoxConstraints.expand(),
color: Colors.yellow,
child: Text("box 5")),
),
Expanded(
flex: 2,
child: Container(
constraints: BoxConstraints.expand(),
color: Colors.green,
child: Text("box 6")),
),
],
),
),
),
],
)),
);
I think you will need to use some fixed heights since you are using ListView and FutureBuiulders. If you can get rid of FutureBuilders, you can probably achieve dynamic heights. Notice the hright of 320 on the parent row and height of 160 on child rows.
But have a look at this:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Assemblers Tasks',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepOrange,
),
home: MyHomePage(title: 'Assembly Tasks'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownValue;
List<Map<String, dynamic>> buildItems = [];
getBuilds() {
List<Map<String, dynamic>> items = [];
items.add({"id": 10, "vehicleModel": "A10", "vehicleNumber": "TEST-00010"});
setState(() {
buildItems = items;
});
}
List<Map<String, dynamic>> buildSections = [];
getSections() {
List<Map<String, dynamic>> items = [];
items.add({
"id": 5,
"section": "Front",
});
items.add({
"id": 15,
"section": "Rear",
});
setState(() {
buildSections = items;
});
}
Future<List<Map<String, dynamic>>> getSystems(String buildSectionId) async {
List<Map<String, dynamic>> items = [];
if (int.parse(buildSectionId) == 5) {
items.add({
"id": 4,
"system": "Hydraulics",
});
items.add({
"id": 20,
"system": "High Voltage",
});
}
return items;
}
#override
void initState() {
getBuilds();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 275.0,
child: DropdownButton(
value: dropdownValue,
hint: Text("Choose Build"),
isExpanded: true,
items: buildItems
.map<Map<String, String>>(
(Map<String, dynamic> item) {
String id = item["id"].toString();
String name = item["vehicleModel"] +
" " +
item["vehicleNumber"];
return {"id": id, "name": name};
})
.toList()
.map<DropdownMenuItem<String>>(
(Map<String, String> item) {
return DropdownMenuItem<String>(
value: item["id"],
child: Text(item["name"]),
);
})
.toList(),
onChanged: (String newValue) {
getSections();
setState(() {
dropdownValue = newValue;
});
}),
),
],
),
Row(
children: <Widget>[
Container(
width: 150.0,
height: 60.0,
color: Colors.black,
child: Align(
alignment: Alignment.center,
child: Text(
"SECTION",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Container(
width: 150.0,
height: 60.0,
color: Color(0xff444444),
child: Align(
alignment: Alignment.center,
child: Text(
"SYSTEM",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
Expanded(
child: Container(
height: 60.0,
padding: EdgeInsets.only(left: 36.0),
margin: EdgeInsets.only(right: 72.0),
color: Color(0xff666666),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"TASK",
style: TextStyle(
color: Colors.white,
fontSize: 17.3,
letterSpacing: 1.35,
),
),
),
),
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black12,
width: 1.0,
style: BorderStyle.solid)),
height: MediaQuery.of(context).size.height - 225,
child: ListView.builder(
shrinkWrap: true,
itemCount: buildSections.length,
itemBuilder: (BuildContext context, int index) {
String section = buildSections[index]["section"] != null
? buildSections[index]["section"]
: "";
String buildSectionId =
buildSections[index]["id"].toString();
return Container(
height: 320,
child: Row(
children: <Widget>[
Container(
width: 120.0,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.yellow,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
padding:
EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: Center(
child: RotatedBox(
quarterTurns: -1,
child: Text(
section.toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
),
Padding(
padding: EdgeInsets.all(12.0),
),
Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(Icons.image),
),
),
],
),
),
Expanded(
child: Container(
color: Colors.orange,
child: false ? Text(" ") : FutureBuilder(
future: getSystems(buildSectionId),
builder: (BuildContext context,
AsyncSnapshot systemsSnap) {
if (systemsSnap.connectionState ==
ConnectionState.waiting) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Please wait..."),
);
} else if (systemsSnap.hasError) {
return Container(
height: 100.0,
width: 200.0,
child: Text("Oops! There was an error!"),
);
}
return Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width -
256.0,
child: ListView.builder(
shrinkWrap: true,
itemCount: systemsSnap.data.length,
itemBuilder: (context, index) {
Map<String, dynamic> system =
systemsSnap.data[index];
String systemName = system["system"];
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(
0.0, 16.0, 0.0, 16.0),
width: 50.0,
height: 160,
decoration: BoxDecoration(
color: Colors.yellow,
border: Border(
right: BorderSide(
color: Colors.red,
width: 1.0,
),
bottom: BorderSide(
color: Colors.black12,
width: 1.0,
),
),
),
child: Column(
children: <Widget>[
Align(
alignment:
Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
systemName
.toUpperCase(),
style: TextStyle(
fontSize: 15.0,
letterSpacing: 1.2,
),
),
),
),
],
),
),
],
);
},
),
),
],
);
},
),
),
),
],
),
);
},
),
),
),
Container(
padding: EdgeInsets.fromLTRB(16.0, 16.0, 0.0, 0.0),
child: Column(
children: <Widget>[
Container(
child: FloatingActionButton(
child: Icon(Icons.photo_library),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.library_books),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.list),
onPressed: () {
//TODO action
},
),
),
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
child: FloatingActionButton(
child: Icon(Icons.history),
onPressed: () {
//TODO action
},
),
),
],
),
),
],
),
],
),
),
);
}
}