如何调整 TextField() 文本的大小以适应 Expanded() 小部件的最大宽度

Posted

技术标签:

【中文标题】如何调整 TextField() 文本的大小以适应 Expanded() 小部件的最大宽度【英文标题】:How to resize TextField() text to fit the max width of an Expanded() widget 【发布时间】:2022-01-03 07:44:54 【问题描述】:

我想调整 TextField() 小部件的文本大小,以适应其父 Expanded() 的最大宽度,此宽度由 flex: 10 确定,如您在代码中所见。

但是,我不知道如何才能达到这个结果。我也尝试了AutoSizeTextField() package,但没有成功。也许有人可以弄清楚如何做到这一点。

提前谢谢你。

编辑。如果不清楚,则由用户输入文本。我想动态调整它的大小。下图只是用户输入“This text should be resized”时应用的当前行为示例。

编辑。我更新了代码,以便清楚我想要做什么。

我有一个交易清单。当用户点击交易时,会弹出一个对话框,让用户编辑他提供的信息。

这是调用对话框的代码,对话框是 ModificaTransazione()。

Material(
            color: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
            child: InkWell(
              borderRadius: BorderRadius.circular(10),
              onTap: () 
                //sleep(Duration(milliseconds: 800));
                showDialog(
                  context: context,
                  builder: (context) 
                    return Dialog(
                      insetPadding: EdgeInsets.only(
                          bottom: 0.0), //QUESTO TOGLIE SPAZIO DALLA TASTIERA
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(40)),
                      elevation: 16,
                      child: ModificaTransazione(
                          idtransazione: tx.id,
                          titolotransazione: tx.titolo,
                          importotransazione: tx.costo,
                          datatransazione: tx.data,
                          indicetransazione: tx.indicecategoria,
                          notatransazione: tx.nota,
                          listatransazioni: widget.transactions,
                          eliminatransazione: widget.deleteTx,
                          listanomicategorie: widget.listanomicategorie,
                          refreshSezioneFinanziaria:
                              widget.refreshFinanceScreen,
                          size: size),
                    );
                  ,
                ).then((_) 
                  setState(() );
                );
              ,
              child: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                ),
                child: SizedBox(
                  height: size.height * 0.10,
                  // color: Colors.red,
                  child: Row(
                    children: [
                      Expanded(
                        flex: 4,
                        child: Container(
                          margin: const EdgeInsets.only(left: 15),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              FittedBox(
                                child: Text(
                                  tx.titolo,
                                  style: const TextStyle(
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ),
                              FittedBox(
                                child: Text(
                                  DateFormat('dd MMMM, yyyy', 'it')
                                      .format(tx.data),
                                  style: const TextStyle(
                                    color: Colors.grey,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                      Expanded(
                        flex: 5,
                        child: Container(
                          alignment: Alignment.centerRight,
                          margin: const EdgeInsets.symmetric(horizontal: 15),
                          child: FittedBox(
                            child: Text(
                              '- $ciframostrata(tx.costo) €',
                              style: const TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 20,
                                  color: Color(0xFF7465fc)),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),

这是“ModificaTransazione()”,在意大利语中的字面意思是“编辑交易”。

        import 'package:auto_size_text/auto_size_text.dart';
        import 'package:flutter/material.dart';
        import 'package:flutter_application_1/models/transaction.dart';
        import 'package:flutter_application_1/widget/transactions_list.dart';
        import 'package:intl/intl.dart';
        import 'package:auto_size_text_field/auto_size_text_field.dart';
        
        class ModificaTransazione extends StatefulWidget 
          ModificaTransazione(
            Key? key,
            required this.size,
            required this.idtransazione,
            required this.titolotransazione,
            required this.importotransazione,
            required this.datatransazione,
            required this.indicetransazione,
            required this.notatransazione,
            required this.listatransazioni,
            required this.eliminatransazione,
            required this.listanomicategorie,
            required this.refreshSezioneFinanziaria,
          ) : super(key: key);
        
          final Size size;
          final String idtransazione;
          String titolotransazione;
          double importotransazione;
          DateTime datatransazione;
          int indicetransazione;
          String notatransazione;
          List<String> listanomicategorie;
          List<Transaction> listatransazioni;
          final Function eliminatransazione;
          final Function refreshSezioneFinanziaria;
        
          @override
          State<ModificaTransazione> createState() => _ModificaTransazioneState();
        
        
        class _ModificaTransazioneState extends State<ModificaTransazione> 
          var _notaController = TextEditingController();
          var _importoController = TextEditingController();
          var _titoloController = TextEditingController();
        
          @override
          void initState() 
            super.initState();
            if (widget.notatransazione != "") 
              _notaController = TextEditingController(text: widget.notatransazione);
             else 
              _notaController = TextEditingController(text: "Aggiungi");
            
        
            _importoController = TextEditingController(
                text: "$ciframostrata(widget.importotransazione)");
            _titoloController = TextEditingController(text: widget.titolotransazione);
          
        
          @override
          Widget build(BuildContext context) 
            
            return SingleChildScrollView(
              child: Container(
                width: widget.size.width * 0.8,
                height: widget.size.height * 0.60,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Padding(
                  padding:
                      const EdgeInsets.only(top: 30, left: 30, right: 30, bottom: 30),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        children: [
                          GestureDetector(
                            onTap: () 
                              setState(() 
                                Navigator.of(context).pop();
                              );
                            ,
                            child: Icon(
                              Icons.cancel,
                              color: Colors.black,
                            ),
                          ),
                          Spacer(),
                          Expanded(
//
// THIS IS WHAT I WANT TO RESIZE, BUT FITTEDBOX IS CAUSING RENDERBOX IS NOT LAID OUT
//
                            flex: 10,
                            child: FittedBox(
                              fit: BoxFit.fitWidth,
                              child: TextField(
                                maxLines: 1,
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                ),
                                controller: _titoloController,
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 20,
                                  fontWeight: FontWeight.bold,
                                ),
                                onSubmitted: (_) => salvaModifica(),
                              ),
                            ),
                          ),
                          Spacer(),
                          GestureDetector(
                              child: Icon(
                                Icons.delete_outline_rounded,
                                color: Colors.black,
                              ),
                              onTap: () 
                                print("Transazione Eliminata");
        
                                widget.eliminatransazione(widget.idtransazione);
                                Navigator.of(context).pop();
                              ),
                        ],
                      ),
                      Container(
                        padding: EdgeInsets.all(15),
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(15),
                          color: Theme.of(context).primaryColor.withOpacity(0.1),
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Flexible(
                              flex: 4,
                              child: TextField(
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                ),
                                controller: _importoController,
                                keyboardType: const TextInputType.numberWithOptions(
                                    decimal: true),
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 60,
                                  color: Theme.of(context).primaryColor,
                                ),
                                onSubmitted: (_) => salvaModifica(),
                              ),
                            ),
                            Flexible(
                              //color: Colors.red,
                              //alignment: Alignment.centerRight,
                              //width: widget.size.width * 0.10,
                              // color: Colors.red,
                              child: Text(
                                "€",
                                style: TextStyle(
                                  fontSize: 40,
                                  color:
                                      Theme.of(context).primaryColor.withOpacity(0.8),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
        
                      //   AutoSizeText(
                      //     "$ciframostrata(widget.importotransazione) €",
                      //     maxLines: 1,
                      //     style: TextStyle(
                      //       fontSize: 70,
                      //       color: Theme.of(context).primaryColor,
                      //     ),
                      //   ),
                      // ),
        
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Text(
                            "Categoria",
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 15,
                              color: Colors.grey,
                            ),
                          ),
                          Container(
                            child: Row(
                              children: [
                                GestureDetector(
                                  child: Text(
                                    "$funzioneCategoria(indicenuovo ?? widget.indicetransazione, widget.listanomicategorie)[2] ",
                                    style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 15,
                                        color: funzioneCategoria(
                                            indicenuovo ?? widget.indicetransazione,
                                            widget.listanomicategorie)[1]),
                                  ),
                                  onTap: _askedToLead,
                                ),
                                Icon(
                                    funzioneCategoria(
                                        indicenuovo ?? widget.indicetransazione,
                                        widget.listanomicategorie)[0],
                                    color: funzioneCategoria(
                                        indicenuovo ?? widget.indicetransazione,
                                        widget.listanomicategorie)[1]),
                              ],
                            ),
                          ),
                        ],
                      ),
        
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Text(
                            "Data",
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 15,
                              color: Colors.grey,
                            ),
                          ),
                          InkWell(
                            // borderRadius: BorderRadius.circular(10),
                            onTap: _presentDatePicker,
        
                            child: Text(
                              DateFormat('dd MMMM, yyyy', 'it')
                                  .format(_selectedDate ?? widget.datatransazione),
                              style: TextStyle(
                                color: Colors.black, //Theme.of(context).primaryColor,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ],
                      ),
        
                      Container(
                        //color: Colors.red,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Expanded(
                              child: Text(
                                "Nota",
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 15,
                                  color: Colors.grey,
                                ),
                              ),
                            ),
                            Expanded(
                                child: (_notaController.text != "Aggiungi")
                                    ? TextField(
                                        textAlign: TextAlign.end,
                                        decoration: InputDecoration(
                                          border: InputBorder.none,
                                        ),
                                        controller: _notaController,
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          color: Colors.black,
                                        ),
                                        onSubmitted: (_) => salvaModifica(),
                                      )
                                    : TextField(
                                        textAlign: TextAlign.end,
                                        decoration: InputDecoration(
                                          border: InputBorder.none,
                                        ),
                                        controller: _notaController,
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          color: Colors.grey[600],
                                        ),
                                        onSubmitted: (_) => salvaModifica(),
                                      )),
                          ],
                        ),
                      ),
        
                      modificato == true
                          ? TextButton(
                              child: Text("Salva"),
                              style: ButtonStyle(
                                backgroundColor: MaterialStateProperty.all(
                                    Theme.of(context).primaryColor),
                                foregroundColor:
                                    MaterialStateProperty.all(Colors.white),
                              ),
                              onPressed: () 
                                premuto = true;
                                salvaModifica();
                              ,
                            )
                          : SizedBox(),
                    ],
                  ),
                ),
              ),
            );
          

【问题讨论】:

正如您在第二张插图中看到的那样,文字要小得多,因此请减小字体大小 这是一个Textfield(),所以文本会随着用户输入而改变。文本的长度是可变的。我希望在用户输入文本时动态调整文本大小。 @戴维斯 【参考方案1】:

您可以使用 FittedBox 小部件根据宽度或高度动态更改文本大小。

      FittedBox(
            fit: BoxFit.fitWidth,
            child: TextField(
                maxLines: 1,
                decoration: InputDecoration(
                  border: InputBorder.none,
                ),
                controller: _titoloController,
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
                onSubmitted: (_) => salvaModifica(),
              )),

文本将根据 Expanded 的宽度调整大小。

【讨论】:

这不起作用,因为它导致RenderBox was not laid out. 我添加了更多代码,以便清楚我在做什么。可以看看吗? 我会试试的,不过你也可以参考这里:***.com/questions/50751226/…【参考方案2】:

我已经检查了您的代码。您可以执行以下操作:

Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          GestureDetector(
                            onTap: () 
                              setState(() 
                                Navigator.of(context).pop();
                              );
                            ,
                            child: Icon(
                              Icons.cancel,
                              color: Colors.black,
                            ),
                          ),
                          Expanded(
                            child: TextField(
                              maxLines: 4,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                              ),
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                fontSize: 20,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                          GestureDetector(
                              child: Icon(
                                Icons.delete_outline_rounded,
                                color: Colors.black,
                              ),
                              onTap: () 
                                print("Transazione Eliminata");

                                Navigator.of(context).pop();
                              ),
                        ],
                      ),

【讨论】:

你在 TextField() 中忘记了 controller: _titoloController,,所以我添加了它。我也想要maxLines: 1,。现在它呈现了我想要的样子,但是一旦到达扩展的边缘,文本就会继续消失。它可以水平滚动,但不会调整大小。 我还添加了两个 Spacer(),一个在 Expanded() 之前,另一个在 Expanded() 之后。因为我想要在应该调整大小的文本之前和之后有一些间隙。不过,仍然需要帮助才能调整它的大小。 如果添加 maxLines: 1,它将强制展开的小部件保持在单行中,您可以滚动它。您应该定义您希望小部件使用的 maxLines。如果您不提供任何 maxLines,它会自动调整大小以留在小部件内,即使这意味着用户必须滚动 我不确定我是否理解正确,因为我不是英语母语。您是否建议我删除 maxLines 属性?如果我正确理解了您的评论,您是在告诉我,如果我保留 maxLines: 1,我的 TextField 将是可滚动的(我不想要这个),但如果我删除 maxLines 属性,它将调整大小。对吗? 文本大小不会调整大小兄弟.. Maxlines 只是告诉文本字段保持在一行中。如果您想在用户输入长文本时调整文本字段的大小,可以查看以下答案:***.com/questions/51580658/…

以上是关于如何调整 TextField() 文本的大小以适应 Expanded() 小部件的最大宽度的主要内容,如果未能解决你的问题,请参考以下文章

AS3 Textfield根据高度设置宽度

如何调整 UIButton 的大小以适应文本而不使其比屏幕更宽?

调整 UILabel 的大小以适应自定义 UITableViewCell 中的文本,无论宽度如何

调整文本大小以适应宽度(1行标签)后,如何在 UILabel 中垂直和水平居中?

自动调整 UILabel 文本大小以适应 UILabel 宽度

如何调整标签大小以适应任何屏幕尺寸