My Container having a description about movies.
Initially i want to show only few lines of description. And below to that there should be a link (more...
ExpandableText with regrex validation as well.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class ExpandableText extends StatefulWidget {
ExpandableText(this.text);
final String text;
// bool isExpanded = false;
@override
_ExpandableTextState createState() => new _ExpandableTextState();
}
class _ExpandableTextState extends State {
String text;
bool canExpand = false;
bool isExpand = false;
@override
Widget build(BuildContext context) {
//
canExpand = widget.text != null && widget.text.length >= 150;
text = canExpand
? (isExpand ? widget.text : widget.text.substring(0, 150))
: (widget.text);
return canExpand
? Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildTextWithLinks(text.trim()),
GestureDetector(
onTap: () {
setState(() {
isExpand = !isExpand;
});
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(isExpand ? ' ... show less' : ' ... show more'
),
),
),
],
)
: Text(text != null ? text : "");
}
}
Text buildTextWithLinks(String textToLink, {String text}) =>
Text.rich(TextSpan(children: linkify(textToLink)));
Future openUrl(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
const String urlPattern =
r"(https?|http)://([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:,.;]*)?";
const String emailPattern = r'\S+@\S+';
const String phonePattern = r'[\d-]{9,}';
final RegExp linkRegExp = RegExp(
'($urlPattern)|($emailPattern)|($phonePattern)',
caseSensitive: false);
WidgetSpan buildLinkComponent(String text, String linkToOpen) => WidgetSpan(
child: InkWell(
child: Text(
text,
style: TextStyle(
color: Colors.red,
decoration: TextDecoration.underline,
),
),
onTap: () => openUrl(linkToOpen),
));
List linkify(String text) {
final List list = [];
final RegExpMatch match = linkRegExp.firstMatch(text);
if (match == null) {
list.add(TextSpan(text: text));
return list;
}
if (match.start > 0) {
list.add(TextSpan(text: text.substring(0, match.start)));
}
final String linkText = match.group(0);
if (linkText.contains(RegExp(urlPattern, caseSensitive: false))) {
list.add(buildLinkComponent(linkText, linkText));
} else if (linkText.contains(RegExp(emailPattern, caseSensitive: false))) {
list.add(buildLinkComponent(linkText, 'mailto:$linkText'));
} else if (linkText.contains(RegExp(phonePattern, caseSensitive: false))) {
list.add(buildLinkComponent(linkText, 'tel:$linkText'));
} else {
throw 'Unexpected match: $linkText';
}
list.addAll(linkify(text.substring(match.start + linkText.length)));
return list;
}