본문 바로가기
개발/플러터(Flutter)

Flutter 위젯 탐방기 - 오늘의 위젯 정리하기[단축키편]

by 수인분당선 2026. 2. 9.

안냐세염.

오늘의 위젯을 정리하던 중,, 삼총사 위젯을 발견하게되엇습니다.

뭔가 이 개념은 조금 어렵기도 하고 하나로 묶어서 따로 정리해두면 좋을 것 같아서 위젯 3가지를 한번에 묶어서 단축키편을 만들어보았습니다.

 

세가지가 어우러져 하나의 기능을 정의하고있기때문에 흐름을 잘 알아보도록 하겠습니다.


이 세가지위젯을 통해 우리가 무엇을 하고자 하느냐,,하면

사용자로부터 받은 키 입력에 대한 이벤트를 처리.라고 할 수 있겠습니다.

 

각각의 세부 기능이나 역할에 대해 알아보기 전에 키보드의 입력 흐름으로부터 이 세가지 요소가 어떻게 흘러가는지 네줄 요약해보겠습니다.

키 입력
 → Focus (누가 키 이벤트를 받을지에 대한 결정)
 → Shortcuts (이 이벤트가 어떤 의미를 가진 이벤트인지를 해석하고 변환)
 → Actions (실제 실행)

 

위 흐름을 기반으로 차근차근 각각의 역할에 대해서 알아보도록 합시다

숨참고 바로 다이브.


1. Focus

https://www.youtube.com/watch?v=JCDfh5bs1xc&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=45

 

: 이 위젯이 이벤트를 받는다는 것을 선언하는 위젯. Focus의 직역인 초점을 맞추다. 라는 의미와 동일

 

포커스에 대해 알아보기 전에 FocusNode에 대해 알아봅시다..

FocusNode의 개념

: Flutter가 어떤 위젯을 우선적으로 입력 대상으로 삼을지 제어하는 객체



Flutter에는 Focus Tree라는 개념이 존재합니다.

이 Focus Tree안에서는 FocusNode 가 존재하고, 한 시점에 하나의 FocusNode가 활성화되는 구조입니다.

FocusNode는 키보드 입력을 받았을 때, 입력을 처리할 시작점이라고 볼 수 있습니다. 

Focus의 특징

  • 버튼이나 텍스트 입력창같은 UI의 모든 상호작용 영역을 포함해 위젯 트리 전체에 이미 존재하고있음
    • = 사용자의 이벤트를 받는 버튼, 텍스트 입력창과 같은 위젯에는 이미 내장되어있으므로, 대부분의 경우 개발자가 직접 이 위젯을 다룰 일이 없음
    •  
    • 다만, 커스텀 위젯이나 키보드 상호작용을 설계하는 경우 필요함
  • FocusNode를 가지고 있고, 이를 통해 Focus의 이동, 요청 해제가 가능함

쉽게 키보드 입력의 흐름으로부터 살펴보자면

키보드 입력이 발생했을 때,

1. 현재 활성화된 FocusNode(포커스된 위젯) 가 먼저 이벤트를 받는다.
2. 그 위젯에서 처리하지 않으면 위젯 트리를 위로 올라가며(Focus → 부모 Focus …) 이벤트가 전달된다.
3. 올라가는 과정에서 Shortcuts 위젯이 입력 키를 발견하면 Intent로 변환한다.(Shortcuts에서 계속,,)
4. 변환된 Intent는 해당 위치의 Actions 위젯이 실행한다.

이런역할을 처리한다고 보시면됩니다. 

 

주의사항 

  • Focus 없이 Shortcuts / Actions는 동작하지 않을 수 있습니다.
  • FocusNode를 직접 생성했다면 dispose()에서 반드시 해제해야 메모리 누수를 방지할 수 있습니다.
  • 하나의 화면에서 여러 FocusNode가 있을 경우 현재 어느 노드가 primary focus인지 잘 확인해야 합니다.

활용 예제

//헤더를 Focus로 감싸서 키보드 포커스를 받을 수 있게 한 상태에서, 키보드로 패널을 열고 닫는 방법
Focus({
	FocusNode? node,
    Widget? child,
}) : node = node ?? FocusNode();

Accordion(
	children: <Widget>[
    	Header(
        	child: Focus(
            		child: Text('section 1'),
                   ),
             ),
         ),
        Section1Body(),
    ]
)

2. Shortcuts

위에서 Shortcuts 위젯이 입력 키를 발견하면 Intent로 변환한다.라는 멘트에 대한 자세한 이해를 위해 이제는 Shortcuts에 대해 알아보도록 하겠습니다.

https://www.youtube.com/watch?v=6ZcQmdoz9N8&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=43

 

: 키보드의 입력을 하나의 Intent로 변환해주는 위젯

 

역시 이 Shortcuts를 알아보기 전에 깨알 Intent개념을 알아봅니다.

 

Intent의 개념

: 어떤 행동을 할 것인지에 대한 정의

어려운 개념은 아니고 간단하게 Enter => 확인버튼을 의미한다! 와 같은 변환과정입니다.

Shortcuts 특징

  • 앱 전반에 걸친 키보드 이벤트들을 연결하는 법을 알려주는 위젯
  • 여러 개의 Shortcuts 위젯을 트리 위치별로 둘 수 있음
  •  
  • shortcutActivators: 도움 클래스로써 메타 키 수정자로 특정 키조합을 파일화함
    • Flutter는 Activator와 일치하는 키 입력을 발견하면 해당 Intent를 생성하고, 현재 활성화된 FocusNode 기준으로 이를 처리할 Actions를 탐색

 

이제 아까 말한 동작 흐름에 이 Shortcuts의 살을 덧붙인다면 

1. 현재 활성화된 FocusNode(포커스된 위젯) 가 먼저 이벤트를 받는다.
2. 그 위젯에서 처리하지 않으면 위젯 트리를 위로 올라가며(Focus → 부모 Focus …) 이벤트가 전달된다.
3-1. 올라가는 과정에서 Shortcuts 위젯이 입력 키를 발견하고 키 조합을 확인한다.
3-2. Shortcuts 위젯 내에 정의된 키 조합을 발견하고 이에 대한 ShortcutActivator 를 매칭한다.
3-3. 이를 하나의 Intent로 변환한다.
4. 변환된 Intent는 해당 위치의 Actions 위젯이 실행한다.

 

주의사항

  • 반드시 ShortcutActivator → Intent 매핑을 제공해야 동작이 이루어질 수 있습니다.
  • 반드시 Actions와 함께 사용해야합니다.
  • rebuild 시 shortcut 맵을 계속 새로 만들면 성능에 영향을 끼칠 수 있으므로, 가능하면 const 사용하는 것을 권장합니다.

활용 예제

//컨트롤+C 만들기
final controlC = SingleActivator(
	LogicalKeyboardKey.keyC,
    control: true
)

//기본 intent클래스를 확장하고 사용자가 원하는 결과를 설명해줌
class CopyIntent extends Intent{}

// 적용!
Accordion(
	child: Shortcuts(
    	shortcuts: {
        	controlC: CopyIntent(), 
        },
     	child:AccordionSections(),
    ),
)

 


3. Actions

https://www.youtube.com/watch?v=XawP1i314WM&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=42

 

: 사용자의 Intent를 실제 로직으로 실행시키는 위젯

특징

  • Flutter의 키보드 입력 처리 흐름은 직접적으로 키 이벤트를 받는 구조가 아니고, 위에서의 구성요소로 인해 받아온 Intent를 그저 실행하는 위젯
  • Actions: 실제 어떤 동작을 실행할 것인가를 나타내는 동작으로 Action<Intent>를 상속
  • Actions위젯: Intent타입에 Action인스턴스로 매핑함(위젯트리 안에서 동작)

주의사항

  • Focus로 처리하지 않으면 아무런 동작도 하지 못합니다.
  • Actions는 위젯 트리 아래로 전파됩니다.
  • 같은 Intent가 여러 Actions에 정의되면 가장 가까운 Actions가 실행됩니다. 
  • 모바일에서는 키보드 기반 액션 활용도가 낮습니다.

활용 예제

final actionsMap = {
	MyFirstIntent: MyFirstAction(),
    MySecondIntent: MySecondAction(),
};

Actions(
	//actions: <Type, Action<Intent>>{},
	actions: actionsMap,
    child: AccordionSections(),
)

class MyFirstAction extends Action<MyFirstIntent> {

	@override
    void invoke(
    	MyFirstIntent intent, 
    ) => doSomething();
}

Actions까지 알아보고 난 후, 키보드 입력에 대한 처리를 다시 한 번 구체적으로 정의하면

1. 현재 활성화된 FocusNode(포커스된 위젯) 가 먼저 이벤트를 받는다.
2. 그 위젯에서 처리하지 않으면 위젯 트리를 위로 올라가며(Focus → 부모 Focus …) 이벤트가 전달된다.
3-1. 올라가는 과정에서 Shortcuts 위젯이 입력 키를 발견하고 키 조합을 확인한다.
3-2. Shortcuts 위젯 내에 정의된 키 조합을 발견하고 이에 대한 ShortcutActivator 를 매칭한다.
3-3. 이를 하나의 Intent로 변환한다.
4-1. 변환된 Intent가 해당 위치의 Action으로 매핑되어 실제 동작이 무엇인지 정의된다
4-2. Actions위젯을 통해 Action의 동작을 실행한다.

가장 처음 정의한 내용과 같지만 흐름을 보니 조금 더 구체적으로 이해할 수 있겠습니다..

많이 사용될 것 같지는 않은 개념이지만 그래도 알아둘 필요는 있는 개념이니 한 번 보고가는 것도 좋을 것 같네용