質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Q&A

解決済

1回答

3331閲覧

Flutter: 子Widgetに渡したコールバック関数が実行されない問題

massanmesu

総合スコア36

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

0グッド

0クリップ

投稿2021/07/17 07:48

Flutterの学習をしています。
親Widgetで実行する関数をコールバック関数として渡し、子Widgetの方で実行させる練習をしています。

スクリーンには値を入力するTextFieldとTextButtonのカスタムWidgetCustomTextButtonがあります。
TextFieldの値をprintするコールバック関数をCustomTextButtonに渡して、onPressedで実行したいのですが実行されませんでした。
イメージ説明

import 'package:flutter/material.dart'; class Test extends StatelessWidget { @override Widget build(BuildContext context) { String? inputtedText; return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('test'), ), body: Column( children: [ TextField( onChanged: (value) { inputtedText = value; }, ), const SizedBox( height: 20, ), /// テキストフィールドの値を出力するコールバックを渡す。 CustomTextButton(callBack: () { print(inputtedText ?? 'empty'); }) ], ), ), ); } } class CustomTextButton extends StatelessWidget { const CustomTextButton({Key? key, required this.callBack}) : super(key: key); final Function callBack; @override Widget build(BuildContext context) { return TextButton( /// プレス時に実行されない。 onPressed: () { callBack; }, child: Container( color: Colors.lightBlueAccent, padding: const EdgeInsets.all(10.0), child: const Text( 'print', style: TextStyle(color: Colors.white), )), ); } }

デバックしたところ、CustomTextButtonのプロパティcallBackの返り値がnullになっていました。
イメージ説明
これは返り値を持たない関数が渡されたのでnullになったという解釈なのか、うまく渡されていないのかどちらなのかがわかりませんでした。

エラー発生してないため何が原因なのかがわかりません。

ご助力願います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

惜しかったですね、

dart

1onPressed: () { 2 callBack(); 3},

括弧の2文字足りませんでした。カッコを付けないと「実行」はされないとイメージしてください。callBack.call()と書くことも一応できます。ただcallBackと書いても代入も処理も何もしていないコードなので何も起きません。コンパイルエラーにはならないと思いますが、何も起きていない式なのでコンパイラの最適化によってむしろ削除されているかもしれません。

ちなみに下記のように書くのをおすすめします。

dart

1final Function callBack;

これを

dart

1final VoidCallback? callBack;

に変えてみてください。そうすると、TextButtonのonPressedと型が一致します。でも仕様を見ると結局typedef VoidCallback = void Function();と定義されているので同じことですね。

そうすると

dart

1onPressed: () { 2 callBack; 3},

これを

dart

1onPressed: callBack,

このように書けます。すっきりしました。もちろんタップ時にコールバックがコールされます。
(記憶から書いていて未検証なのでどこか間違っていたらすみません。)

投稿2021/07/18 17:47

hiroshihorie

総合スコア192

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

massanmesu

2021/07/19 01:59 編集

ありがとうございます。うまく動作しました。 ですが、コールバックの型を`Function`から`VoidCallback`に変えても、実行時には()は必要でした。 ``` final VoidCallback? callBack; ... onPressed: callBack(), ``` 簡易ドキュメントを見ても、返り値は`void Function()`であることは間違い無いのですが、仕様が変わったんでしょうかね?
hiroshihorie

2021/07/19 09:22

実行時には必ず()が必要です。 パラメータとして渡す場合は onPressed: callBack(), ではなくて onPressed: callBack, と書きます。 つまり onPressed: () { callBack(); }, と書くか onPressed: callBack, と書くかの2択です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問