颤振:在文本的最后设置显示更多和显示更少图标

Posted

技术标签:

【中文标题】颤振:在文本的最后设置显示更多和显示更少图标【英文标题】:flutter: Set show more and show less icon in last of text 【发布时间】:2021-10-14 13:52:08 【问题描述】:

我想在文本的最后使用 set show more and show less icon。 我想在文本的最后使用设置显示更多并显示更少的图标。 我想在文本的最后使用设置显示更多并显示更少的图标。 我想在文本的最后使用 set show more and show less icon。

这是我的代码

class HomeScreen extends StatelessWidget 
  final String description =
      "Flutter is Google’s mobile UI framework for crafting high-quality native interfaces on ios and android in record time. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.";

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: const Text("Demo App"),
      ),
      body: new Container(
        child: new DescriptionTextWidget(text: description),
      ),
    );
  


class DescriptionTextWidget extends StatefulWidget 
  final String? text;

  DescriptionTextWidget(@required this.text);

  @override
  _DescriptionTextWidgetState createState() => new _DescriptionTextWidgetState();


class _DescriptionTextWidgetState extends State<DescriptionTextWidget> 
  String? firstHalf;
  String? secondHalf;
  Icon? ic=Icon(Icons.arrow_back);

  bool flag = true;

  @override
  void initState() 
    super.initState();

    if (widget.text!.length > 50) 
      firstHalf = widget.text!.substring(0, 50);
      secondHalf = widget.text!.substring(50, widget.text!.length);
     else 
      firstHalf = widget.text;
      secondHalf = "";
    
  

  @override
  Widget build(BuildContext context) 
    return new Container(

      child: secondHalf!.isEmpty
          ? new Text(firstHalf!)
          : new Column(
              children: <Widget>[
                // new Text(flag ? (firstHalf! + '...') : (firstHalf! + secondHalf!)),
                flag==true?Column(children: [Text(firstHalf!),SizedBox(width: 10,) ,InkWell(
                  child: new Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      Icon(Icons.forward),
                    ],
                  ),
                  onTap: () 
                    setState(() 
                      flag = !flag;
                    );
                  ,
                ),],):Column(

                  children: [
                    Text( (firstHalf! + secondHalf!)),
                    InkWell(
                  child:
                           Icon(Icons.arrow_back),
                  onTap: () 
                    setState(() 
                      flag = !flag;
                    );
                  ,
                ),
                  ],
                ),
                // new InkWell(
                //   child: new Row(
                //     mainAxisAlignment: MainAxisAlignment.end,
                //     children: <Widget>[
                //       new Text(
                //         flag ? "show more" : "show less",
                //         style: new TextStyle(color: Colors.blue),
                //       ),
                //     ],
                //   ),
                //   onTap: () 
                //     setState(() 
                //       flag = !flag;
                //     );
                //   ,
                // ),
              ],
            ),
    );
  

我想要这样的东西

但我不能这样,请帮助我

【问题讨论】:

【参考方案1】:

试试 Flutter read_more 依赖,如下-

readmore: ^2.1.0

Visit

【讨论】:

但是如何在最后使用图标 表示在文本的末尾。正如您在照片中看到的那样。 我已经看到字符串中的文本越多,我认为这不会使用图标而不是文本。尝试管理图标。【参考方案2】:

这是您问题的解决方案

您可以添加此自定义小部件来展开和折叠您的文本

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

enum TrimMode 
  Length,
  Line,


class ReadMoreText extends StatefulWidget 
  const ReadMoreText(
      this.data, 
        Key key,
        this.trimExpandedText = ' read less',
        this.trimCollapsedText = ' ...read more',
        this.colorClickableText,
        this.trimLength = 240,
        this.trimLines = 2,
        this.trimMode = TrimMode.Length,
        this.style,
        this.textAlign,
        this.textDirection,
        this.locale,
        this.textScaleFactor,
        this.semanticsLabel,
      )  : assert(data != null),
        super(key: key);

  final String data;
  final String trimExpandedText;
  final String trimCollapsedText;
  final Color colorClickableText;
  final int trimLength;
  final int trimLines;
  final TrimMode trimMode;
  final TextStyle style;
  final TextAlign textAlign;
  final TextDirection textDirection;
  final Locale locale;
  final double textScaleFactor;
  final String semanticsLabel;

  @override
  ReadMoreTextState createState() => ReadMoreTextState();


const String _kEllipsis = '\u2026';

const String _kLineSeparator = '\u2028';

class ReadMoreTextState extends State<ReadMoreText> 
  bool _readMore = true;

  void _onTapLink() 
    setState(() => _readMore = !_readMore);
  

  @override
  Widget build(BuildContext context) 
    final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
    TextStyle effectiveTextStyle = widget.style;
    if (widget.style == null || widget.style.inherit) 
      effectiveTextStyle = defaultTextStyle.style.merge(widget.style);
    

    final textAlign =
        widget.textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start;
    final textDirection = widget.textDirection ?? Directionality.of(context);
    final textScaleFactor =
        widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context);
    final overflow = defaultTextStyle.overflow;
    final locale =
        widget.locale ?? Localizations.maybeLocaleOf(context);

    final colorClickableText = widget.colorClickableText ?? Theme.of(context).accentColor;

    TextSpan link = TextSpan(
      text: _readMore ? widget.trimCollapsedText : widget.trimExpandedText,
      style: effectiveTextStyle.copyWith(
        color: Colors.blue,
        fontSize: 12,
      ),
      recognizer: TapGestureRecognizer()..onTap = _onTapLink,
    );

    Widget result = LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) 
        assert(constraints.hasBoundedWidth);
        final double maxWidth = constraints.maxWidth;

        // Create a TextSpan with data
        final text = TextSpan(
          style: effectiveTextStyle,
          text: widget.data,
        );

        // Layout and measure link
        TextPainter textPainter = TextPainter(
          text: link,
          textAlign: textAlign,
          textDirection: textDirection,
          textScaleFactor: textScaleFactor,
          maxLines: widget.trimLines,
          ellipsis: overflow == TextOverflow.ellipsis ? _kEllipsis : null,
          locale: locale,
        );
        textPainter.layout(minWidth: constraints.minWidth, maxWidth: maxWidth);
        final linkSize = textPainter.size;

        // Layout and measure text
        textPainter.text = text;
        textPainter.layout(minWidth: constraints.minWidth, maxWidth: maxWidth);
        final textSize = textPainter.size;

        // Get the endIndex of data
        bool linkLongerThanLine = false;
        int endIndex;

        if (linkSize.width < maxWidth) 
          final pos = textPainter.getPositionForOffset(Offset(
            textSize.width - linkSize.width,
            textSize.height,
          ));
          endIndex = textPainter.getOffsetBefore(pos.offset);
        
        else 
          var pos = textPainter.getPositionForOffset(
            textSize.bottomLeft(Offset.zero),
          );
          endIndex = pos.offset;
          linkLongerThanLine = true;
        

        var textSpan;
        switch (widget.trimMode) 
          case TrimMode.Length:
            if (widget.trimLength < widget.data.length) 
              textSpan = TextSpan(
                style: effectiveTextStyle,
                text: _readMore
                    ? widget.data.substring(0, widget.trimLength)
                    : widget.data,
                children: <TextSpan>[link],
              );
             else 
              textSpan = TextSpan(
                style: effectiveTextStyle,
                text: widget.data,
              );
            
            break;
          case TrimMode.Line:
            if (textPainter.didExceedMaxLines) 
              textSpan = TextSpan(
                style: effectiveTextStyle,
                text: _readMore
                    ? widget.data.substring(0, endIndex) +
                    (linkLongerThanLine ? _kLineSeparator : '')
                    : widget.data,
                children: <TextSpan>[link],
              );
             else 
              textSpan = TextSpan(
                style: effectiveTextStyle,
                text: widget.data,
              );
            
            break;
          default:
            throw Exception(
                'TrimMode type: $widget.trimMode is not supported');
        

        return RichText(
          textAlign: textAlign,
          textDirection: textDirection,
          softWrap: true,
          //softWrap,
          overflow: TextOverflow.clip,
          //overflow,
          textScaleFactor: textScaleFactor,
          text: textSpan,
        );
      ,
    );
    if (widget.semanticsLabel != null) 
      result = Semantics(
        textDirection: widget.textDirection,
        label: widget.semanticsLabel,
        child: ExcludeSemantics(
          child: result,
        ),
      );
    
    return result;
  

如何使用这个小部件见下面的代码

Container(
    child:ReadMoreText(
           description,
           trimLines: 3,
           colorClickableText: Colors.pink,
           trimMode: TrimMode.Line,
           trimCollapsedText: "show more ...",
           trimExpandedText: "show less ....",
           style: TextStyle(fontSize: 14, color: 
           Colors.black.withOpacity(0.5)),
      ),
)

【讨论】:

以上是关于颤振:在文本的最后设置显示更多和显示更少图标的主要内容,如果未能解决你的问题,请参考以下文章

显示更多/显示更少文本,但如果文本没有溢出则隐藏选项(Angular)

Jquery切换图标显示越来越少

在颤振中如果文本内容增加,我想在帖子底部显示更多文本?

用链接截断 html 中的文本以显示更多/更少并将元素保留在里面

在表格单元格角度显示更多/更少按钮

通知未显示 - 已设置 chennel 以及小图标、标题和文本