플러터의 GlobalKey
란?
- 전체 앱에서 고유한 키이다.
- 전체 앱에서 위젯을 고유하게 식별하는 데 사용된다.
- 위젯 트리 전체에서 보존해야 하는 위젯의 상태를 유지하는 것이 목적이다.
상태 보존
GlobalKey
를 사용하면 위젯 트리에서 위젯을 이동해도 연결된 위젯의 상태가 유지된다.- 원래 위젯 트리의 일부를 재빌드하면 해당 트리의 위젯 상태가 손실된다.
위젯 트리 전체 액세스
GlobalKey
를 사용하면 앱 어느곳에서나 위젯에 액세스 가능하다.- 앱의 다른 부분에서 위젯의 상태나 기능에 액세스해야 하는 경우 유용하다.
고유 식별자
GlobalKey
는 앱 전체에서 고유하다.
사용 사례
- 앱의 다른부분에서 위젯의 상태에 액세스
- 위젯 트리 내에서 위젯이 이동할 때 위젯의 상태 유지
- ex. 목록 위젯이 다시 빌드될 때 목록에서 스크롤 위치 유지
주의점
GlobalKey
를 과도하게 사용하면 위젯 간 긴밀한 결합이 만들어지고 위젯 트리 자체가 복잡해진다.- 성능 문제가 발생할 수 있다.
- 하위 트리로만 소통하는 경우엔 로컬 키 혹은 기타 상태 관리 솔루션을 사용하는 것이 좋다.
구현
GlobalKey
를 사용하려면,GlobalKey
의 인스턴스를 만들어 위젯에 할당한다.- 나중에 이 키를 사용하여 위젯의 상태에 액세스할 수 있다.
예제 코드
Form
에 GlobalKey
이용하기
- 아래의 예제에서는
GlobalKey
를 이용해Form
위젯 밖에서Form
의 각 필드가validate
가 되었는지 확인할 수 있다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter GlobalKey Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
// Define a GlobalKey for the form
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
void _validateForm() {
if (_formKey.currentState!.validate()) {
// If the form is valid, proceed further
print('Form is valid!');
} else {
// If the form is invalid, show a message
print('Form is not valid!');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter GlobalKey Example'),
),
body: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
ElevatedButton(
onPressed: _validateForm,
child: Text('Submit'),
),
],
),
),
);
}
}
다른 위젯에 GlobalKey
를 넘겨 상태 제어하기
CustomWidget
에 키를 넘겨CustomWidget
의incrementCount()
메서드를MyHomePage
위젯에서 실행할 수 있다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter GlobalKey Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
// Define a GlobalKey for the custom widget
final GlobalKey<_CustomWidgetState> _customWidgetKey = GlobalKey<_CustomWidgetState>();
void _incrementCounter() {
_customWidgetKey.currentState!.incrementCounter();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter GlobalKey Example'),
),
body: Center(
child: CustomWidget(key: _customWidgetKey),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class CustomWidget extends StatefulWidget {
CustomWidget({Key? key}) : super(key: key);
@override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
int _counter = 0;
void incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Text('Counter: $_counter');
}
}
반응형
'플러터' 카테고리의 다른 글
플러터(Flutter) 프로바이더(Provider) 라이브러리란? (0) | 2023.12.17 |
---|---|
플러터(Flutter) 에서 자주 쓰는 GetIt 패키지란? (0) | 2023.12.07 |
플러터의 Drift 라이브러리(플러그인) 이란? (0) | 2023.12.03 |
플러터 (Flutter) 의 initializeDateFormatting() 메서드의 역할과 사용법 (0) | 2023.12.03 |
플러터(Flutter) 의 WidgetsFlutterBinding.ensureInitializing() 이란? (0) | 2023.12.02 |