This question is related to this one
Widgets inside a closed section still getting the focus
After trying with !_isOpen I tried with fixed value TRUE :
AbsorbPointer( absorbing: `TRUE`, child: content )
And I figure that the AbsorbPointer handle only the mouse events not the keyboard event, so thats why the Widgets still continue to get the Focus,
So the question is How to stop also the keyboard events RawKeyboardListener for the children ?
Related
Flutter desktop:
I'm successfully using the RawKeyboardListener widget to use physical arrow keys and control the listview (selects items up and down). The scaffold is wrapped in it.
The problem is the listview widget itself has built in default keyboard actions on the arrow keys that also scroll up and down. These actions that are randomly triggered in the listview when they are pressed along with my custom actions handled by the RawKeyboardListener.
Does anyone know how to disable default listview keyboard actions on flutter desktop to prevent it from listening to physical keyboard input / triggering built-in actions. Cheers.
In Flutter, is there a way to allow both a parent and a child to respond to a Drag Gesture and toggle between which one is receiving it mid-drag.
I have a Widget that updates its size using onVerticalDragUpdate from a GestureDetector Widget. Its child is a ListView wrapped in IgnorePointer. When the parent is the correct size I set the state to prevent the parent from responding to gestures and set ignore to false for the child to allow it to scroll.
Whilst this works, the user has to lift their finger from the screen and scroll again for the child to begin scrolling. Is there a way to achieve this with the same gesture so that if the user is still dragging and the parent reaches the correct size, the child begins to scroll instead all without having to lift the finger.
Here is a simplified example.
final ignorePointer = useState<bool>(true); // hook state
double desiredSize = 100;
GestureDetector(
onVerticalDragUpdate: ignorePointer ? (details){
if((details.globalPosition.dy / desiredSize) >= 1){
ignorePointer.value = false;
}
} : null,
child: IgnorePointer(
ignoring: ignorePointer.value,
child: ListView(
children:[for(int i = 0; i < 100; i++) Text('Boo $i')]
),
),
);
The way that Gestures and other pointer events work is that the Gesture furthest down the stack that can receive an input, will receive an input. Whilst IgnorePointer can prevent a child element receiving the input, the GestureDetector won't 'let go' of its 'win' as the receiving input until that gesture comes to an end. So changing the state of IgnorePointer mid-drag will change the state but not undo the win of GestureDetector as the receiving input until that Gesture ends.
What is needed here is a way for both the ListView and the GestureDetector to receive the user input. Then with logic decide which one (or both) is going to act on the user input.
Therefore you need a Widget that can register the user input without blocking other Widgets also receiving user input.
There's a Widget for that: Listener.
Behind the scenes GestureDetector engages in a little battle in something called the GestureArena that decides which Gesture wins in any battle of multiple gestures or multiple elements that could receive gestures. Listener does not engage in this battle.
So using Listener is the answer as you will now be able to receive all events received by any user input be it pointerDown, pointerUp, pointerMove etc.. etc.. regardless of anything else (like a ListView) that may also be directly responding to user inputs. You then need to decide what you do with those events.
Listener(
onPointerMove: (e) => // your logic
child: // your scrollable widget
)
I am using InteractiveViewer which enables the user to "drag" that widget around when panEnabled is true. The drag can happen using the mouse right-click or middle-click. However, I want to limit this only to the middle-click. So is there a widget, maybe like IgnorePointer, but which has a callback or something that gives me the key that caused the event and I return then true or false for ignoring or not ignoring accordingly?
I have a TextFormField which is empty by default.
I'm trying to handle the change when the user finishes editing the field (i don't have a confirm button)
How to trigger a function when the TextFormField loses focus ?
You can add a FocusNode to the field and add a listener to it, within the listener you can know if it gains/loses focus.
refer to How to listen focus change in flutter?
When you say TextFormField loses focus, I am assuming that whenever the user clicks anywhere other than the TextFormField on the screen, the TextFormField loses focus.
In that case, you can wrap the entire widget with a GestureDetector and inside the onTap function
GestureDetector(
onTap: (){}, //call the function here
);
I want to disable GestureArena which decides the preference of gestures,
is there any possible way to do this?
About Gesture disambiguation
you can try an IgnorePointer widget or an AbsorbPointer widget.
IgnorePointer prevents its children from receiving pointer events but is itself invisible to hit testing.
AbsorbPointer prevents its subtree from receiving pointer events by terminating hit testing at itself.