import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class ExpandableText extends StatefulWidget {
final String text;
final int maxLines;
final TextStyle style;
final bool expand;
const ExpandableText(
{Key key, this.text, this.maxLines, this.style, this.expand})
: super(key: key);
State<StatefulWidget> createState() {
return _ExpandableTextState(text, maxLines, style, expand);
}
}
class _ExpandableTextState extends State<ExpandableText> {
final String text;
final int maxLines;
final TextStyle style;
bool expand;
_ExpandableTextState(this.text, this.maxLines, this.style, this.expand) {
if (expand == null) {
expand = false;
}
}
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, size) {
final span = TextSpan(text: text ?? '', style: style);
//通过TextPainter判断是否超过最大行数
final tp = TextPainter(
text: span, maxLines: maxLines, textDirection: TextDirection.ltr);
tp.layout(maxWidth: size.maxWidth);
if (tp.didExceedMaxLines) {
final textSize = tp.size;
final position = tp.getPositionForOffset(Offset(
textSize.width - tp.width,
textSize.height,
));
// 默认endOffset = position.offset;但是这样导致查看全部两字有时会换行,故再减了16(由于减了16所以收起时的行数会与传入的maxLines对不上,比传入的少了一行)
final endOffset = tp.getOffsetBefore(position.offset - 16);
return RichText(
overflow: TextOverflow.clip,
text: TextSpan(
text: expand?text
: text.substring(0, endOffset)+'...',
style: TextStyle(
fontSize: style != null ? style.fontSize : null,
color: Colors.black),
children: [
TextSpan(
text: expand ? '收起' : '查看全部',
style: TextStyle(
fontSize: style != null ? style.fontSize : null,
color: JadeColors.blue_2),
recognizer: TapGestureRecognizer()
..onTap = () {
setState(() {
expand = !expand;
});
},
)
])
);
} else {
return Text(text ?? '', style: style);
}
});
}
}
使用
ExpandableText(
text: Utils().breakWord(S.current.experienceStationTipTwo),
maxLines: 4,
style:TextStyle(fontSize: setFontSize(30)),
),