함수를 인수로 전달하는 방법에 대해 궁금한 적이 있습니다. 아니면 기능을 유지하면서 코드를 깔끔하고 읽기 쉽게 유지할 수 있도록 전달해야 합니까?
그렇다면 들어가 보겠습니다.
Flutter는 동일한 기능을 더 많이 달성하면서 함수를 인수로 쉽게 전달할 수 있는 다양한 방법을 제공합니다. 이 기사는 이에 대해 토론하고 지식 카누에 추가하는 것을 목표로 합니다 😁
1. Function() && Function(String val)
이것이 가장 기본이며 다른 모든 구현의 기반이 됩니다. 콜백 함수에서 전달된 값을 수신할 수 있는 변형 Function(String val)을 사용 하여 값을 전달하는 옵션이 있습니다 .
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(
onTap: () {
print('I am a function with no return value');
},
function: (String val) {
print('I am a function with a return value');
},
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
//Declare the functions
final Function()? onTap;
final Function(String val) function;
MyWidget({
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Column(children: [
TextField(
//Sample usage by passing it to the onChanged value of a TextField.
//This way you will receive the Textfields value everytime it changes
onChanged: widget.function,
),
ElevatedButton(
child: Text('Simple Function Callback'),
//Sample usage by passing it to the onPressed value of an Elevated Button
//There is no return value for this function
onPressed: onTap,
)
]);
}
}
2. VoidCallback
이름에서 알 수 있듯이 어떤 값도 전달하지 않는 함수 콜백을 선언할 수 있습니다. 이는 클릭 이벤트를 수신하고 위의 Function() 처럼 전달합니다 .
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(
//Listen for the click event
voidCallback: () {
print('I am a voidCallback');
}),
),
),
);
}
}
class MyWidget extends StatelessWidget {
//Declare the variable
final VoidCallback voidCallback;
MyWidget({required this.voidCallback});
@override
Widget build(BuildContext context) {
return ElevatedButton(
//sample usage by passing it to the onPressed value of an ElevatedButton
onPressed: voidCallback,
child: Text('Am a VoidCallback'));
}
}
3. GestureTapCallback
GestureDetector 위젯 에서 탭 이벤트를 수신하는 Flutter 프레임워크에서 제공하는 콜백 중 하나입니다 . 제공되는 기타 기능으로는 GestureDoubleTapCallback, GestureTapDownCallback, GestureTapCancelCallback 등이 있습니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(
//Listen for the click events
gestureDoubleTapCallback: () {
print('I am a gestureDoubleTapCallback');
},
gestureTapCallback: () {
print('I am a gestureTapCallback');
},
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
//Declare the callbacks
final GestureTapCallback gestureTapCallback;
final GestureDoubleTapCallback gestureDoubleTapCallback;
MyWidget(
{required this.gestureDoubleTapCallback,
required this.gestureTapCallback});
@override
Widget build(BuildContext context) {
return GestureDetector(
//Assign the callbacks to their intended counterparts
onTap: gestureTapCallback,
onDoubleTap: gestureDoubleTapCallback,
child: Text('GestureDetector Callbacks'));
}
}
4. ValueChanged && ValueSetter && ValueGetter
ValueChanged — 값 변경을 수신할 때 사용됩니다.
ValueSetter — ValueChanged 와 동일한 시그니처를 갖지만 값이 변경되지 않은 경우에도 호출됩니다. 비동기 대응 AsyncValueSetter 가 있습니다 .
ValueGetter — 이벤트를 수신하고 요청 시 호출됩니다. 비동기 대응 AsyncValueGetter 가 있습니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(
//Listening to the click and input events
valueChanged: (val) {
print('I am a valueChanged');
},
valueSetter: (value) {
print('I am a valueSetter');
},
valueGetter: () {
print('I am a valueGetter');
},
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
//Declare the callbacks
final ValueGetter valueGetter;
final ValueSetter valueSetter;
final ValueChanged<String?> valueChanged;
MyWidget(
{required this.valueChanged,
required this.valueGetter,
required this.valueSetter});
@override
Widget build(BuildContext context) {
return Column(children: [
//Sample usage of the callbacks
TextField(
onChanged: valueSetter,
),
TextField(
onChanged: valueChanged,
),
ElevatedButton(onPressed: valueGetter, child: Text('Am a ValueGetter')),
]);
}
}
주의 ⚠ 💀
아시다시피 콜백을 할당할 때 대괄호( )가 없습니다. 추가하면 위젯 레이아웃 시 빌드 메소드에 의해 해당 기능이 실행되기 때문입니다. 또한 나중에 이벤트를 수신하지 않으므로 클릭 이벤트에 대해 콜백이 실행되지 않습니다.
🟢
ElevatedButton(onPressed: onTap, child: Text('Tap Me')),
하지 마세요 🔴
ElevatedButton(onPressed: onTap(), child: Text('Tap Me')),
업데이트: 분리
Flutter 2.5: Tear Off라는 개념이 채택되었습니다.
이는 단순히 함수를 호출하지 않고 매개변수로 전달하여 아래 표시된 대로 기본 위젯이 나중에 사용할 수 있도록 하는 것입니다. 이전 예제에서 해왔지만 개념에 이름을 지정하는 것이 좋습니다😁.
ElevatedButton(onPressed: onTap, child: Text('Tap Me')),
https://medium.com/@dnkibere/passing-a-function-as-an-argument-flutter-e011ad2afd86
'[====== Development ======] > Flutter' 카테고리의 다른 글
Flutter에서 Nested ListView보단 Sliver와 ScrollView를 사용해야하는 이유 (0) | 2023.11.14 |
---|---|
Flutter - Stacked Card List (0) | 2023.11.08 |
Flutter BoxDecoration의 Gradient 적용 (0) | 2023.11.08 |
Flutter get_it (0) | 2023.11.06 |
[flutter] context 없는 환경에서 화면 호출, current context 가져오기 (0) | 2023.11.01 |