In my app, I have some (youtube)links, which always have the text value of "Link", but their tap launch parameter is different as the content of the page is changing.
I recognized that the app first builds these links with the initial correct value, then, upon changes, they won't get updated.
RichText _createExerciseLink(String url) {
return new RichText(
text: new TextSpan(
children: [
new TextSpan(
text: Translate.of(context).trans("exercise.link"),
recognizer: new TapGestureRecognizer()
..onTap = () {
print("Launcihng: ${url}");
launch(url);
},
),
],
),
);
}
But, if I change the text "link" to the corresponding HTTP link then it gets rerendered...
RichText _createExerciseLink(String url) {
return new RichText(
text: new TextSpan(
children: [
new TextSpan(
text: url,
recognizer: new TapGestureRecognizer()
..onTap = () {
print("Launcihng: ${url}");
launch(url);
},
),
],
),
);
}
I assume this is some kind of a caching mechanism?
Is there any way to force to recreate the whole widget?
Seems like adding a Key is the trick here:
Parent widget:
Key key = new Key(link);
...
link != null ? _createExerciseLink(link, key) : Container(),
and in the text:
RichText _createExerciseLink(String url, Key key) {
return new RichText(
key: key,
text: new TextSpan(
children: [
new TextSpan(
text: Translate.of(context).trans("exercise.link"),
recognizer: new TapGestureRecognizer()
..onTap = () {
print("Launcihng: ${url}");
launch(url);
},
),
],
),
);
}
Related
I want to add a TextButton in the middle of a paragraph in a Text widget. Similarly when writing a paragraph and want to add a button to let users route to that screen to get the desired information about something. How could I do that?
Thank you
you can use RichText to make your works clickable.
you can use like this :
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(text: 'By clicking Sign Up, you agree to our '),
TextSpan(
text: 'Terms of Service',
recognizer: TapGestureRecognizer()
..onTap = () {
print('Terms of Service"');
}),
TextSpan(text: ' and that you have read our '),
TextSpan(
text: 'Privacy Policy',
recognizer: TapGestureRecognizer()
..onTap = () {
print('Privacy Policy"');
}),
],
),
),
I have a line that has three buttons inside it. I know that I can use RichText with Gesture Recogniser to make them clickable like HTML <a href=""> tag. But I am new to flutter and don't know how can I achieve that behaviour.
Also is there any better option to do similar thing?
Also I don't want to open an External Link. Just navigate to another page.
I have attached a picture containing what I want to do. Picture of what I want to do
import 'package:flutter/gestures.dart';
and the widget
RichText(
text: TextSpan(
children: [
TextSpan(
text: "By Clicking Sign up you are agree to the ",
),
TextSpan(
text: "Privacy Policy ",
style: TextStyle(
color: Colors.lightGreen,
),
recognizer: new TapGestureRecognizer()
..onTap = () => print("Privacy Policy"),
),
TextSpan(text: "and our "),
TextSpan(
text: "Terms and Conditions ",
style: TextStyle(
color: Colors.lightGreen,
),
recognizer: new TapGestureRecognizer()
..onTap = () => print("Terms and Conditions"),
),
TextSpan(text: "and "),
TextSpan(
text: "Cookie Statement",
style: TextStyle(
color: Colors.lightGreen,
),
recognizer: new TapGestureRecognizer()
..onTap = () => print("Cookie Statement"),
),
TextSpan(text: "."),
],
),
),
does it help?
you can wrap the Text widget with GestureDetector()
GestureDetector(
child: Text(
'Clickable text'
),
onTap: () {
//go to destination page
},
)
In case if you're opening to an external link you can check URL launcher to open websites
I am trying to do a stateless widget for inline text links.
I am using this answer here https://stackoverflow.com/a/55607224/3808307 to create the links
RichText(
text: TextSpan(
children: [
TextSpan(text: 'This is a going to be a Text which has '),
TextSpan(
text: 'single tap',
style: style,
recognizer: TapGestureRecognizer()
..onTap = () {
// single tapped
},
),
TextSpan(text: ' along with '),
TextSpan(
text: 'double tap',
style: style,
recognizer: DoubleTapGestureRecognizer()
..onDoubleTap = () {
// double tapped
},
),
TextSpan(text: ' and '),
TextSpan(
text: 'long press',
style: style,
recognizer: LongPressGestureRecognizer()
..onLongPress = () {
// long pressed
},
),
],
),
)
, but I would like to have a TextSpan that I can import, and already has the styling applied, passing it a text that would act as label and a function.
Do I need a stateful widget for this, or can I just use a stateless widget?
You can use a stateless widget without a problem.
In the case that you need to change the style of the text when you press the links you will need to use a stateful widget.
I've been trying to use Flutter Linkify to show a webpage. The link I am planning to use is long (and non-esthetic). I would like to edit the link, for example I want for the screen to read 'Privacy Policy' while the link being 'https://www.long.web/address/.../'
Has anyone done something similar?
SelectableLinkify(
onOpen: (link) async {
if (await canLaunch(link.url)) {
await launch(link.url);
} else {
throw 'Could not launch $link';
}
},
text: "Terms of use: https://www.long.web/.../...",
style: Sizes.style2,
linkStyle: Sizes.styleLink,
),
I was able to find a solution for this, in case anyone needs it.
Container(
width: SizeConfig.safeBlockHorizontal * 75,
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: 'I accept the ',
style: Sizes.style2,
),
TextSpan(
style: Sizes.styleLink,
text: 'Terms of Use',
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = 'web where doc is hosted';
if (await canLaunch(url)) {
await launch(
url,
forceSafariVC: false,
);
}
},
),
TextSpan(
text: ' and ',
style: Sizes.style2,
),
TextSpan(
style: Sizes.styleLink,
text: 'Privacy Policy',
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = 'web where doc is hosted';
if (await canLaunch(url)) {
await launch(
url,
forceSafariVC: false,
);
}
},
),
],
),
),
)
All you have to do is add your own webpage so the link opens it, we just used the same page where our privacy policy is so users could access it.
I am using something like this to have links in text inside a paragraph
RichText(
text: TextSpan(
children: [
TextSpan(text: 'This is a going to be a Text which has '),
TextSpan(
text: 'single tap',
style: style,
recognizer: TapGestureRecognizer()
..onTap = () {
// single tapped
},
),
],
),
)
Now, it works fine, but I cannot have a hand cursor when rolling over the text?
I was looking on how to do it and found this
MouseRegion(
cursor: SystemMouseCursors.click,
child: Container(
height: 30,
width: 30,
color: Colors.red,
),
),
but is not possible to wrap one of the TextSpans in a Container and MouseRegion.
You can create a custom WidgetSpan like this:
class MouseRegionSpan extends WidgetSpan {
MouseRegionSpan({
#required MouseCursor mouseCursor,
#required InlineSpan inlineSpan,
}) : super(
child: MouseRegion(
cursor: mouseCursor,
child: Text.rich(
inlineSpan,
),
),
);
}
and wrap your TextSpan with it:
MouseRegionSpan(
mouseCursor: SystemMouseCursors.click,
inlineSpan: TextSpan(
text: 'single tap',
style: style,
recognizer: TapGestureRecognizer()
..onTap = () {
// single tapped
},
),
),
Recently, this feature has been added to TextSpans.
As of Flutter 5647407 on master (probably going to be in the 2.1.0 release), the mouse cursor is clickable (hand cursor) by default. So you do not need to take any action other than upgrading Flutter.
Manually specifying
You can manually specify the mouseCursor property:
TextSpan(
text: 'single tap',
style: style,
mouseCursor: MaterialStateMouseCursor.clickable,
recognizer: TapGestureRecognizer()
..onTap = () {
// single tapped
},
),
Furthermore, there are now onEnter and onExit callbacks for responding to the mouse entering and leaving the text span.
Default SystemMouseCursors.click
If you take a look at the commit, you will notice that the default is now SystemMouseCursors.click when you specify a recognizer.