Get straight to the specific requirements style

There are three widgets in a row, and only the contents of the first widget are determined. The contents of the second widget are returned by the interface, and the contents of the third widget are determined by the second. Display only one row, if too much, widget2 is omitted to… Visible end. Let’s draw a picture, make it clear, and then give us an idea of what it looks like.

Widget2: Returns a list of publishing scopes for the interface, which can be very long or very short. When long, widget1 and 3 are positioned, Widget2 displays as much content as possible, and then starts with “… Visible “copy ends. It could be something like this:

Eg1: Maximum visible range: Zhang SAN, Li Si and Wang Wu are visible. ✅ (widget2 has very little content)

Eg2: Maximum visible range: Zhang SAN, Li Si, Wang Wu, Zhao… Wait until 26 people are visible. ✅ (Widget2 is too much to display on a single line)

UED renderings:

Implementation method:
A:

Row-> widget1 -> Container(BoxConstraints limits the width)->widget2/widget3

Row(children: [
      Container(
        constraints: BoxConstraints(
            minWidth: margin,
            maxWidth: MediaQuery.of(context).size.width - margin),
        child: Text(
          str,
          style: titleStyle,
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
        ),
      ),
      Text(
        endStr,
        style: StyleConstant.subtitleStyle,
      )
    ]);
Copy the code
To realize two:

Use the system’s built-in CustomMultiChildLayout to customize a widget that inherits from it

class MultipleChildWrapWidget extends CustomMultiChildLayout { MultipleChildWrapWidget({Key key, List<Widget> children}) : super( key: key, children: children, delegate: MultiChildrenWidgetDelegate()); } class MultiChildrenWidgetDelegate extends MultiChildLayoutDelegate { @override void performLayout(Size size) { // Size var surplus = size (size.width, size.height); If (hasChild("former")) {var formerSize = layoutChild("former", boxcontrains.loose (surplus)); positionChild("former", Offset.zero); // update the remaining size surplus = size (plus.width - formerSize. Width, plus.height); } if (hasChild("middle") &&haschild ("last")) {var lastSize = layoutChild("last", BoxConstraints.loose(surplus)); Var middleSize = layoutChild("middle", BoxConstraints. Loose (Size(surplus. Width - lastSize. surplus.height))); // Place the positionChild("middle", Offset(sie.width - surplus. Width, 0)); positionChild("last", Offset(size.width - surplus.width + middleSize.width, 0)); }}Copy the code

Use it as a widget, but be sure to write the control’S ID correctly. Use examples:

Container( child: MultipleChildWrapWidget( children: [ LayoutId(id: "former", child: LayoutId(id: "middle", child: child,), LayoutId(id: "last", child: child)],),);Copy the code

Same kind of requirement

Popup prompt, display up to two lines of text, more than two lines with “… Visible “end.

implementation

I originally tried to do it in the “steal the chicken” way, making the text appear on just two lines, and then at the bottom of the second line with “… See “Text overwrites. Soon three under five two finished, fix, ha ha 😆 ideal is full, reality is very bold. There is a problem with overlaying a fixed widget directly after the run. you know what I mean.

B: No, let’s change it. Later, I wanted to display the two rows separately and the second row as a combination of two widgets. But how do you determine how much text to display per line? At which text does it break? This will have to draw out a word, too much trouble, do not want to do so. Programmers are lazy. I’m looking for an easy way.

Since the text exceeds a fixed number of lines, it ends with “…” End, can I customize it to end with “… Visible “end?? This has realized my request!! Well, that’s good. Ellipsis style Settings overflow: Textoverflow. ellipsis. However, the TextWidget system provides only a few ellipsis styles, which cannot be customized.

No, I won’t do it. Since you can give me those ellipsis styles, you can set others. I’ll keep looking. Your Text doesn’t work. I’ll look for something else. What about the way I draw it myself, TextPainter;

  TextPainter({
    InlineSpan? text,
    TextAlign textAlign = TextAlign.start,
    TextDirection? textDirection,
    double textScaleFactor = 1.0,
    int? maxLines,
    String? ellipsis,
    Locale? locale,
    StrutStyle? strutStyle,
    TextWidthBasis textWidthBasis = TextWidthBasis.parent,
    ui.TextHeightBehavior? textHeightBehavior,
  })
Copy the code

Well, I can pass ellipsis in here, so I’ll just end it with the String I want. This seems to work. Hey, hey, it’s you.

Create a custom widget that inherits the CustomPainter protocol.

class CustomTextPaintWidget extends CustomPainter { final String text; final String endStr; final TextStyle textStyle; final int maxLines; TextPainter _textPainter; CustomTextPaintWidget({this.text, this.endStr,this.textStyle, this.maxLines}) { _textPainter = TextPainter( text: TextSpan(text: text, style: textStyle), maxLines: maxLines, ellipsis: endStr, textDirection: TextDirection.ltr); } @override void paint(Canvas canvas, Size size) { _textPainter.layout(maxWidth: size.width); _textPainter.paint(canvas, Offset(0, 0)); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; }}Copy the code

It can be used as a widget. This will also solve the problem above.

Widget CustomPaint(
      size: Size(MediaQuery.of(context).size.width - margin, 20),
      painter: CustomTextPaintWidget(
          text: str,
          endStr: endStr,
          textStyle: TextStyle,
          maxLines: 2),
    );
Copy the code

Perfect. 😆

In fact, the demand is very simple, don’t worry, first think well do, there will always be a better way.

If the big guy has a better implementation style, I hope you don’t hesitate to give me advice, younger brother in this first thanks [fist].