How to add hyperlinks to Flutter's RichText widget
Before building out the above terms of service and privacy policy widget, I hadn't delved much into Flutter's RichText class. Figuring out how to add the hyperlinks was a bit more involved than expected, but thanks to this StackOverflow thread, the widget was built quickly and worked well.
Note that opening the URLs requires using the url_launcher package and, in my case, a service class that wraps its functionality (not shown below).
Here's my implementation:
class TermsAndPrivacy extends StatefulWidget {
@override
_TermsAndPrivacyState createState() => _TermsAndPrivacyState();
}
class _TermsAndPrivacyState extends State<TermsAndPrivacy> {
TapGestureRecognizer _termsOfServiceLink;
TapGestureRecognizer _privacyPolicyLink;
@override
void initState() {
super.initState();
_termsOfServiceLink = TapGestureRecognizer()..onTap = _termsOfServiceOnTap;
_privacyPolicyLink = TapGestureRecognizer()..onTap = _privacyPolicyOnTap;
}
@override
void dispose() {
_termsOfServiceLink.dispose();
_privacyPolicyLink.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Center(
child: Column(
children: [
Text(
'By using Clearful, you agree to our ',
style: Theme.of(context).textTheme.overline,
),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
TextSpan(
text: 'Terms of Service',
style: Theme.of(context)
.textTheme
.overline
.copyWith(fontWeight: FontWeight.w800),
recognizer: _termsOfServiceLink
..onTap = _termsOfServiceOnTap,
),
TextSpan(
text: ' and ',
style: Theme.of(context).textTheme.overline,
),
TextSpan(
text: 'Privacy Policy',
style: Theme.of(context)
.textTheme
.overline
.copyWith(fontWeight: FontWeight.w800),
recognizer: _privacyPolicyLink..onTap = _privacyPolicyOnTap,
),
TextSpan(
text: '.',
style: Theme.of(context).textTheme.overline,
),
],
),
),
],
),
),
);
}
Future<void> _termsOfServiceOnTap() async {
await locator<UrlLauncher>().launchUrl(url: termsOfServiceUrl);
}
Future<void> _privacyPolicyOnTap() async {
await locator<UrlLauncher>().launchUrl(url: privacyPolicyUrl);
}
}