How can I implement tap-able Text widget, Flutter? - flutter

I have a Text widget on pressing which another Route has to be shown. But I could not see any onPressed() method for the Text widget. Please Help.

In your case there are multiple routes where you can go.
Using material TextButton:
TextButton(onPressed: () {}, child: Text('Your child'))
Using InkWell Widget, which covers your widget with 'as button' properties, splashes etc, which allows you to have more customisable buttons taps:
InkWell(onTap: () {}, onDoubleTap: () {}, onLongPress: () {}, onHover: () {}, ..etc , child: Text('Your child widget'))
Using GestureDetector, is the most customisable solution for any gestures you can provide (from its name), can handle taps, long presses, double taps, drags etc.
Syntax is similar:
GestureDetector(onTap: () {}, child: Text('Your child widget'))

Try using TextButton widget:
TextButton(
onPressed: () {},
child: Text('Simple Button'),
),

The best way to make any widget tappable is to use GestrureDetector you just put it outside of the widget/widgets you want and you can use dozen of properties.
For example
GestureDetector(child:
onPressed: () {},
Text('Your text')
)

Related

How to get tap event inside absorb pointer

I have a page containing many widgets which is opened in view only mode. i used AbsorbPointer for ignoring user inputs. but in some cases i have to get onTap event on one button which is inside AbsorbPointer. how can i achieve that ?
I tried using GestureDetector but its not giving onTap event.
any idea??
AbsorbPointer(
absorbing:true,
child: Column(children: [
Text("HELLO"),
Text("HELLO 2"),
GestureDetector(
onTap: () {
showToast("I tried this");
},
child: IconButton(
icon: Icon(
Icons.local_offer,
color: Colors.red,
),
onPressed: () {
print("I need this event");
},
),
)
]),
);
use absorbing: property for your cases... set it to false in the case you want to allow the GestureDetector inside

How to make InkWell `onLongPress()` override tap on a TextField inside of it?

I have a TextField inside of an InkWell with an onLongPress() callback. The problem is, despite the fact that even when long pressing on the TextField, I see the ripple effect on InkWell, but the onLongPress() does not run after the long press time passes. It only gets me into editing Text. When pressing on the bottom side of the Card, everything runs fine.
In short: On tap I want to get into TextField editing. On long press I want to trigger the onLongPress(), not the TextField, even if I am pressing on it.
How do I do this? Thank you.
InkWell(
onLongPress: () {
// do stuff
}
child: ListTile(
title: TextField(),
),
),
You can use the AbsorbPointer widget to ignore the TextField gesture recognizer:
InkWell(
onLongPress: () {
print('onLongPress');
},
child: AbsorbPointer(
child: ListTile(
title: TextField(),
),
),
)
To still enabling the editing of TextField when single tapping on it, you can use FocusNode like this:
InkWell(
onLongPress: () {
print('onLongPress');
},
onTap: () => node.requestFocus(),
child: AbsorbPointer(
child: ListTile(
title: TextField(
focusNode: node,
controller: textController,
),
),
),
)
#Bach 's answer helped me to find a solution. Thank you!
InkWell(
onLongPress: () {
// do stuff
},
child: ListTile(
title: GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(_focusNode),
child: AbsorbPointer(
child: TextField(
focusNode: _focusNode,
),
),
),
),
The only problem is now that I started messing with focusNode, multiple input fiels are focusing at the same time. But that is a whole other story ;)
UPD: Just realised, that I can't move text cursor this way. So not useful.
It seems that IntrinsicWidth widget can find the right balance between long press and text editing.
The rationale behind is that IntrinsicWidth will let the TextField shrink to its minimum width, therefore avoiding a gesture collision with the InkWell
So your solution can be like this:
InkWell(
onLongPress: () {
// do stuff
}
child: ListTile(
child: IntrinsicWidth(
title: TextField(
//remember to make some hints here
//because with intrinsicwidth if your textfield is empty it might disappear
),
),
),
),

TextButton.icon and ElevatedButton.icon: is it possible to show the label first then the icon?

I can't seem to find a parameter that lets the widgets TextButton.icon and ElevatedButton.icon place the label first then the icon. Is there a way or do I have to make a custom widget for this?
Example:
ElevatedButton.icon(
onPressed: () { /* code */ },
icon: Icon(Icons.arrow_forward),
label: Text('Some text'),
)
Both icon & label accepts a Widget. So you could do this:
ElevatedButton.icon(
icon: Text('A'),
label: Icon(Icons.add),
onPressed: () {},
),

floatingActionButton shows but figure is empty

Hello This is my code:
floatingActionButton: FloatingActionButton(onPressed:(){
Icon(Icons.edit);
} ,),
The problem is, when i add any icon (like icons.edit or icons.alarm etc.), it shows empty circular button.
floatingActionButton: FloatingActionButton(
onPressed: () {
//do something
},
child: Icon(Icons.edit),
),
This is because you are putting the Icon inside on onPressed. OnPressed is code that executes when the button is pressed, add a child Icon widget.
You haven't added a child to the FloatingActionButton.
Specify the child property of FloatingActionButton
floatingActionButton: FloatingActionButton(
child: Icon(Icons.edit, color: Colors.white),
onPressed:(){
// onPressed function
},
),

Handle tap event in parent widget

In my app tree I have two widgets:
GestureDetector(
onTap: () => print('Outer'),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () => print('Inner')),
),
)
Both of them are trying to react to touch event but only child's callback is invoked (which is default behaviour). Is it possible to define widgets in a way that will prevent ancestor from propagating touch event to its children? Or maybe the only way is to implement such behaviour on your own, e.g. by making use of GestureArena?
I think you are looking for the AbsorbPointer widget:
A widget that absorbs pointers during hit testing.
When absorbing is true, this widget prevents its subtree from
receiving pointer events by terminating hit testing at itself. It
still consumes space during layout and paints its child as usual. It
just prevents its children from being the target of located events,
because it returns true from RenderBox.hitTest.
You can use it like this:
GestureDetector(
onTap: () => print('Outer'),
child: AbsorbPointer(
child: IconButton(
icon: Icon(Icons.add),
onPressed: () => print('Inner'),
),
),
),