Created
April 23, 2020 04:32
-
-
Save prafullakumar/649715dbd9edc56a5072afd3ff06975c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/gestures.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/rendering.dart'; | |
import 'package:flutter/widgets.dart'; | |
void main() => runApp(MaterialApp( home: DemoApp())); | |
class DemoApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text( | |
'Read More Text', | |
)), | |
body: SingleChildScrollView( | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: <Widget>[ | |
Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: ExpandableText( | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque scelerisque efficitur posuere. Curabitur tincidunt placerat diam ac efficitur. Cras rutrum egestas nisl vitae pulvinar. Donec id mollis diam, id hendrerit neque. Donec accumsan efficitur libero, vitae feugiat odio fringilla ac. Aliquam a turpis bibendum, varius erat dictum, feugiat libero. Nam et dignissim nibh. Morbi elementum varius elit, at dignissim ex accumsan a', | |
trimLines: 2, | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
class ExpandableText extends StatefulWidget { | |
const ExpandableText( | |
this.text, { | |
Key key, | |
this.trimLines = 2, | |
}) : assert(text != null), | |
super(key: key); | |
final String text; | |
final int trimLines; | |
@override | |
ExpandableTextState createState() => ExpandableTextState(); | |
} | |
class ExpandableTextState extends State<ExpandableText> { | |
bool _readMore = true; | |
void _onTapLink() { | |
setState(() => _readMore = !_readMore); | |
} | |
@override | |
Widget build(BuildContext context) { | |
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context); | |
final colorClickableText = Colors.blue; | |
final widgetColor = Colors.black; | |
TextSpan link = TextSpan( | |
text: _readMore ? "... read more" : " read less", | |
style: TextStyle( | |
color: colorClickableText, | |
), | |
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( | |
text: widget.text, | |
); | |
// Layout and measure link | |
TextPainter textPainter = TextPainter( | |
text: link, | |
textDirection: TextDirection.rtl,//better to pass this from master widget if ltr and rtl both supported | |
maxLines: widget.trimLines, | |
ellipsis: '...', | |
); | |
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 | |
int endIndex; | |
final pos = textPainter.getPositionForOffset(Offset( | |
textSize.width - linkSize.width, | |
textSize.height, | |
)); | |
endIndex = textPainter.getOffsetBefore(pos.offset); | |
var textSpan; | |
if (textPainter.didExceedMaxLines) { | |
textSpan = TextSpan( | |
text: _readMore | |
? widget.text.substring(0, endIndex) | |
: widget.text, | |
style: TextStyle( | |
color: widgetColor, | |
), | |
children: <TextSpan>[link], | |
); | |
} else { | |
textSpan = TextSpan( | |
text: widget.text, | |
); | |
} | |
return RichText( | |
softWrap: true, | |
overflow: TextOverflow.clip, | |
text: textSpan, | |
); | |
}, | |
); | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
add
to unlimited maxline textSpan. otherwise the text will not visible. default color is white.