颤音 - 柔性在内部的圆柱上,不带最大列高度

发布于 2025-01-31 12:19:06 字数 8311 浏览 3 评论 0原文

我的flex小部件有问题,里面有一个圆柱,其中孩子的身高固定(约束至min和max)。

我必须构建一个带有许多行的列的屏幕,每行都有一些列的孩子,并且该列的小部件高度有限。

我希望每一行都适合内列的最大高度,同时所有行都适合屏幕的全高度。

我的意思是,我希望孩子身高比他的父母优先。

编辑:我附加了一个图像和代码以查看问题。


class SecheduleDatatable extends StatelessWidget {
  final DateTime initDate;
  final int dayTreshold;
  final List<ActivityItem> items;
  final bool buildHeaders;

  SecheduleDatatable({
    required this.items,
    required this.initDate,
    required this.dayTreshold,
    this.buildHeaders = false,
  });

  final double spaceBetween = 64;
  final double leftPadding = 32;
  double minItemHeight = 100;
  double maxItemHeight = 150;
  double fontSize = 45;
  double headerHeight = 120;

  void _initSizes(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    if (screenWidth > 4000) {
      fontSize = 100;
      minItemHeight = 0;
      maxItemHeight = 180;
      headerHeight = 180;
    } else if (screenWidth > 1920) {
      fontSize = 45;
      minItemHeight = 60;
      maxItemHeight = 120;
      headerHeight = 120;
    } else {
      fontSize = 25;
      minItemHeight = 0;
      maxItemHeight = 80;
      headerHeight = 80;
    }
  }

  @override
  Widget build(BuildContext context) {
    _initSizes(context);
    return Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Flexible(child: _createColumns()),
        ..._createRows(),
      ],
    );
  }

  bool hasToExpand(String time) {
    final days = _createDays(true);
    days.addAll(_createDays(false));
    final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);

    for (DateTime date in days) {
      final tempItems = groupedByTimeSort[time]
          ?.where((element) => element.date.getInitDay() == date.getInitDay())
          .toList();
      if (tempItems != null && tempItems.length > 1) return false;
    }

    return true;
  }

  Widget _createColumns() {
    final days = _createDays(true);
    days.addAll(_createDays(false));

    return IntrinsicHeight(
      child: Row(
        children: [
          Expanded(
              child: Row(
            children: [
              Expanded(child: _clock()),
              Expanded(flex: 3, child: _header(days[0].formatHeaderDate())),
              Expanded(flex: 3, child: _header(days[1].formatHeaderDate())),
            ],
          )),
          /*  Spacer(
            flex: 1,
          ), */
          Expanded(
              child: Row(
            children: [
              Expanded(child: Container()),
              Expanded(flex: 4, child: _header(days[2].formatHeaderDate())),
              Expanded(flex: 4, child: _header(days[3].formatHeaderDate())),
              Expanded(child: Container())
            ],
          )),
        ],
      ),
    );
  }

  List<Widget> _createRows() {
    final days = _createDays(true);
    days.addAll(_createDays(false));
    final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);

    Widget _getItemByDate(String time, DateTime date) {
      final maybeItems = groupedByTimeSort[time]
          ?.where((element) => element.date.getInitDay() == date.getInitDay());
      if (maybeItems != null) {
        return Column(
            mainAxisSize: MainAxisSize.min,
            children: maybeItems
                .map((e) => hasToExpand(time)
                    ? Flexible(child: _item(e, kSpacing / 2))
                    : Flexible(child: _item(e, 0)))
                .toList());
      } else {
        return Container();
      }
    }

    Widget _getItem(String time, int pos, int flex) {
      return Expanded(flex: flex, child: IntrinsicHeight(child: _getItemByDate(time, days[pos])));
    }

    final rows = groupedByTimeSort.keys.map((time) {
      final row = Flexible(
          child: IntrinsicHeight(
              child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
              child: IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Expanded(child: _hour(time)),
                _getItem(time, 0, 3),
                _getItem(time, 1, 3),
              ],
            ),
          )),
          Expanded(
              child: IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Expanded(child: Container()),
                _getItem(time, 2, 4),
                _getItem(time, 3, 4),
                Expanded(child: Container()),
              ],
            ),
          ))
        ],
      )));

      /* final row = IntrinsicHeight(
          child: Row(children: [
        Expanded(child: _hour(time)),
        ...days.map((date) => Expanded(flex: 3, child: _getItemByDate(time, date))).toList()
      ])); */

      return row;
    }).toList();

    return rows;
  }

  Widget _item(ActivityItem item, double spacing) {
    return Container(
        width: double.infinity,
        margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
        padding: EdgeInsets.all(spacing),
        decoration: BoxDecoration(
            color: item.activityModel!.color, borderRadius: BorderRadius.circular(15)),
        child: Center(
          child: Text(
            item.activityModel!.getTitle(),
            maxLines: 1,
            textAlign: TextAlign.center,
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
          ),
        ));
  }

  Widget _emptyItem() {
    return Container(
        // constraints: BoxConstraints(minHeight: minItemHeight, maxHeight: maxItemHeight),
        width: double.infinity,
        margin: EdgeInsets.symmetric(vertical: 1),
        padding: EdgeInsets.all(kSpacing / 2),
        child: FittedBox(
          fit: BoxFit.scaleDown,
          child: Text(
            "",
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
          ),
        ));
  }

  Widget _clock() {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
      decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
      child: FittedBox(
        fit: BoxFit.contain,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Icon(
            FeatherIcons.clock,
          ),
        ),
      ),
    );
  }

  Widget _hour(String time) {
    return Container(
      margin: EdgeInsets.all(2),
      padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
      decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
      child: Align(
        alignment: Alignment.topCenter,
        child: FittedBox(
          fit: BoxFit.contain,
          child: Text(
            time,
            style: TextStyle(color: Colors.white, fontSize: fontSize, fontWeight: FontWeight.bold),
          ),
        ),
      ),
    );
  }

  Widget _header(String text) {
    return Container(
        height: headerHeight,
        margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
        padding: EdgeInsets.all(kSpacing / 2),
        decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
        child: Align(
          alignment: Alignment.center,
          child: FittedBox(
            child: Text(
              text,
              textAlign: TextAlign.center,
              style:
                  TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
            ),
          ),
        ));
  }

  List<DateTime> _createDays(bool first) {
    final days = first ? [initDate] : [initDate.add(Duration(days: dayTreshold ~/ 2))];
    for (var i = first ? 1 : dayTreshold ~/ 2;
        i < (first ? dayTreshold ~/ 2 : dayTreshold - 1);
        i++) {
      days.add(days.last.add(Duration(days: 1)));
    }

    return days;
  }
}

我希望父行是Column Child的高度。请注意,这些行灵活以适合筛选更改的响应能力。

因此,总而言之,我希望行是响应性,但其内部列获得最大高度。

对不起,不容易解释它。

I'm having problems with flex widget with a column inside where the children have a fixed height (constrained to min and max).

I have to build a screen with a column with many rows as children and each row has some column children and this column has widgets with restricted height.

I want each row to fit the maximum height of the inner column and at the same time all rows to fit the full height of the screen.

I mean, I want the children height has priority over his parent.

EDIT: I attached an image and the code to see the problem.


class SecheduleDatatable extends StatelessWidget {
  final DateTime initDate;
  final int dayTreshold;
  final List<ActivityItem> items;
  final bool buildHeaders;

  SecheduleDatatable({
    required this.items,
    required this.initDate,
    required this.dayTreshold,
    this.buildHeaders = false,
  });

  final double spaceBetween = 64;
  final double leftPadding = 32;
  double minItemHeight = 100;
  double maxItemHeight = 150;
  double fontSize = 45;
  double headerHeight = 120;

  void _initSizes(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    if (screenWidth > 4000) {
      fontSize = 100;
      minItemHeight = 0;
      maxItemHeight = 180;
      headerHeight = 180;
    } else if (screenWidth > 1920) {
      fontSize = 45;
      minItemHeight = 60;
      maxItemHeight = 120;
      headerHeight = 120;
    } else {
      fontSize = 25;
      minItemHeight = 0;
      maxItemHeight = 80;
      headerHeight = 80;
    }
  }

  @override
  Widget build(BuildContext context) {
    _initSizes(context);
    return Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Flexible(child: _createColumns()),
        ..._createRows(),
      ],
    );
  }

  bool hasToExpand(String time) {
    final days = _createDays(true);
    days.addAll(_createDays(false));
    final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);

    for (DateTime date in days) {
      final tempItems = groupedByTimeSort[time]
          ?.where((element) => element.date.getInitDay() == date.getInitDay())
          .toList();
      if (tempItems != null && tempItems.length > 1) return false;
    }

    return true;
  }

  Widget _createColumns() {
    final days = _createDays(true);
    days.addAll(_createDays(false));

    return IntrinsicHeight(
      child: Row(
        children: [
          Expanded(
              child: Row(
            children: [
              Expanded(child: _clock()),
              Expanded(flex: 3, child: _header(days[0].formatHeaderDate())),
              Expanded(flex: 3, child: _header(days[1].formatHeaderDate())),
            ],
          )),
          /*  Spacer(
            flex: 1,
          ), */
          Expanded(
              child: Row(
            children: [
              Expanded(child: Container()),
              Expanded(flex: 4, child: _header(days[2].formatHeaderDate())),
              Expanded(flex: 4, child: _header(days[3].formatHeaderDate())),
              Expanded(child: Container())
            ],
          )),
        ],
      ),
    );
  }

  List<Widget> _createRows() {
    final days = _createDays(true);
    days.addAll(_createDays(false));
    final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);

    Widget _getItemByDate(String time, DateTime date) {
      final maybeItems = groupedByTimeSort[time]
          ?.where((element) => element.date.getInitDay() == date.getInitDay());
      if (maybeItems != null) {
        return Column(
            mainAxisSize: MainAxisSize.min,
            children: maybeItems
                .map((e) => hasToExpand(time)
                    ? Flexible(child: _item(e, kSpacing / 2))
                    : Flexible(child: _item(e, 0)))
                .toList());
      } else {
        return Container();
      }
    }

    Widget _getItem(String time, int pos, int flex) {
      return Expanded(flex: flex, child: IntrinsicHeight(child: _getItemByDate(time, days[pos])));
    }

    final rows = groupedByTimeSort.keys.map((time) {
      final row = Flexible(
          child: IntrinsicHeight(
              child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
              child: IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Expanded(child: _hour(time)),
                _getItem(time, 0, 3),
                _getItem(time, 1, 3),
              ],
            ),
          )),
          Expanded(
              child: IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Expanded(child: Container()),
                _getItem(time, 2, 4),
                _getItem(time, 3, 4),
                Expanded(child: Container()),
              ],
            ),
          ))
        ],
      )));

      /* final row = IntrinsicHeight(
          child: Row(children: [
        Expanded(child: _hour(time)),
        ...days.map((date) => Expanded(flex: 3, child: _getItemByDate(time, date))).toList()
      ])); */

      return row;
    }).toList();

    return rows;
  }

  Widget _item(ActivityItem item, double spacing) {
    return Container(
        width: double.infinity,
        margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
        padding: EdgeInsets.all(spacing),
        decoration: BoxDecoration(
            color: item.activityModel!.color, borderRadius: BorderRadius.circular(15)),
        child: Center(
          child: Text(
            item.activityModel!.getTitle(),
            maxLines: 1,
            textAlign: TextAlign.center,
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
          ),
        ));
  }

  Widget _emptyItem() {
    return Container(
        // constraints: BoxConstraints(minHeight: minItemHeight, maxHeight: maxItemHeight),
        width: double.infinity,
        margin: EdgeInsets.symmetric(vertical: 1),
        padding: EdgeInsets.all(kSpacing / 2),
        child: FittedBox(
          fit: BoxFit.scaleDown,
          child: Text(
            "",
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
          ),
        ));
  }

  Widget _clock() {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
      decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
      child: FittedBox(
        fit: BoxFit.contain,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Icon(
            FeatherIcons.clock,
          ),
        ),
      ),
    );
  }

  Widget _hour(String time) {
    return Container(
      margin: EdgeInsets.all(2),
      padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
      decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
      child: Align(
        alignment: Alignment.topCenter,
        child: FittedBox(
          fit: BoxFit.contain,
          child: Text(
            time,
            style: TextStyle(color: Colors.white, fontSize: fontSize, fontWeight: FontWeight.bold),
          ),
        ),
      ),
    );
  }

  Widget _header(String text) {
    return Container(
        height: headerHeight,
        margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
        padding: EdgeInsets.all(kSpacing / 2),
        decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
        child: Align(
          alignment: Alignment.center,
          child: FittedBox(
            child: Text(
              text,
              textAlign: TextAlign.center,
              style:
                  TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
            ),
          ),
        ));
  }

  List<DateTime> _createDays(bool first) {
    final days = first ? [initDate] : [initDate.add(Duration(days: dayTreshold ~/ 2))];
    for (var i = first ? 1 : dayTreshold ~/ 2;
        i < (first ? dayTreshold ~/ 2 : dayTreshold - 1);
        i++) {
      days.add(days.last.add(Duration(days: 1)));
    }

    return days;
  }
}

I want that the parent row take height of column child. Notice the rows are flexible to fit responsiveness to screen changes.

So really, in summarize, I want the rows are responsiveness but its inner columns get max height.

Sorry is not easy to explain it.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

z祗昰~ 2025-02-07 12:19:06

我添加了SinglechildScrollview,并将列的容器的高度设置为80个项目的320


导入'软件包:flutter/chestures.dart';

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      
        primarySwatch: Colors.blue,
      ),
       scrollBehavior: MyCustomScrollBehavior(),
      debugShowCheckedModeBanner:false,
      home: Test_Flexible(),
    );
  }
}

class Test_Flexible extends StatefulWidget {
  Test_Flexible({Key? key}) : super(key: key);

  @override
  State<Test_Flexible> createState() => _Test_FlexibleState();
}

class _Test_FlexibleState extends State<Test_Flexible> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text("Test Flexible"),) ,body: 
    SingleChildScrollView(child:
    Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
      Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
        Expanded(
          flex: 1,
          child: Container(
            height: 100,
            color: Colors.orange,
          )),

        Expanded(
          flex: 3,
          child: Container(
            height: 320,
            color: Colors.blue,
            child:(Column(children:[
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.purple,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.green,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.yellow,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.pink,
                ),
              ),
            ]))
          )),
      
          Expanded(
          flex: 3,
          child: Container(
            height: 100,
            color: Colors.blueGrey,
          )),

      ],)
    ])
    ,));
  }
}

I added singlechildscrollview and I set the height of the container for the column items at 320 for four items of 80.

import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      
        primarySwatch: Colors.blue,
      ),
       scrollBehavior: MyCustomScrollBehavior(),
      debugShowCheckedModeBanner:false,
      home: Test_Flexible(),
    );
  }
}

class Test_Flexible extends StatefulWidget {
  Test_Flexible({Key? key}) : super(key: key);

  @override
  State<Test_Flexible> createState() => _Test_FlexibleState();
}

class _Test_FlexibleState extends State<Test_Flexible> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text("Test Flexible"),) ,body: 
    SingleChildScrollView(child:
    Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
      Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
        Expanded(
          flex: 1,
          child: Container(
            height: 100,
            color: Colors.orange,
          )),

        Expanded(
          flex: 3,
          child: Container(
            height: 320,
            color: Colors.blue,
            child:(Column(children:[
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.purple,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.green,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.yellow,
                ),
              ),
              Flexible(
                child: Container(
                  height: 80,
                  color: Colors.pink,
                ),
              ),
            ]))
          )),
      
          Expanded(
          flex: 3,
          child: Container(
            height: 100,
            color: Colors.blueGrey,
          )),

      ],)
    ])
    ,));
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文