【问题标题】:Flutter - Display grid of buttons more dynamicallyFlutter - 更动态地显示按钮网格
【发布时间】:2020-11-14 17:00:05
【问题描述】:

我对 Flutter 和 UI 工作有点陌生。我正在尝试为一周中的几天显示一组单选按钮,并希望包含每一天的框适合文本的长度而不缩小文本。然后我想展示一组中的所有盒子,但要让它们很好地组合在一起。这是我现在所遵循的,以及我想要的:

第二张图片中的方框应该有不同的日子,其中一些会比其他的更宽,但这是我对它的粗略形象化。

我一直在为单个框尝试不同大小的、适合的和有限的框组合,以及一个 gridview 与一个有两行的列来显示一组框。

这是我目前拥有的代码。感谢任何人对使用 Flutter 布局的见解或解释。

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

class TimeRadioModel {
  bool isSelected;
  String timeText;

  TimeRadioModel(this.isSelected, this.timeText);
}

class TimeRadioItem extends StatelessWidget {
  final TimeRadioModel item;
  TimeRadioItem(this.item);

  @override
  Widget build(BuildContext context) {
    return LimitedBox(
      child: Container(
        child: Text(
          item.timeText,
          style: TextStyle(fontSize: 12),
          textAlign: TextAlign.center,
        ),
        padding: EdgeInsets.all(4),
        decoration: BoxDecoration(
          shape: BoxShape.rectangle,
          color: Colors.amber,
          border: item.isSelected ? Border.all(width: 0.1) : null,
          boxShadow: item.isSelected
              ? [
                  BoxShadow(
                    color: Colors.grey.withOpacity(0.3),
                    spreadRadius: 2,
                    blurRadius: 3,
                    offset: Offset(1, 1.5),
                  ),
                ]
              : null,
          borderRadius: BorderRadius.all(Radius.circular(7)),
        ),
      ),
    );
  }
}

class CustomTimeRadio extends StatefulWidget {
  @override
  _CustomTimeRadioState createState() => _CustomTimeRadioState();
}

class _CustomTimeRadioState extends State<CustomTimeRadio> {
  List<TimeRadioModel> timeChoices = new List<TimeRadioModel>();

  final currTime = DateTime.now().weekday;
  // m = 1, t = 2, w = 3, th = 4, f = 5, s = 6, su = 7

  @override
  void initState() {
    super.initState();
    if (currTime == 1) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Wednesday'));
      timeChoices.add(TimeRadioModel(false, 'Thursday'));
      timeChoices.add(TimeRadioModel(false, 'Friday'));
      timeChoices.add(TimeRadioModel(false, 'Saturday'));
      timeChoices.add(TimeRadioModel(false, 'Sunday'));
    } else if (currTime == 2) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Thursday'));
      timeChoices.add(TimeRadioModel(false, 'Friday'));
      timeChoices.add(TimeRadioModel(false, 'Saturday'));
      timeChoices.add(TimeRadioModel(false, 'Sunday'));
      timeChoices.add(TimeRadioModel(false, 'Monday'));
    } else if (currTime == 3) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Friday'));
      timeChoices.add(TimeRadioModel(false, 'Saturday'));
      timeChoices.add(TimeRadioModel(false, 'Sunday'));
      timeChoices.add(TimeRadioModel(false, 'Monday'));
      timeChoices.add(TimeRadioModel(false, 'Tuesday'));
    } else if (currTime == 4) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Saturday'));
      timeChoices.add(TimeRadioModel(false, 'Sunday'));
      timeChoices.add(TimeRadioModel(false, 'Monday'));
      timeChoices.add(TimeRadioModel(false, 'Tuesday'));
      timeChoices.add(TimeRadioModel(false, 'Wednesday'));
    } else if (currTime == 5) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Sunday'));
      timeChoices.add(TimeRadioModel(false, 'Monday'));
      timeChoices.add(TimeRadioModel(false, 'Tuesday'));
      timeChoices.add(TimeRadioModel(false, 'Wednesday'));
      timeChoices.add(TimeRadioModel(false, 'Thursday'));
    } else if (currTime == 6) {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Monday'));
      timeChoices.add(TimeRadioModel(false, 'Tuesday'));
      timeChoices.add(TimeRadioModel(false, 'Wednesday'));
      timeChoices.add(TimeRadioModel(false, 'Thursday'));
      timeChoices.add(TimeRadioModel(false, 'Friday'));
    } else {
      timeChoices.add(TimeRadioModel(false, 'Today'));
      timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
      timeChoices.add(TimeRadioModel(false, 'Tuesday'));
      timeChoices.add(TimeRadioModel(false, 'Wednesday'));
      timeChoices.add(TimeRadioModel(false, 'Thursday'));
      timeChoices.add(TimeRadioModel(false, 'Friday'));
      timeChoices.add(TimeRadioModel(false, 'Saturday'));
    }
    timeChoices.add(TimeRadioModel(false, 'Anytime'));
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 100,
      width: 200,
      child: Column(
        children: [
          Row(
            children: [
              for (int i = 0; i < timeChoices.length - 4; i++)
                IconButton(
                  padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
                  icon: new TimeRadioItem(timeChoices[i]),
                  onPressed: () {
                    setState(() {
                      timeChoices.forEach((element) {
                        element.isSelected = false;
                      });
                      timeChoices[i].isSelected = true;
                    });
                  },
                ),
            ],
          ),
          Row(
            children: [
              for (int i = 4; i < timeChoices.length; i++)
                IconButton(
                  padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
                  icon: new TimeRadioItem(timeChoices[i]),
                  onPressed: () {
                    setState(() {
                      timeChoices.forEach((element) {
                        element.isSelected = false;
                      });
                      timeChoices[i].isSelected = true;
                    });
                  },
                ),
            ],
          )
        ],
      ),
    );
  }
}

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

你可以用换行符代替row

  Wrap(
        children: [
          for (int i = 4; i < timeChoices.length; i++)
            IconButton(
              padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
              icon: new TimeRadioItem(timeChoices[i]),
              onPressed: () {
                setState(() {
                  timeChoices.forEach((element) {
                    element.isSelected = false;
                  });
                  timeChoices[i].isSelected = true;
                });
              },
            ),
        ],
      )

在此处阅读有关 Wrap 小部件的更多信息 https://medium.com/flutter-community/flutter-wrap-widget-e1ee0b005b16

【讨论】:

  • 这适用于安排一组盒子。谢谢!有没有更好的方法来构建我的 TimeRadioItems,使其创建的框的大小与其中的文本长度一致?
  • 你的意思是你想根据容器的文本来设置容器的大小?
【解决方案2】:

我相信在之前的回复的帮助下我能够弄清楚。为了根据文本设置我的日框大小,在 TimeRadioItem 小部件中,我使用了一个根据文本长度计算其宽度的大小框:

return SizedBox(
      width: item.timeText.length * 9.0,
      child: Container(
        child: Text(
          item.timeText,
          style: TextStyle(fontSize: 12),
          textAlign: TextAlign.center,
        ),
        padding: EdgeInsets.fromLTRB(0, 4, 0, 4),
        decoration: BoxDecoration(
          shape: BoxShape.rectangle,
          color: Colors.amber,
          border: item.isSelected ? Border.all(width: 0.1) : null,
          boxShadow: item.isSelected
              ? [
                  BoxShadow(
                    color: Colors.grey.withOpacity(0.3),
                    spreadRadius: 2,
                    blurRadius: 3,
                    offset: Offset(1, 1.5),
                  ),
                ]
              : null,
          borderRadius: BorderRadius.all(Radius.circular(7)),
        ),
      ),
    );

然后,通过使用 Wrap 和 GestureDetector 而不是 IconButton,我可以在我的 CustomTimeRadio 小部件中正确显示日期:

return SizedBox(
      width: 250,
      child: Wrap(
        children: [
          for (int i = 0; i < timeChoices.length; i++)
            GestureDetector(
              child: Container(
                padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
                child: new TimeRadioItem(timeChoices[i]),
              ),
              onTap: () {
                setState(() {
                  timeChoices.forEach((element) {
                    element.isSelected = false;
                  });
                  timeChoices[i].isSelected = true;
                });
              },
            ),
        ],
      ),
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 2020-12-10
    • 2018-07-13
    相关资源
    最近更新 更多