3
2

More than 1 year has passed since last update.

【Flutter】コールバックを自分なりにまとめました。

Last updated at Posted at 2021-11-11

はじめに

iOSメインのスマホアプリエンジニアです。
iOSエンジニア視点からFlutterのコールバックの利用タイミングなどを自分なりにまとめました。

Dartの文化に反していたり、好みや等があるかもしれませんがご了承ください。
その他ご意見ございましたらご指摘ください。

VoidCallback

最もシンプルでFlutter callbackと検索すると真っ先に引っかかるコールバック方法です。
その名の通り、「空っぽのコールバック」

宣言

VoidCallbackを受ける側の実装。

voidCallback = (){ 
   print("voidCallback");
};

呼び出し

VoidCallbackを呼び出す

voidCallback.call();

// 以下でも可能。
voidCallback();

利用用途

明示的に「このコールバックには引数がないですよー」と表したいときに利用する。
ただ、後述のFunctionで事足りるため、チーム内で統一するために使わないようにするのも良いと思いました。

Function

コールバックを呼び出すタイミングで何かしらパラメータを渡したいことが多いと思います。
そのときに登場するのがこちらのFunctionになります。

引数なし

宣言

受ける側の実装。

// 引数なし。VoidCallbackと同じ。
Function function1;

// 受ける側の実装。
function1 = (){
  print("voidCallBack");
};

呼び出し

Functionを呼び出す

function1();

引数あり

宣言

受ける側の実装。

// 引数ありのコールバック
Function(String) function1;

// 受ける側の実装。
function1 = (args){
  print("function1 args:$args");
};

呼び出し

呼び出し側の実装。

function1("このパラメータが渡されます。");

引数あり応用編

宣言

// 引数が複数のコールバック。
Function(int, String) function2;

function2 = (args1 , args2){
  print("function2 args1:$args1 args2:$args2");
};


// 引数にクラスを渡す。
class Hoge {
  final String name;
  final int age;
  Hoge({this.name, this.age});
}

Function(Hoge) function3;

function3 = (hoge){
  print("function3 name:${hoge.name} age:${hoge.age}");
};

呼び出し

// 引数が複数のコールバックを呼び出す。
function2(111 , "function2の引数が渡されます。");

// 引数がクラスのコールバックを呼び出す
function3(Hoge(name: "name" ,age: 20));

利用用途

iOSでいうBlockClosuresに似ており、単一のコールバックを返すに適していると思います。
複数のコールバックを返したい場合に、メンバー変数等に宣言すると冗長になります。
Delegateみたいなこと出来ないかな。と探しましたところありました!

mixinを使ったDelegateパターン

mixinを使ったDelegateパターンを使って実装してみましたところ、iOSエンジニアから見ると非常に馴染み深い書き方になります。
今回はStatefulWidgetに記載する例を記載しました。

宣言

// iOSで言うところのprotocolを宣言。
mixin HogeDelegate {
  void hoge();
  void hogeHoge1(String);
  void hogeHoge2(String args1, String args2);
  String hogehoge4();
}

// クラスにDelegateを作成。
class Hoge {
  HogeDelegate delegate;

  void run(){
    delegate.hoge();
  }
}

// Stateクラスに受け取れるように実装します。
// with HogeDelegate追加。
class _MyHomePageState extends State<MyHomePage> with HogeDelegate {

  // Hogeクラスを宣言。
  Hoge hogehoge;

  void hoge() {
    print("delegate hoge");
  }

  void hogeHoge1(String) {
    print("delegate hogeHoge1");
  }

  void hogeHoge2(String args1, String args2) {
    print("delegate hogeHoge2 args1$args1 $args2");
  }

  String hogehoge4(){
    return "hogehoge4を返却する。";
  }

  @override
  void initState() {
    super.initState();

   // initでクラスとdelegateを宣言しておく。
    hogehoge = Hoge();
    hogehoge.delegate = this;
  }
}

呼び出し

hogehoge.run();

まとめ

個人的には以下のように使い分けてみようかと思います。

概要 iOSでは? 使いみち
VoidCallback iOSではない 明示的にパラメータ等を返さないと宣言したい時に利用する。
Function Block/Closures 単一のコールバックを返すに適している。複数のコールバックをFunctionで実装すると冗長になる可能性がある。
mixin Delegate TableViewDelegateのように、複数のコールバックを返却したいときに適している。

その他のコールバックを見つけたら追記していきたいと思います。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2