Search code examples
flutterfocus

Flutter: Jump out of "Focus" Widget on key pressed


I want to traverse a Focus-Group with arrow keys, so that the next/previous focusNode is selected. On tab/shift+tab I want the focus to jump out of that focus group, to the next/previous focusNode OUTSIDE my Focus-Group:

Focus(
  onKey: (focusNode, event) {
     if (event.runtimeType == RawKeyDownEvent) {
      if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
          focusNode.nextFocus();
          return KeyEventResult.handled;

      } else if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
          focusNode.previousFocus();
          return KeyEventResult.handled;

      } else if (event.logicalKey == LogicalKeyboardKey.tab) {
          if(RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft))){ 

            // TODO: JUMP FOCUS OUT OF THIS FOCUS WIDGET 
            // TO THE FOCUS NODE ABOVE/BEFORE THIS FOCUS WIDGET

          } else {

            // TODO: JUMP FOCUS OUT OF THIS FOCUS WIDGET 
            // TO THE FOCUS NODE BELOW/AFTER THIS FOCUS WIDGET

          }
          return KeyEventResult.handled;
      }
     }
     return KeyEventResult.ignored;
  },
  child: ...

Solution

  • Solution was:

    bool someoneInListHasPrimaryFocus(Iterable<FocusNode> descendants){
      for (FocusNode fn in descendants) {
        if(fn.hasPrimaryFocus) return true;
      }
      return false;
    }
    
                            Focus(
                              onKey: (focusNode, event) {
                                if (event.runtimeType == RawKeyDownEvent) {
                                  if (event.logicalKey == LogicalKeyboardKey.arrowDown || event.logicalKey == LogicalKeyboardKey.arrowRight) {
                                    focusNode.nextFocus();
                                    return KeyEventResult.handled;
                                  } else if (event.logicalKey == LogicalKeyboardKey.arrowUp || event.logicalKey == LogicalKeyboardKey.arrowLeft) {
                                    focusNode.previousFocus();
                                    return KeyEventResult.handled;
                                  } else if (event.logicalKey == LogicalKeyboardKey.tab) {
                                    if(RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft) || RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftRight)){ //You think shiftLeft + shiftRight = shift? HAHAHA think again
                                      FocusNode firstElement = focusNode.descendants.first;
                                      firstElement.requestFocus();
                                      firstElement.previousFocus();
                                    } else {
                                      if(someoneInListHasPrimaryFocus(focusNode.descendants)){
                                        FocusNode lastElement = focusNode.descendants.last;
                                        lastElement.requestFocus();
                                        lastElement.nextFocus();
                                      } else {
                                        FocusNode firstElement = focusNode.descendants.first;
                                        firstElement.requestFocus();
                                      }
                                    }
                                    return KeyEventResult.handled;
                                  }
                                }
                                return KeyEventResult.ignored;
                              },
                              child: ...