Flutter:让 TextField(或任何小部件)仅占用最小的必要空间

问题描述 投票:0回答:1

我是 Flutter 新手,来自 React 和 Vue。

我正在尝试制作一个简单的小部件,用于输入小时和分钟。我认为结果很好,尽管我遇到了小部件伸展以占用所有可用空间的问题。由于每个

TextField
中的最大输入长度为两个字符,因此我不希望它采用全宽。我只需要必要的宽度。

但是,我不喜欢设置明确的宽度。我宁愿将约束简单地传递下去,而我的小部件只使用它需要的东西。 有什么类/小部件可以用于此目的?显然不是

Flexible
。我也尝试过
Alignment
但与 InputDecorator 结合得不好...

import 'package:flutter/material.dart';

class DurationPicker extends StatefulWidget {
  const DurationPicker({super.key});

  @override
  _DurationPickerState createState() => _DurationPickerState();
}

const zwsp = '\u200b';
const zwspEditingValue = TextEditingValue(text: zwsp, selection: TextSelection(baseOffset: 1, extentOffset: 1));

class _DurationPickerState extends State<DurationPicker> {
  List<String> input = ['', ''];
  late List<TextEditingController> controllers;
  late List<FocusNode> focusNodes;
  int hourIndex = 0;
  int minuteIndex = 1;

  _DurationPickerState() {
    controllers = List.generate(2, (index) => TextEditingController());
    controllers.forEach((controller) {
      controller.value = zwspEditingValue;
    });

    focusNodes = List.generate(2, (index) => FocusNode());

    WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
      focusNodes[0].requestFocus();
    });
  }

  @override
  void dispose() {
    super.dispose();
    focusNodes.forEach((focusNode) {
      focusNode.dispose();
    });
    controllers.forEach((controller) {
      controller.dispose();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        const Icon(Icons.access_time),
        const SizedBox(width: 10),
        Flexible(
          child: InputDecorator(
            decoration: const InputDecoration(
              labelText: 'Label',
              border: OutlineInputBorder(
                borderRadius: BorderRadius.all(Radius.circular(10))
                ),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Flexible(
                  child: TextField(
                    expands: false,
                    controller: controllers[hourIndex],
                    focusNode: focusNodes[hourIndex],
                    maxLength: 3,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(
                      counterText: '',
                    ),
                    onChanged: (value) {
                      if (value.length > 2) {
                        focusNodes[minuteIndex].requestFocus();
                      } else if (value.length < 2) {
                        controllers[hourIndex].value = zwspEditingValue;
                      }
                      input[hourIndex] = value.replaceAll(zwsp, '');
                    },
                  ),
                ),
                const Text(':'),
                Flexible(
                  child: TextField(
                    expands: false,
                    controller: controllers[minuteIndex],
                    focusNode: focusNodes[minuteIndex],
                    maxLength: 3,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(
                      counterText: '',
                    ),
                    onChanged: (value) {
                      if (value.length > 2) {
                        FocusScope.of(context).unfocus();
                      } else if (value.length < 2) {
                        controllers[minuteIndex].value = zwspEditingValue;
                        focusNodes[hourIndex].requestFocus();
                      }
                      input[minuteIndex] = value.replaceAll(zwsp, '');
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

如果我没有得到答案,为了缩小问题的范围:我的问题是由文本字段本身引起的,还是由某些家长引起的?

flutter dart constraints width textfield
1个回答
0
投票

您必须用

textField
包裹您的
SizedBox
来固定尺寸:

SizedBox(
width: 250,
child: TextField()
)
© www.soinside.com 2019 - 2024. All rights reserved.