import 'package:atui/jade/utils/JadeColors.dart';
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;
final String expandText;
final TextStyle expandTextStyle;
final bool removeExpandAction;
final bool keepShowExpandText;
final paragraphsWidth;
final Function expandCallback;
const ExpandableText(
{Key key,
this.text,
this.maxLines,
this.style,
this.expand,
this.expandText,
this.expandTextStyle,
this.removeExpandAction,
this.keepShowExpandText,
this.paragraphsWidth,
this.expandCallback})
: super(key: key);
State<StatefulWidget> createState() {
return _ExpandableTextState(text, maxLines, style, expand, expandText,expandTextStyle,removeExpandAction,keepShowExpandText,paragraphsWidth,expandCallback);
}
}
class _ExpandableTextState extends State<ExpandableText> {
final String text;//文本内容
final int maxLines;//最大行数
final TextStyle style;//文本样式
bool expand; //是否展开
String expandText; //展开、收起按钮文本
TextStyle expandTextStyle;//展开、收起按钮文本样式
final bool removeExpandAction; //是否一处展开、收起按钮的点击响应
final bool keepShowExpandText; //是否在未超过设置的最大行数时,显示拼接的展开、收起按钮
final paragraphsWidth; //自然段样式时,句头占位的宽度
final Function expandCallback; //点击扩展文字按钮回调出去
_ExpandableTextState(this.text, this.maxLines, this.style, this.expand, this.expandText, this.expandTextStyle,
this.removeExpandAction, this.keepShowExpandText, this.paragraphsWidth,this.expandCallback) {
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 position = tp.getPositionForOffset(Offset(
size.maxWidth - tp.width / maxLines, //size.maxWidth最右,减去tp.width / maxLines为省略号和拼接的文本按钮预留距离
tp.size.height,
));
//final endOffset = tp.getOffsetBefore(position.offset);
final endOffset = tp.getOffsetAfter(position.offset);
return RichText(
overflow: TextOverflow.clip,
text: TextSpan(
children: [
WidgetSpan(child: SizedBox(width: paragraphsWidth ?? 0)),
TextSpan(
text: expand?text
: text.substring(0, endOffset)+'...',
style: TextStyle(
fontSize: style != null ? style.fontSize : null,
color: style != null ? style.color : Colors.black,
shadows: style != null ? style.shadows : [Shadow(
blurRadius: 0.0,
color: Colors.black,
offset: Offset(0.0, 0.0),
)],
height: style.height != null ? style.height : 1.0
),
),
TextSpan(
text: expand ? '收起' : expandText??'查看全部',
style: TextStyle(
fontSize: style != null ? style.fontSize : null,
color: expandTextStyle != null ? expandTextStyle.color : JadeColors.blue_2,
shadows: expandTextStyle != null ? expandTextStyle.shadows : [
Shadow(
blurRadius: 0.0,
color: JadeColors.blue_2,
offset: Offset(0.0, 0.0),
)
],
decoration: TextDecoration.underline
),
recognizer: TapGestureRecognizer()
..onTap = () {
if(expandCallback != null){
expandCallback();
}
//是取消点击扩展文字按钮显示全文的响应操作
if(removeExpandAction == true){
return;
}
setState(() {
expand = !expand;
});
},
)
])
);
} else {
if(keepShowExpandText == true && text != null && text.isNotEmpty){
return Text.rich(TextSpan(
children: [
TextSpan(
text: text,style: style
),
TextSpan(
text: expandText,style: expandTextStyle
)
]
));
}
return Text(text ?? '', style: style);
}
});
}
}
使用
String _content = "这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容这里是文本内容";
ExpandableText(
text: _content ,
maxLines: 4,
style:TextStyle(fontSize: setFontSize(30)),
),