Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fit Container Widget Height to Parent Row Height

I have a web application with the following layout:

enter image description here

I am trying to create a flutter application with a similar layout and this is what I have so far:

enter image description here

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.

like image 340
Morfinismo Avatar asked Dec 10 '22 01:12

Morfinismo


1 Answers

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.

like image 159
Pablo Barrera Avatar answered Jan 19 '23 13:01

Pablo Barrera