组件化,封装为公共组件
收起和更多按钮的样式可以根据自己的需求来修改,提供了很多可先参数来控制。
非空
class TextSpanShow extends StatefulWidget {
final String text;
final Color colorTest;
final Color ellipsisColorTest;
final Color moreBackgroundTest;
final Color moreContainerColor;
final int mMaxLine;
final bool showColor;
final TextStyle styleText;
final double textSpanWidth;
final double textSpanHeight;
const TextSpanShow(
this.text, {
Key key,
this.colorTest = Colors.black,
this.ellipsisColorTest,
this.mMaxLine = 3, this.styleText, this.moreBackgroundTest, this.showColor, this.textSpanWidth, this.textSpanHeight, this.moreContainerColor,
}) : super(key: key);
@override
_TextSpanShowState createState() => _TextSpanShowState();
}
class _TextSpanShowState extends State<TextSpanShow> {
bool mIsExpansion = false;
@override
Widget build(BuildContext context) {
return Container(
width: widget.textSpanWidth ?? null,
height: widget.textSpanHeight ?? null,
color: widget.moreContainerColor ?? null,
child: richText(widget.text,),
);
}
Widget richText(String _text) {
if (IsExpansion(_text)) {
//如果需要截断
if (mIsExpansion) {
return Stack(
children: <Widget>[
new Text(
_text,
textAlign: TextAlign.left,
style:widget.styleText?? TextStyle(color: widget.colorTest),
),
Positioned(
right: 0,
bottom: 0,
child: Container(
decoration: BoxDecoration(color: Colors.red),
child: GestureDetector(
onTap: () {
_isShowText();
},
child: Text("收起<",
style: TextStyleFactory.styleSubtitle3(
context, 12, Colors.blue)),
),
),
),
],
);
} else {
return Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.all(0),
child: Text(
_text,
maxLines: widget.mMaxLine,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style:widget.styleText?? TextStyle(color: widget.ellipsisColorTest??widget.colorTest),
),
),
Positioned(
right: 0,
bottom: 0,
child: Container(
color: widget.moreContainerColor??Color.fromARGB(255, 250, 250, 250),
child: Row(
children: [
Container(
child: Text(
"... ",
style:widget.styleText?? TextStyle(color: widget.moreBackgroundTest),
),
),
GestureDetector(
child: Text("更多>",
style: TextStyleFactory.styleSubtitle3(
context, 12, Colors.blue)),
onTap: () {
_isShowText();
},
),
],
)),
),
],
);
}
} else {
return Text(
_text,
maxLines: widget.mMaxLine,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style:widget.styleText?? TextStyle(color: Colors.black),
);
}
}
bool IsExpansion(String text) {
TextPainter _textPainter = TextPainter(
maxLines: widget.mMaxLine,
text: TextSpan(
text: text, style: TextStyle(fontSize: 16.0, color: Colors.black)),
textDirection: TextDirection.ltr)
..layout(maxWidth: Screen.width, minWidth: Screen.width);
if (_textPainter.didExceedMaxLines) {
//这里判断 文本是否截断
return true;
} else {
return false;
}
}
void _isShowText() {
if (mIsExpansion) {
//关闭了
setState(() {
mIsExpansion = false;
});
} else {
setState(() {
mIsExpansion = true;
});
}
}
}
空安全
class TextSpanShow extends StatefulWidget {
final String text;
final Color? colorTest;
final Color? ellipsisColorTest;
final Color? moreBackgroundTest;
final Color? moreContainerColor;
final int mMaxLine;
final bool? showColor;
final TextStyle? styleText;
final double? textSpanWidth;
final double? textSpanHeight;
const TextSpanShow(this.text,
{super.key,
required this.mMaxLine,
this.colorTest,
this.ellipsisColorTest,
this.moreBackgroundTest,
this.moreContainerColor,
this.showColor,
this.styleText,
this.textSpanWidth,
this.textSpanHeight});
@override
State<TextSpanShow> createState() => _TextSpanShowState();
}
class _TextSpanShowState extends State<TextSpanShow> {
bool mIsExpansion = false;
@override
Widget build(BuildContext context) {
return Container(
width: widget.textSpanWidth,
height: widget.textSpanHeight,
color: widget.moreContainerColor,
child: richText(
widget.text,
),
);
}
Widget richText(String text) {
if (isExpansion(text)) {
//如果需要截断
if (mIsExpansion) {
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
text,
maxLines: 100,
textAlign: TextAlign.left,
style: widget.styleText ?? TextStyle(color: widget.colorTest),
)),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_isShowText();
},
child: Container(
alignment: Alignment.bottomRight,
width: 70.rpx,
height: 30.rpx,
child: const Icon(Icons.keyboard_arrow_up),
),
),
],
);
} else {
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
text,
maxLines: widget.mMaxLine,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: widget.styleText ??
TextStyle(
color: widget.ellipsisColorTest ?? widget.colorTest),
)),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_isShowText();
},
child: Container(
alignment: Alignment.bottomRight,
width: 70.rpx,
height: 30.rpx,
child: const Icon(Icons.keyboard_arrow_down),
),
),
],
);
}
} else {
return Text(
text,
maxLines: widget.mMaxLine,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: widget.styleText ?? const TextStyle(color: Colors.black),
);
}
}
bool isExpansion(String text) {
TextPainter textPainter = TextPainter(
maxLines: widget.mMaxLine,
text: TextSpan(
text: text,
style: const TextStyle(fontSize: 16.0, color: Colors.black)),
textDirection: TextDirection.ltr)
..layout(maxWidth: 750.rpx, minWidth: 750.rpx);
if (textPainter.didExceedMaxLines) {
//这里判断 文本是否截断
return true;
} else {
return false;
}
}
void _isShowText() {
if (mIsExpansion) {
//关闭了
setState(() {
mIsExpansion = false;
});
} else {
setState(() {
mIsExpansion = true;
});
}
}
}
使用
TextSpanShow(
"t", mMaxLine: 3)