반응형

함수를 인수로 전달하는 방법에 대해 궁금한 적이 있습니다. 아니면 기능을 유지하면서 코드를 깔끔하고 읽기 쉽게 유지할 수 있도록 전달해야 합니까?

그렇다면 들어가 보겠습니다.

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

 

Passing a Function as an Argument — Flutter💙

Ever wondered how to pass a function as an argument 😤. Or even better, Do you need to pass it so your code can remain clean and readable…

medium.com

 

반응형

+ Recent posts