Flutter: Multiple Tap Gestures for Text - flutter

I'm looking for a way to add multiple tap gestures to a block of text.
The block of text may consist of a hyperlink. The goal is that if a user taps on the link, navigate to that web page. If they tap anywhere else on the block of text, navigate to a detail view.
I am using Linkable to detect the links. That portion works as expected, but the other tap does not.
Here is what I have tried:
return InkWell(
onTap: () {
AutoRouter.of(context).push(
// Detailed Page
);
}
},
child: Container(
padding: const EdgeInsets.all(16.0),
child: Linkable(
text: myText,
textColor: Colors.black,
linkColor: Colors.blue,
),
),
);

You can use the RichText widget to break your texts into TextSpans. Add the following code to the TextSpan you want to make clickable.
TextSpan(
text: "Clickable text.",
style: TextStyle(
color: Colors.blue,
),
recognizer: TapGestureRecognizer()
..onTap = () {
doStuff();
},
),

Related

Flutter loading text animation

How to achieve this effect with Flutter? Preferably with something like animatedContainer, but not necessarily.
Solution 1:
Look at this package: animated_text_kit
https://pub.dev/packages/animated_text_kit
See the Wavy pattern...
return DefaultTextStyle(
style: const TextStyle(
fontSize: 20.0,
),
child: AnimatedTextKit(
animatedTexts: [
WavyAnimatedText('Hello World'),
WavyAnimatedText('Look at the waves'),
],
isRepeatingAnimation: true,
onTap: () {
print("Tap Event");
},
),
);
Solution 2:
There are several more general packages that provide out of the box and ready to use Loading animations... (but not necessarily the exact same animation from your link)
Links:
https://pub.dev/packages/flutter_easyloading
Flutter loading text animation
Flutter loading text animation

How to pop a bubble at the point I touch in Flutter?

I installed speech balloon package for Flutter. I made the design in the image myself with the Column and Row widgets to tell you what I want. What I want is for this message bubble to appear at the clicked point when the button is clicked (the SpeechBalloon widget has an offset parameter) and disappear after a while or when I click it again. For this the bubble needs to appear in a new layer, like the Stack widget. But I don't know how to do this. I will be very happy if you can help.
Actually, there will be Text widgets and TextButton widgets in the Wrap widget. That's why the message bubble needs to be on a top layer.
Wrap(
children: [
for (var i = 0; i < newItems.length; i++)
(unknownWords.containsKey(newItems[i]))
? GestureDetector(
onTap: (){
SpeechBalloon("Mean of word: ${unknownWords[newItems[i]]}"),
//This algorithm definitely works, I tried it before with the easy_loading package. But I want it to be displayed below the clicked point.
},
child: Text(
word.split(" ")[i] + " ",
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
backgroundColor: Colors.yellow.shade900,
),
),
)
: Text(
word.split(" ")[i] + ' ',
style: TextStyle(fontSize: fontSize),
),
],
);

Flutter how to remove open routes when changing page inside IndexedStack

In my app I have a NavigationRail on the left and the main body on the right. I'm using nested Navigators so that when a widget inside the IndexedStack pushes a new route the NavigationRail stays on the screen. But this generates a problem when there is a new Navigator Route on the screen and I try to change the page with NavigationRail it changes the selected icon, but the Navigator route stays on the screen.
Row(
children: [
// GestureDetector uses onHorizontalDragStart to make the Navigation
// Rail extend or shrink
GestureDetector(
onHorizontalDragStart: (details) {
setState(() {
_navRailExtended = !_navRailExtended;
});
},
child: NavigationRail(
// The width of the navigation rail
minExtendedWidth: 180,
// Text and icon themes for selected destinations
selectedIconTheme:
IconThemeData(color: Colors.purple[600]),
selectedLabelTextStyle: TextStyle(
color: Colors.purple[600],
fontWeight: FontWeight.bold,
fontSize: 16),
// Text and icon themes for unselected destinations
unselectedIconTheme:
IconThemeData(color: Colors.grey[200]),
unselectedLabelTextStyle: TextStyle(
color: Colors.grey[400],
fontWeight: FontWeight.bold,
fontSize: 15),
// Background color of the navigation rail, typical
// color for the dark theme in Flutter
backgroundColor: const Color.fromARGB(255, 47, 47, 47),
// extended makes the navigation rail wider
extended: _navRailExtended,
selectedIndex: _pageIndex,
onDestinationSelected: (int index) {
setState(() {
_pageIndex = index;
});
},
destinations: const <NavigationRailDestination>[
NavigationRailDestination(
icon: Icon(Icons.explore_rounded, size: 35),
label: Text('Discover'),
),
NavigationRailDestination(
icon: Icon(Icons.home_filled, size: 35),
label: Text('Notebook'),
),
NavigationRailDestination(
icon: Icon(Icons.games_sharp, size: 35),
label: Text('Games'),
),
NavigationRailDestination(
icon: Icon(Icons.analytics_outlined, size: 35),
label: Text('Analytics'),
),
],
),
),
// A vertical divider between the navigation rail and the body
const VerticalDivider(thickness: 1.5, width: 1),
// Expanded makes the body of the windows app centered
// (without it the row widget would screw up the sizing of the app)
Expanded(
// Navigator makes all new routes inside the main pages
// opened with 'Navigator.pop()' ignore the navigation rail,
// i.e. the navigation rail will always stay opened
child: Navigator(
onGenerateRoute: (settings) {
return MaterialPageRoute(builder: ((context) {
// Indexed Stack keeps the state of each page unchanged
return IndexedStack(
index: _pageIndex,
children: const [Discover(), NoteBook(), Games(), Analytics()],
);
}));
},
),
)
],
)
App on the start:
When there is a new Navigator route on the screen:
I try to change the page:
What it should do:

Flutter: How to change button background color on the basis of condition

Description (Requirement):
I'm trying to change the button background color and handling its on press enable and disable.
I want, when user redirect to dashboard screen there will be 2 buttons time in and time out. Initially time in button will be enable (background color should be dark blue) and time out button will be disable (background color should be light blue).
Time in button will be enable when getTimeInStatus=false (i am getting this value from api), and its background color should be dark blue and when user click on time in button its text change to current time, and its background color should change to light blue and it should be disable for press. and time out button background color should be change to dark blue and user will be able to click it.
Code:
i have created two widgets, one for time in and other is time out, calling it in body.
here is time in code
Widget _timein() {
//enable
if(getTimeInStatus==false) {
return FlatButton(
color: timeInButtonPressed ? Colors.blue[200]:Colors.blue[500],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Icon(Icons.timer,),
Expanded(child:
Text(timeInText,
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
onPressed: () {
_getTime();
setState(() {
timeInText=getTime;
}
);
calltimeInApi();
timeOutButtonPressed=true;
//timeInButtonPressed=true;
}
);
}
//disable
else if(timeInText!="Time in") {
return FlatButton(
color: Colors.blue[200],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Icon(Icons.timer,),
Expanded(child:
Text(timeInText,
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
);}
}
here is time out code:
Widget _timeout(){
//enable
if(timeOutButtonPressed==true) {
return FlatButton(
color: Colors.blue[500],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Icon(Icons.timer_off,),
Expanded(child:
Text(timeOutText,
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
onPressed: () {
_getTime();
setState(() {
timeOutText=getTime;
}
);
calltimeOutApi();
}
);
}
//disable
else if(timeInText=="Time in"){
return FlatButton(
color: Colors.blue[200],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Icon(Icons.timer_off,),
Expanded(child:
Text(timeOutText,
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
);
}
}
Output:
After login, when user redirect to dashboard screen my button looks like this, and i want background color of time out light blue.
when i click on time in button this is output, but i am able to click again time in button. which is not my requirement.
Please help me how I can do this. Would add more clarification is needed.
FlatButton( color : condition ? Colors.green : Colors.grey )
Anytime you want to update the colors, setState() with the bool named 'condition' updated.
When condition is true, the color is green and when false, it's grey.

How to have multiple child with their onTaps within GestureDetector?

I have a sign-up page which contains Text like privacy policy, terms and etc and I want that on clicking those text webpage should get open.
I used the GestureDetector for that but the issue is that it contains one child only
But I want all the three texts to be there and should perform Onclick or here onTap.
Any idea?
GestureDetector(
onTap: () => launch(
'https://docs.flutter.io/flutter/services/UrlLauncher- class.html'),
child: Text('Terms of use,',
style: TextStyle(
color: Colors.blueAccent,
fontSize: 18.0,
fontWeight: FontWeight.bold)),
)
expected: all three text with onTap inside GestureDetector.
actual: only one child is there.
You can try creating a Row widget which contains the text you need, that is, privacy policy, terms and etc, as its children. And then wrap the Text widgets with GestureDetector widgets. A code snippet is given below:
Container(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: (){
print("Privacy policy");
},
child: Text("Privacy policy, "),
),
GestureDetector(
onTap: (){
print('Terms');
},
child: Text("Terms, "),
),
GestureDetector(
onTap: (){
print('Contact Us');
},
child: Text("Contact Us"),
),
],
),
),
Outputs:
Hope this helps!!
That's currently not directly supported by Flutter. But you can use RichText for implementing the requirement.
It is similar to Spannable string in Android.