サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【Jetpack Compose】親から子コンポーザブルに関数を渡す方法

【Jetpack Compose】親から子コンポーザブルに関数を渡す方法

この記事にはプロモーションが含まれています。

プログラミングの学習をある程度進めていくと、『このポイントは理解が難しくて躓きやすい』といったポイントに遭遇することがあります。

その中でも序盤に出てくる中ボス的な存在と言えば、関数が処理の実行に必要とする項目を示すパラメータや、関数に実際に渡される値である引数(ひきすう)、そして関数の処理の結果として返される戻り値(もどりち)あたりではないでしょうか?

変数や、変数に値を代入するところまでは、特に理解が難しいポイントはないかと思いますが、関数が登場するあたりから、『プログラミングってなんだか難しそう…』といった苦手意識を持ってしまう方が出てくるのではないかと思います。

その関数の中でも厄介なのが、『複雑な引数(例えば関数)を渡さなければならない関数』です。(言い方を変えれば、複雑なパラメータを持つ関数ということになります)

出現頻度が低いものや、大規模で複雑なアプリを作ろうとしない限り、深く知らなくて良いような知識であれば、理解を後回しにして先に進めるというのも一つの手ですが、関数を関数に引数として渡す処理は頻繁に行われます。

Jetpack Composeは関数でUIを構築する仕組みであるため、『関数(コンポーザブル)に何を渡すか』そして『関数(コンポーザブル)から何を受け取るか』を理解することがとても大切です。

そこで今回は、『親から子コンポーザブルに関数を渡す方法』をテーマに、ある関数(A)を別の関数(B)に渡す(受け取る)際に必要なパラメータと引数について、基礎からポイントを解説していきます!

この記事を読むことで分かること
  • ・パラメータと引数の基本
  • ・関数を引数として渡す・受け取る方法
  • ・Jetpack Composeで親から子コンポーザブルに関数を渡す具体例

– 目次 –

関数をパラメータに持つ関数

Jetpack Composeでコードを書いていく前に、まずはシンプルな関数で基本形を確認していきましょう。

特に、『関数を関数の引数として渡す』という言葉の意味がまだよく分からないという方は、基本からじっくり学んだ方が結果的に近道です。

プログラミングにおける関数とは、様々な処理をひとまとめにした便利なパッケージのようなイメージです。

一度作成(定義)すれば、それを色んなところで使い回すことができるのも大きなメリットです。

ただし、柔軟な処理を行えるように設計したければ、引数を受け取るようにパラメータを設定する必要があります。

例えば、下の関数は常に1 + 2の結果(3)を返すので、決して使い勝手が良い関数とは言えませんよね。

Kotlin

fun plusNumber(): Int {
    return 1 + 2
}

println(plusNumber()) // 3

ですが、パラメータとして整数を2つ受け取ることができるようにしておけば、関数を呼び出す際に、何と何を足すかを自由に決められるようになります。

Kotlin

fun plusNumber(x: Int, y: Int): Int {
    return x + y
}

println(plusNumber(x = 3, y = 2)) // 5

ただ、これはまだまだ非常にシンプルな例です。

もう少し複雑なことをしたい場合は、整数などの決まった値ではなく、関数を受け取ってその関数を利用して処理を行いたい…という場合が少なくありません。

例えば、受け取った引数を2倍にして返す関数(doubleNumber)があったとしましょう。

Kotlin

fun doubleNumber(x: Int): Int {
    return x * 2
}

println(doubleNumber(3)) // 6

この関数を利用して、『○を2倍すると×になります』という文字列を得る別の関数を定義したいとします。

この場合、doubleNumberを引数として渡してもらう必要があるため、パラメータに関数を設定しておく必要があります。

doubleNumberは整数を引数として受け取り、戻り値として整数を返す関数であるため、パラメータの指定は次のようになります。

Kotlin

fun printDoubleNumberMessage(doubleNumFun: (Int) -> Int) {
    
}

また、そもそもどんな値(整数)を2倍するのかという問題を解決するために、第2引数として整数も受け取る必要があります。

Kotlin

fun printDoubleNumberMessage(doubleNumFun: (Int) -> Int, num: Int) {
    
}

さらに、最終的には『○を2倍すると×になります。』という文字列を得たいわけですから、Stringを戻り値として返すように指定しなければなりません。

Kotlin

fun printDoubleNumberMessage(doubleNumFun: (Int) -> Int, num: Int): String {
    return "文字列"
}

最後に、受け取った引数を利用して文字列を調整すれば完成です。

Kotlin

fun printDoubleNumberMessage(doubleNumFun: (Int) -> Int, num: Int): String {
    return "$num を2倍すると ${doubleNumFun(num)} になります"
}

println(
       printDoubleNumberMessage(::doubleNumber,3) // 3 を2倍すると 6 になります
)

ちなみに、ラムダ式を使って変数(定数)に代入した関数を引数として渡すようにしたい場合は次のようになります。

Kotlin

val doubleNumber = { x: Int ->
    x * 2
}
fun printDoubleNumberMessage(doubleNumFun: (Int) -> Int, num: Int): String {
    return "$num を2倍すると ${doubleNumFun(num)} になります"
}
println(
   printDoubleNumberMessage(doubleNumber,3) // 3 を2倍すると 6 になります
)

さらに応用として、ラムダ式を使って呼び出し元の関数(printDoubleNumberMessage)に直接無名関数を渡すこともできます。

Kotlin

println(
    printDoubleNumberMessage(
        { it * 2 }, 3
    )
) // 3 を2倍すると 6 になります

まずはこの基本形をしっかり理解することが大切です。

はじめは、『よく分からないけど、こんな感じで書けばコードが動く』といったような感覚的な理解でも構いません。

ですが、慣れてきたらさらに理解を深めていき、関数が何を求めていて、どんな値を渡さなければならないか?最終的にどんな結果が返されるか?…といったことを論理的に掴めるようになっておきましょう!

次の章では、Jetpack Composeで親コンポーザブルから子コンポーザブルへ関数を渡す例をご紹介します。

    POINT!
  1. ・柔軟な処理を行える関数を定義するには、処理に必要なパラメータを設定して引数を受け取れるようにする!
  2. ・パラメータとして関数を指定する場合は、その関数が何を引数に受け取っていて、何を返すのかを把握することが大切!
  3. ・基本が理解できたら、ラムダ式とitを使った書き方にも慣れておこう!

親から子コンポーザブルへ関数を渡す例

Jetpack Composeでは様々なコンポーザブル(Composable)を定義できますが、親(呼び出し元)のコンポーザブルから子(呼び出し先)のコンポーザブルへ、必要なデータを渡したい場合が多くあります。

この時、データの受け渡しが最小限で済むように工夫すると、無駄にコードが複雑かつ冗長になるのを防ぐことができます。

例えば、ボタンを押すと『あなたの成績は○○点でした!』というふうにゲームの結果を表示する仕組みがあったとしましょう。

この時、ゲームの点数の情報(Int)と、それを表示するかどうかを決定するための真偽値(Boolean)は親コンポーザブル内で管理されており、ボタンは子コンポーザブとして管理・配置されているとします。

具体的には次のようなイメージです。

親コンポーザブルで点数と真偽値を管理し、子コンポーザブルにボタンが定義されているコードのイメージ

この時、子コンポーザブルに、点数(Int)とメッセージ表示を切り替える真偽値(Boolean)の両方を渡すのは面倒ですよね。

それに、万が一意図せず点数の情報が子コンポーザブルから勝手に書き換えられてしまっては困ります。

これを防ぐには、必要なモノだけを子コンポーザブルに渡すようにします。

この場合、『結果を表示させるための真偽値をtrueに切り替える』という処理だけ子コンポーザブルに渡せば良いわけですから、親はその処理を行う関数を渡し、子は関数を受け取るようにパラーメータを指定しておけば良いということになります。

ということで、親から子コンポーザブルへ、必要な関数を渡しているシンプルな例がこちらになります。

まずは親コンポーザブルの部分です。

Kotlin

@Composable
fun ParentComposable(
   modifier: Modifier = Modifier
) {
   val gameResult = 80
   var isShowResult by remember {
       mutableStateOf(false)
   }

   Column(
       horizontalAlignment = Alignment.CenterHorizontally,
       verticalArrangement = Arrangement.Center,
       modifier = modifier
   ) {
       Text(text = "あなたの成績は")
       if(isShowResult) {
           Text(text = $gameResult でした!")
       } else {

       }
       Spacer(modifier = Modifier.height(36.dp))
       ChildComposable(onButtonClick = {isShowResult = true})
   }
}

そして次に、子コンポーザブルの部分です。

Kotlin

@Composable
fun ChildComposable(
   onButtonClick: () -> Unit
) {
   Button(onClick = onButtonClick) {
       Text(text = "結果を表示")
   }
}

親から子へ渡す関数は、『isShowResultが保持する真偽値の値をtrueにする』という処理ですから、何らかの引数を受け取って何らかの結果を返すというものではありません。

なので、子コンポーザブルで指定するパラメータは、『引数を何も受け取らず、戻り値も返さない関数』ということになるため、onButtonClick: () -> Unit となります。(パラメータの名前は適切なものであれば何でも良いですが)

こうすることで、点数の情報や、表示を制御する真偽値の情報を子コンポーザブルに渡さなくても、ボタンタップで点数の表示を行うことができるようになります。

Jetpack Composeのコードだと、関数の受け渡しとは関係ないコードも含まれるので少し複雑に見えてしまいますが、やっていることは前章で紹介したことと全く同じです。

関数が関数が受け取れるようにパラメータを指定し(子コンポーザブル側)、関数を引数として関数に渡すように指定している(親コンポーザブル側)だけです。

この基本的な仕組みを理解できれば、Jetpack Composeの多彩なコンポーザブルがより使いやすく感じられるようになります。

というのも、コンポーザブルは元を辿ればただの関数であるため、『このパラメータには整数を渡せば良い、こっちのパラメータには真偽値を渡せば良い、そして最後に関数をラムダ式で渡せば良い』…というふうにシンプルに理解できるようになるためです。

筆者も、最初にJetpack Composeに触れた時は、何やら得体の知れないモノを扱っているかのような感覚がありましたが、この基本的な仕組みをしっかり理解してからは、Jetpack Composeをグッと身近に感じられるようになりました。

Jetpack Composeに限らず、フレームワークやライブラリの扱いに戸惑ったり、理解できずに苦しんだ時は、基本に立ち返ってプログラミングの基礎から見直してみると、意外と『なんだ、そういうことか』と理解ができるようになるかもしれません。

    POINT!
  1. ・Jetpack Composeではコンポーザブル間で様々なデータの受け渡しが行われる!
  2. ・コードの可読性を高めるために、データの受け渡しができるだけ少なく済むように設計しよう!
  3. ・関数を渡すことで、その他の情報を子に渡さなくて済むようになるケースは多い!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン