如何在行中的扩展长文本之后放置小部件?

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

如何将动态长文本与另一个小部件(如按钮)一起展开,如下所示:


我尝试了

Expanded
Flexible
Warp
,但没有得出结论。

!注意我不希望它位于

Stack
中或从底部使用
Padding
!导致此文本会发生变化,其长度可能会变大或变短。


更新:我尝试使用 ExtendedText,但 TextOverFlowWidget 的子项没有显示给我。我的代码:

Container(
  color: Colors.amber,
  height: 70,
  child: ExtendedText(
    'bbbbb ${toPhoneStyle(widget.inputPhone)}  (${widget.selectedCountry.dialCode})  aaaaaa aaaaaaaaaaa',
     overflowWidget: TextOverflowWidget(
        // maxHeight: double.infinity,
        // align: TextOverflowAlign.right,
        // fixedOffset: Offset.zero,
        child: Container(
            width: 60,
            height: 60,
            color: Colors.red,
            ),
         ),
      ),
   ),

但是如果像

height:20
这样缩小 Container 的高度,则显示如下:

flutter dart text widget warp
3个回答
5
投票

显然,您可以使用

RichText
小部件将文本和小部件换行,即它旨在使用多种显示样式显示文本。文本使用
<TextSpan>
<WidgetSpan>
类型的子级呈现。

以下代码将解释您在问题中尝试的确切内容。请注意,我只使用了有状态小部件,因为我也在处理其他东西,所以我只编辑了该小部件中的所有内容,如果您不打算在此处引入任何状态,则可以使用无状态小部件。

完整代码:

import 'package:flutter/material.dart';

void main()
{
  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final String str = 'Some really long text to show the working of a wrap widget'
      + ' and place a button at the end of the text and it will then prove that'
      + ' you can do the same with other kind of widgets.';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Container(
            width: (MediaQuery.of(context).size.width) / 1.3,
            decoration: BoxDecoration(
              color: Colors.orange[100],
            ),
            child: RichText(
              text: TextSpan(
                children: [
                  TextSpan(
                    text: str,
                    style: TextStyle(
                      fontSize: 24,
                      color: Colors.black,
                    ),
                  ),
                  // treat the child of WidgetSpan as the parameter to insert
                  // whatever widget you wish to put here
                  // SizedBox is only used to put a little space after the text string
                  WidgetSpan(
                    child: SizedBox(width: 5,),
                  ),
                  WidgetSpan(
                    child: Container(
                      child: RaisedButton(
                        color: Colors.blueAccent,
                        onPressed: (){},
                        child: Text('Button'),
                      ),
                    ),
                  ),
                ]
              ),
            ),
          ),
        ),
      ),
    );
  }
}

渲染后的结果:


1
投票

试试这个:扩展文本包

您可以使用一个溢出小部件。

检查他们的示例:

ExtendedText(...
        overFlowWidget:
            TextOverflowWidget(
                //maxHeight: double.infinity,
                //align: TextOverflowAlign.right,
                //fixedOffset: Offset.zero,
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    const Text('\u2026 '),
                    RaisedButton(
                      child: const Text('more'),
                      onPressed: () {
                        launch(
                            'https://github.com/fluttercandies/extended_text');
                      },
                    )
                  ],
                ),
              ),
        ...
      )

好吧,你需要指定 maxLines 才能使溢出正常工作。我认为您应该选择跟随文本的小部件。您可以尝试 Text.rich() 小部件

Text.rich(
  TextSpan(
    text: 'This is an example text!',
    children: [
      WidgetSpan(
        // Set the alignment
        alignment: PlaceholderAlignment.middle,
        // You can put any widget inline with text using WidgetSpan
        child: Container(
          margin: const EdgeInsets.only(left: 8.0),
          child: ElevatedButton(
            child: Text("Read more..."),
            onPressed: () {},
          ),
        ),
      ),
    ],
  ),
);

在这种情况下,您不需要扩展文本包。


0
投票

这是一个完整的示例。

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

  @override
  State<TestWidget> createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {

  bool showMoreInfo = false;
  void onTap(){
    setState(() {
      showMoreInfo = !showMoreInfo;
    });
  }

  String removeLastWord(String input) {
    if (input.isEmpty || input.endsWith(' ') || input.endsWith('.')) {
      return input;
    } else {
      int lastSpaceIndex = input.lastIndexOf(' ');
      if (lastSpaceIndex == -1) {
        return '';
      } else {
        return input.substring(0, lastSpaceIndex);
      }
    }
  }

  final content = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum";
  final maxLengthLimit = 160;

  @override
  Widget build(BuildContext context) {
    final bool isBigText = content.length>maxLengthLimit;
    final maxLength = content.length<maxLengthLimit? content.length : maxLengthLimit;
    String finalText = showMoreInfo
        ? content
        : isBigText? removeLastWord(content.substring(0, maxLength)) : content;

    return InkWell(
      onTap: onTap,
      child: Text.rich(
        style: TextStyle(
            fontSize: 14,
            color: Colors.white.withOpacity(0.8)),
        softWrap: true,
        textAlign: TextAlign.center,
        TextSpan(
          children: [
            TextSpan(
              text: finalText,
            ),
            if(isBigText)
              WidgetSpan(
                  child: Padding(
                    padding: const EdgeInsets.only(left: 5.0),
                    child: Container(
                      width: 20,
                      height: 20,
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(7),
                          border: Border.all(
                              width: 1, color: Colors.white.withOpacity(0.2))),
                      child: Icon(
                        showMoreInfo
                            ? Icons.keyboard_arrow_up
                            : Icons.more_horiz,
                        size: 11,
                        color: Colors.white,
                      ),
                    ),
                  )),
          ],
        ),
      ),
    );
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.